Переглянути джерело

feat(screenshare): use camera as a screenshare source

This feature is intended for spot. Spot can have an
HDMI -> usb adapter hooked up to it. In that case,
attempting to screenshare should use that adapter
as a screensharing source.
dev1
Leonard Kim 7 роки тому
джерело
коміт
b596bc7d28
1 змінених файлів з 59 додано та 12 видалено
  1. 59
    12
      modules/RTC/RTCUtils.js

+ 59
- 12
modules/RTC/RTCUtils.js Переглянути файл

@@ -1145,6 +1145,13 @@ class RTCUtils extends Listenable {
1145 1145
                     return { audioVideo };
1146 1146
                 }
1147 1147
 
1148
+                if (options.desktopSharingSourceDevice) {
1149
+                    this.stopMediaStream(audioVideo);
1150
+
1151
+                    throw new Error('Using a camera as screenshare source is'
1152
+                        + 'not supported on this browser.');
1153
+                }
1154
+
1148 1155
                 return new Promise((resolve, reject) => {
1149 1156
                     screenObtainer.obtainStream(
1150 1157
                         this._parseDesktopSharingOptions(options),
@@ -1255,6 +1262,8 @@ class RTCUtils extends Listenable {
1255 1262
      * @param {Object} options.desktopSharingFrameRate
1256 1263
      * @param {Object} options.desktopSharingFrameRate.min - Minimum fps
1257 1264
      * @param {Object} options.desktopSharingFrameRate.max - Maximum fps
1265
+     * @param {String} options.desktopSharingSourceDevice - The device id or
1266
+     * label for a video input source that should be used for screensharing.
1258 1267
      * @returns {Promise} The promise, when successful, will return an array of
1259 1268
      * meta data for the requested device type, which includes the stream and
1260 1269
      * track. If an error occurs, it will be deferred to the caller for
@@ -1277,24 +1286,55 @@ class RTCUtils extends Listenable {
1277 1286
          */
1278 1287
         const maybeRequestDesktopDevice = function() {
1279 1288
             const umDevices = options.devices || [];
1280
-            const isDesktopDeviceRequsted = umDevices.indexOf('desktop') !== -1;
1289
+            const isDesktopDeviceRequested
1290
+                = umDevices.indexOf('desktop') !== -1;
1291
+
1292
+            if (!isDesktopDeviceRequested) {
1293
+                return Promise.resolve();
1294
+            }
1281 1295
 
1282 1296
             const {
1283 1297
                 desktopSharingExtensionExternalInstallation,
1298
+                desktopSharingSourceDevice,
1284 1299
                 desktopSharingSources,
1285 1300
                 desktopSharingFrameRate
1286 1301
             } = options;
1287 1302
 
1288
-            return isDesktopDeviceRequsted
1289
-                ? this._newGetDesktopMedia(
1290
-                    {
1291
-                        desktopSharingExtensionExternalInstallation,
1292
-                        desktopSharingSources,
1293
-                        gumOptions: {
1294
-                            frameRate: desktopSharingFrameRate
1295
-                        }
1296
-                    })
1297
-                : Promise.resolve();
1303
+            // Attempt to use a video input device as a screenshare source if
1304
+            // the option is defined.
1305
+            if (desktopSharingSourceDevice) {
1306
+                const matchingDevice
1307
+                    = availableDevices && availableDevices.find(device =>
1308
+                        device.kind === 'videoinput'
1309
+                            && (device.deviceId === desktopSharingSourceDevice
1310
+                            || device.label === desktopSharingSourceDevice));
1311
+
1312
+                const requestedDevices = [ 'video' ];
1313
+                const constraints = newGetConstraints(
1314
+                    requestedDevices, { options });
1315
+
1316
+                // Use exact to make sure there is no fallthrough to another
1317
+                // camera device. If a matching device could not be found,
1318
+                // try anyways and let the caller handle errors.
1319
+                constraints.video.deviceId = {
1320
+                    exact: (matchingDevice && matchingDevice.deviceId)
1321
+                        || desktopSharingSourceDevice
1322
+                };
1323
+
1324
+                return this._newGetUserMediaWithConstraints(
1325
+                    requestedDevices, constraints)
1326
+                    .then(stream => {
1327
+                        return { stream };
1328
+                    });
1329
+            }
1330
+
1331
+            return this._newGetDesktopMedia({
1332
+                desktopSharingExtensionExternalInstallation,
1333
+                desktopSharingSources,
1334
+                gumOptions: {
1335
+                    frameRate: desktopSharingFrameRate
1336
+                }
1337
+            });
1298 1338
         }.bind(this);
1299 1339
 
1300 1340
         /**
@@ -1390,7 +1430,14 @@ class RTCUtils extends Listenable {
1390 1430
             .then(maybeCreateAndAddDesktopTrack)
1391 1431
             .then(maybeRequestCaptureDevices)
1392 1432
             .then(maybeCreateAndAddAVTracks)
1393
-            .then(() => mediaStreamsMetaData);
1433
+            .then(() => mediaStreamsMetaData)
1434
+            .catch(error => {
1435
+                mediaStreamsMetaData.forEach(({ stream }) => {
1436
+                    this.stopMediaStream(stream);
1437
+                });
1438
+
1439
+                return Promise.reject(error);
1440
+            });
1394 1441
     }
1395 1442
 
1396 1443
     /**

Завантаження…
Відмінити
Зберегти