Add minimum frame rate constraint for screen share
This commit is contained in:
parent
ee1e15646b
commit
a23d107343
3 changed files with 56 additions and 20 deletions
8
package-lock.json
generated
8
package-lock.json
generated
|
@ -14,7 +14,7 @@
|
||||||
"@formatjs/icu-messageformat-parser": "2.3.0",
|
"@formatjs/icu-messageformat-parser": "2.3.0",
|
||||||
"@formatjs/intl-localematcher": "0.2.32",
|
"@formatjs/intl-localematcher": "0.2.32",
|
||||||
"@indutny/dicer": "0.3.2",
|
"@indutny/dicer": "0.3.2",
|
||||||
"@indutny/mac-screen-share": "1.0.11",
|
"@indutny/mac-screen-share": "1.0.13",
|
||||||
"@indutny/range-finder": "1.3.4",
|
"@indutny/range-finder": "1.3.4",
|
||||||
"@indutny/simple-windows-notifications": "2.0.7",
|
"@indutny/simple-windows-notifications": "2.0.7",
|
||||||
"@indutny/sneequals": "4.0.0",
|
"@indutny/sneequals": "4.0.0",
|
||||||
|
@ -4086,9 +4086,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@indutny/mac-screen-share": {
|
"node_modules/@indutny/mac-screen-share": {
|
||||||
"version": "1.0.11",
|
"version": "1.0.13",
|
||||||
"resolved": "https://registry.npmjs.org/@indutny/mac-screen-share/-/mac-screen-share-1.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@indutny/mac-screen-share/-/mac-screen-share-1.0.13.tgz",
|
||||||
"integrity": "sha512-0UHiWyUBYn3VjjwpaS0nD6bppunyaTdFGXU84uGmzlV1R9RYcXQOF4EDCWQLpMlw4TieLOBvsh10gLEP116MPw==",
|
"integrity": "sha512-fCOYWGaIuZAwfk/eUUjqPKge4+PKKCwTsuH9SSoaBZMP8IsWQtyyrTVpeuq84oDren4b9EUgRGgh2t950sQA0w==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -98,7 +98,7 @@
|
||||||
"@formatjs/icu-messageformat-parser": "2.3.0",
|
"@formatjs/icu-messageformat-parser": "2.3.0",
|
||||||
"@formatjs/intl-localematcher": "0.2.32",
|
"@formatjs/intl-localematcher": "0.2.32",
|
||||||
"@indutny/dicer": "0.3.2",
|
"@indutny/dicer": "0.3.2",
|
||||||
"@indutny/mac-screen-share": "1.0.11",
|
"@indutny/mac-screen-share": "1.0.13",
|
||||||
"@indutny/range-finder": "1.3.4",
|
"@indutny/range-finder": "1.3.4",
|
||||||
"@indutny/simple-windows-notifications": "2.0.7",
|
"@indutny/simple-windows-notifications": "2.0.7",
|
||||||
"@indutny/sneequals": "4.0.0",
|
"@indutny/sneequals": "4.0.0",
|
||||||
|
|
|
@ -18,6 +18,8 @@ import { strictAssert } from './assert';
|
||||||
import { explodePromise } from './explodePromise';
|
import { explodePromise } from './explodePromise';
|
||||||
import { isNotNil } from './isNotNil';
|
import { isNotNil } from './isNotNil';
|
||||||
import { drop } from './drop';
|
import { drop } from './drop';
|
||||||
|
import { SECOND } from './durations';
|
||||||
|
import { isOlderThan } from './timestamp';
|
||||||
|
|
||||||
// Chrome-only API for now, thus a declaration:
|
// Chrome-only API for now, thus a declaration:
|
||||||
declare class MediaStreamTrackGenerator extends MediaStreamTrack {
|
declare class MediaStreamTrackGenerator extends MediaStreamTrack {
|
||||||
|
@ -176,7 +178,14 @@ export class DesktopCapturer {
|
||||||
liveCapturers.add(this);
|
liveCapturers.add(this);
|
||||||
try {
|
try {
|
||||||
const stream = await navigator.mediaDevices.getDisplayMedia({
|
const stream = await navigator.mediaDevices.getDisplayMedia({
|
||||||
video: {
|
video: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const videoTrack = stream.getVideoTracks()[0];
|
||||||
|
strictAssert(videoTrack, 'videoTrack does not exist');
|
||||||
|
|
||||||
|
// Apply constraints and ensure that there is at least 1 frame per second.
|
||||||
|
await videoTrack.applyConstraints({
|
||||||
width: {
|
width: {
|
||||||
max: REQUESTED_SCREEN_SHARE_WIDTH,
|
max: REQUESTED_SCREEN_SHARE_WIDTH,
|
||||||
ideal: REQUESTED_SCREEN_SHARE_WIDTH,
|
ideal: REQUESTED_SCREEN_SHARE_WIDTH,
|
||||||
|
@ -186,10 +195,10 @@ export class DesktopCapturer {
|
||||||
ideal: REQUESTED_SCREEN_SHARE_HEIGHT,
|
ideal: REQUESTED_SCREEN_SHARE_HEIGHT,
|
||||||
},
|
},
|
||||||
frameRate: {
|
frameRate: {
|
||||||
|
min: 1,
|
||||||
max: REQUESTED_SCREEN_SHARE_FRAMERATE,
|
max: REQUESTED_SCREEN_SHARE_FRAMERATE,
|
||||||
ideal: REQUESTED_SCREEN_SHARE_FRAMERATE,
|
ideal: REQUESTED_SCREEN_SHARE_FRAMERATE,
|
||||||
},
|
},
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
strictAssert(
|
strictAssert(
|
||||||
|
@ -222,6 +231,20 @@ export class DesktopCapturer {
|
||||||
|
|
||||||
let isRunning = false;
|
let isRunning = false;
|
||||||
|
|
||||||
|
let lastFrame: VideoFrame | undefined;
|
||||||
|
let lastFrameSentAt = 0;
|
||||||
|
|
||||||
|
let frameRepeater: NodeJS.Timeout | undefined;
|
||||||
|
|
||||||
|
const cleanup = () => {
|
||||||
|
lastFrame?.close();
|
||||||
|
if (frameRepeater != null) {
|
||||||
|
clearInterval(frameRepeater);
|
||||||
|
}
|
||||||
|
frameRepeater = undefined;
|
||||||
|
lastFrame = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
const stream = new macScreenShare.Stream({
|
const stream = new macScreenShare.Stream({
|
||||||
width: REQUESTED_SCREEN_SHARE_WIDTH,
|
width: REQUESTED_SCREEN_SHARE_WIDTH,
|
||||||
height: REQUESTED_SCREEN_SHARE_HEIGHT,
|
height: REQUESTED_SCREEN_SHARE_HEIGHT,
|
||||||
|
@ -230,6 +253,17 @@ export class DesktopCapturer {
|
||||||
onStart: () => {
|
onStart: () => {
|
||||||
isRunning = true;
|
isRunning = true;
|
||||||
|
|
||||||
|
// Repeat last frame every second to match "min" constraint above.
|
||||||
|
frameRepeater = setInterval(() => {
|
||||||
|
if (isRunning && track.readyState !== 'ended' && lastFrame != null) {
|
||||||
|
if (isOlderThan(lastFrameSentAt, SECOND)) {
|
||||||
|
drop(writer.write(lastFrame.clone()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
}, SECOND);
|
||||||
|
|
||||||
this.options.onMediaStream(mediaStream);
|
this.options.onMediaStream(mediaStream);
|
||||||
},
|
},
|
||||||
onStop() {
|
onStop() {
|
||||||
|
@ -253,13 +287,15 @@ export class DesktopCapturer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const videoFrame = new VideoFrame(frame, {
|
lastFrame?.close();
|
||||||
|
lastFrameSentAt = Date.now();
|
||||||
|
lastFrame = new VideoFrame(frame, {
|
||||||
format: 'NV12',
|
format: 'NV12',
|
||||||
codedWidth: width,
|
codedWidth: width,
|
||||||
codedHeight: height,
|
codedHeight: height,
|
||||||
timestamp: 0,
|
timestamp: 0,
|
||||||
});
|
});
|
||||||
drop(writer.write(videoFrame));
|
drop(writer.write(lastFrame.clone()));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue