From 7f405c039ae1b441101e933032d10847d6af29f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Wang?= Date: Tue, 27 Jun 2023 17:58:07 +0200 Subject: [PATCH 1/4] Add code examples - Basic example - Example for efficiency enhancements during RTC (cursor constraint and RTCDataChannel) fixes #6 --- index.html | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/index.html b/index.html index 8fa5015..b4622a4 100644 --- a/index.html +++ b/index.html @@ -65,6 +65,67 @@

Use case #2: Efficiency enhancements during RTC

+
+

Examples

+

The basic example from + the Screen Capture specification is extended below by passing + to getDisplayMedia() a CaptureController + object. An event handler is set on that object in order to receive + {{CapturedMouseEvent}}s with the mouse coordinates over the captured + surface. +

+
try {
+  let controller = new CaptureController();
+  controller.oncapturedmousechange = (event) => {
+    console.log(`Mouse coordinates: x=${event.surfaceX}, y=${event.surfaceY}`);
+  };
+  let mediaStream = await navigator.mediaDevices.getDisplayMedia({
+    video: true,
+    controller: controller,
+  });
+  videoElement.srcObject = mediaStream;
+} catch (e) {
+  console.log(`Unable to acquire screen capture: ${e}`);
+}
+

+

In the following example, the + cursor constraint is used to + omit the cursor from the captured display surface. The mouse coordinates are + transmitted via a RTCDataChannel to + the receiving application, which can then redraw the cursor.

+
+// An peer-to-peer connection is established and a data channel created for
+// transmitting the mouse events.
+const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
+let pc = new RTCPeerConnection(configuration);
+let channel = pc.createDataChannel('mouse-events', {negotiated: true, id: 0});
+
+// On the capturing side, the capture session is initialized with the mouse
+// cursor ommitted from the captured surface. The mouse coordinates are
+// transmitted via the data channel.
+let controller = new CaptureController();
+controller.oncapturedmousechange = (event) => {
+  channel.send(JSON.stringify({x: event.surfaceX, y: event.surfaceY}));
+};
+let mediaStream = await navigator.mediaDevices.getDisplayMedia({
+  video: { advanced: [{cursor: "never"}] },
+  controller: controller,
+});
+pc.addTrack(mediaStream.getVideoTracks()[0], mediaStream);
+...
+
+// On the receiving side, the remote stream is rendered in a video and the
+// coordinates received from the data channel are used to redraw the cursor.
+let remoteView = document.getElementById('my-video-element');
+channel.onmessage = ({data}) => redrawCursor(removeView, JSON.parse(data));
+pc.ontrack = ({track, streams}) => {
+  track.onunmute = () => {
+    if (remoteView.srcObject) return;
+    remoteView.srcObject = streams[0];
+  };
+};
+...
+

CapturedMouseEvent interface

From 4aa4337522ff47f5391c9ee012ee3028ddb0c1d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Wang?= Date: Sat, 1 Jul 2023 11:00:07 +0200 Subject: [PATCH 2/4] address review feedback --- index.html | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/index.html b/index.html index b4622a4..3092a79 100644 --- a/index.html +++ b/index.html @@ -67,48 +67,44 @@

Use case #2: Efficiency enhancements during RTC

Examples

-

The basic example from - the Screen Capture specification is extended below by passing - to getDisplayMedia() a CaptureController - object. An event handler is set on that object in order to receive - {{CapturedMouseEvent}}s with the mouse coordinates over the captured - surface. +

+ In the basic example below, a CaptureController is passed to + getDisplayMedia(). An event handler is set on that object in order to receive + {{CapturedMouseEvent}}s with the mouse coordinates over the captured surface.

-
try {
+      
+try {
   let controller = new CaptureController();
   controller.oncapturedmousechange = (event) => {
     console.log(`Mouse coordinates: x=${event.surfaceX}, y=${event.surfaceY}`);
   };
-  let mediaStream = await navigator.mediaDevices.getDisplayMedia({
-    video: true,
-    controller: controller,
-  });
-  videoElement.srcObject = mediaStream;
+  let mediaStream = await navigator.mediaDevices.getDisplayMedia({ controller });
 } catch (e) {
   console.log(`Unable to acquire screen capture: ${e}`);
 }
-

-

In the following example, the - cursor constraint is used to - omit the cursor from the captured display surface. The mouse coordinates are - transmitted via a RTCDataChannel to - the receiving application, which can then redraw the cursor.

-
+      

+ In the following example, the + cursor constraint is used to omit the cursor + from the captured display surface. The mouse coordinates are transmitted via a + RTCDataChannel to the receiving application, which + can then redraw the cursor. +

+
 // An peer-to-peer connection is established and a data channel created for
 // transmitting the mouse events.
 const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
-let pc = new RTCPeerConnection(configuration);
-let channel = pc.createDataChannel('mouse-events', {negotiated: true, id: 0});
+const pc = new RTCPeerConnection(configuration);
+const channel = pc.createDataChannel('mouse-events', {negotiated: true, id: 0});
 
 // On the capturing side, the capture session is initialized with the mouse
 // cursor ommitted from the captured surface. The mouse coordinates are
 // transmitted via the data channel.
-let controller = new CaptureController();
+const controller = new CaptureController();
 controller.oncapturedmousechange = (event) => {
   channel.send(JSON.stringify({x: event.surfaceX, y: event.surfaceY}));
 };
-let mediaStream = await navigator.mediaDevices.getDisplayMedia({
-  video: { advanced: [{cursor: "never"}] },
+const mediaStream = await navigator.mediaDevices.getDisplayMedia({
+  video: { cursor: "never" },
   controller: controller,
 });
 pc.addTrack(mediaStream.getVideoTracks()[0], mediaStream);
@@ -116,7 +112,7 @@ 

Examples

// On the receiving side, the remote stream is rendered in a video and the // coordinates received from the data channel are used to redraw the cursor. -let remoteView = document.getElementById('my-video-element'); +const remoteView = document.getElementById('my-video-element'); channel.onmessage = ({data}) => redrawCursor(removeView, JSON.parse(data)); pc.ontrack = ({track, streams}) => { track.onunmute = () => { From fc204575c992a628fe8fa86e6b405a35d7031a83 Mon Sep 17 00:00:00 2001 From: Elad Alon Date: Mon, 3 Jul 2023 13:08:16 +0200 Subject: [PATCH 3/4] Fix formatting --- index.html | 86 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 45 insertions(+), 41 deletions(-) diff --git a/index.html b/index.html index 3092a79..433bd3a 100644 --- a/index.html +++ b/index.html @@ -73,15 +73,16 @@

Examples

{{CapturedMouseEvent}}s with the mouse coordinates over the captured surface.

-try {
-  let controller = new CaptureController();
-  controller.oncapturedmousechange = (event) => {
-    console.log(`Mouse coordinates: x=${event.surfaceX}, y=${event.surfaceY}`);
-  };
-  let mediaStream = await navigator.mediaDevices.getDisplayMedia({ controller });
-} catch (e) {
-  console.log(`Unable to acquire screen capture: ${e}`);
-}
+ try { + let controller = new CaptureController(); + controller.oncapturedmousechange = (event) => { + console.log(`Mouse coordinates: x=${event.surfaceX}, y=${event.surfaceY}`); + }; + let mediaStream = await navigator.mediaDevices.getDisplayMedia({ controller }); + } catch (e) { + console.log(`Unable to acquire screen capture: ${e}`); + } +

In the following example, the cursor constraint is used to omit the cursor @@ -90,37 +91,38 @@

Examples

can then redraw the cursor.

-// An peer-to-peer connection is established and a data channel created for
-// transmitting the mouse events.
-const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
-const pc = new RTCPeerConnection(configuration);
-const channel = pc.createDataChannel('mouse-events', {negotiated: true, id: 0});
+        // An peer-to-peer connection is established and a data channel created for
+        // transmitting the mouse events.
+        const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
+        const pc = new RTCPeerConnection(configuration);
+        const channel = pc.createDataChannel('mouse-events', {negotiated: true, id: 0});
 
-// On the capturing side, the capture session is initialized with the mouse
-// cursor ommitted from the captured surface. The mouse coordinates are
-// transmitted via the data channel.
-const controller = new CaptureController();
-controller.oncapturedmousechange = (event) => {
-  channel.send(JSON.stringify({x: event.surfaceX, y: event.surfaceY}));
-};
-const mediaStream = await navigator.mediaDevices.getDisplayMedia({
-  video: { cursor: "never" },
-  controller: controller,
-});
-pc.addTrack(mediaStream.getVideoTracks()[0], mediaStream);
-...
+        // On the capturing side, the capture session is initialized with the mouse
+        // cursor ommitted from the captured surface. The mouse coordinates are
+        // transmitted via the data channel.
+        const controller = new CaptureController();
+        controller.oncapturedmousechange = (event) => {
+          channel.send(JSON.stringify({x: event.surfaceX, y: event.surfaceY}));
+        };
+        const mediaStream = await navigator.mediaDevices.getDisplayMedia({
+          video: { cursor: "never" },
+          controller: controller,
+        });
+        pc.addTrack(mediaStream.getVideoTracks()[0], mediaStream);
+        ...
 
-// On the receiving side, the remote stream is rendered in a video and the
-// coordinates received from the data channel are used to redraw the cursor.
-const remoteView = document.getElementById('my-video-element');
-channel.onmessage = ({data}) => redrawCursor(removeView, JSON.parse(data));
-pc.ontrack = ({track, streams}) => {
-  track.onunmute = () => {
-    if (remoteView.srcObject) return;
-    remoteView.srcObject = streams[0];
-  };
-};
-...
+ // On the receiving side, the remote stream is rendered in a video and the + // coordinates received from the data channel are used to redraw the cursor. + const remoteView = document.getElementById('my-video-element'); + channel.onmessage = ({data}) => redrawCursor(removeView, JSON.parse(data)); + pc.ontrack = ({track, streams}) => { + track.onunmute = () => { + if (remoteView.srcObject) return; + remoteView.srcObject = streams[0]; + }; + }; + ... +

CapturedMouseEvent interface

@@ -146,13 +148,15 @@

CapturedMouseEvent interface

Constructs a new {{CapturedMouseEvent}}.

The arguments are passed as is to {{Event}}'s constructor.

-

If any of {{CapturedMouseEventInit.surfaceX}} or - {{CapturedMouseEventInit.surfaceY}} is negative, and they are not - both equal to -1, then the constructor +

+ If any of {{CapturedMouseEventInit.surfaceX}} or {{CapturedMouseEventInit.surfaceY}} is + negative, and they are not both equal to -1, then the constructor throws a RangeError exception. +

+
surfaceX

From 632d28383b809e5c257375fb6168403b0c8c1f84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Wang?= Date: Mon, 3 Jul 2023 13:43:14 +0200 Subject: [PATCH 4/4] address review comments --- index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 433bd3a..d6689ea 100644 --- a/index.html +++ b/index.html @@ -68,13 +68,13 @@

Use case #2: Efficiency enhancements during RTC

Examples

- In the basic example below, a CaptureController is passed to - getDisplayMedia(). An event handler is set on that object in order to receive - {{CapturedMouseEvent}}s with the mouse coordinates over the captured surface. + In the basic example below, a {{CaptureController}} is passed to + {{MediaDevices/getDisplayMedia()}}. An event handler is set on that object in order to + receive {{CapturedMouseEvent}}s with the mouse coordinates over the captured surface.

         try {
-          let controller = new CaptureController();
+          const controller = new CaptureController();
           controller.oncapturedmousechange = (event) => {
             console.log(`Mouse coordinates: x=${event.surfaceX}, y=${event.surfaceY}`);
           };