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/intl-localematcher": "0.2.32",
|
||||
"@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/simple-windows-notifications": "2.0.7",
|
||||
"@indutny/sneequals": "4.0.0",
|
||||
|
@ -4086,9 +4086,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@indutny/mac-screen-share": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@indutny/mac-screen-share/-/mac-screen-share-1.0.11.tgz",
|
||||
"integrity": "sha512-0UHiWyUBYn3VjjwpaS0nD6bppunyaTdFGXU84uGmzlV1R9RYcXQOF4EDCWQLpMlw4TieLOBvsh10gLEP116MPw==",
|
||||
"version": "1.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@indutny/mac-screen-share/-/mac-screen-share-1.0.13.tgz",
|
||||
"integrity": "sha512-fCOYWGaIuZAwfk/eUUjqPKge4+PKKCwTsuH9SSoaBZMP8IsWQtyyrTVpeuq84oDren4b9EUgRGgh2t950sQA0w==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
|
@ -98,7 +98,7 @@
|
|||
"@formatjs/icu-messageformat-parser": "2.3.0",
|
||||
"@formatjs/intl-localematcher": "0.2.32",
|
||||
"@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/simple-windows-notifications": "2.0.7",
|
||||
"@indutny/sneequals": "4.0.0",
|
||||
|
|
|
@ -18,6 +18,8 @@ import { strictAssert } from './assert';
|
|||
import { explodePromise } from './explodePromise';
|
||||
import { isNotNil } from './isNotNil';
|
||||
import { drop } from './drop';
|
||||
import { SECOND } from './durations';
|
||||
import { isOlderThan } from './timestamp';
|
||||
|
||||
// Chrome-only API for now, thus a declaration:
|
||||
declare class MediaStreamTrackGenerator extends MediaStreamTrack {
|
||||
|
@ -176,19 +178,26 @@ export class DesktopCapturer {
|
|||
liveCapturers.add(this);
|
||||
try {
|
||||
const stream = await navigator.mediaDevices.getDisplayMedia({
|
||||
video: {
|
||||
width: {
|
||||
max: REQUESTED_SCREEN_SHARE_WIDTH,
|
||||
ideal: REQUESTED_SCREEN_SHARE_WIDTH,
|
||||
},
|
||||
height: {
|
||||
max: REQUESTED_SCREEN_SHARE_HEIGHT,
|
||||
ideal: REQUESTED_SCREEN_SHARE_HEIGHT,
|
||||
},
|
||||
frameRate: {
|
||||
max: REQUESTED_SCREEN_SHARE_FRAMERATE,
|
||||
ideal: REQUESTED_SCREEN_SHARE_FRAMERATE,
|
||||
},
|
||||
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: {
|
||||
max: REQUESTED_SCREEN_SHARE_WIDTH,
|
||||
ideal: REQUESTED_SCREEN_SHARE_WIDTH,
|
||||
},
|
||||
height: {
|
||||
max: REQUESTED_SCREEN_SHARE_HEIGHT,
|
||||
ideal: REQUESTED_SCREEN_SHARE_HEIGHT,
|
||||
},
|
||||
frameRate: {
|
||||
min: 1,
|
||||
max: REQUESTED_SCREEN_SHARE_FRAMERATE,
|
||||
ideal: REQUESTED_SCREEN_SHARE_FRAMERATE,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -222,6 +231,20 @@ export class DesktopCapturer {
|
|||
|
||||
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({
|
||||
width: REQUESTED_SCREEN_SHARE_WIDTH,
|
||||
height: REQUESTED_SCREEN_SHARE_HEIGHT,
|
||||
|
@ -230,6 +253,17 @@ export class DesktopCapturer {
|
|||
onStart: () => {
|
||||
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);
|
||||
},
|
||||
onStop() {
|
||||
|
@ -253,13 +287,15 @@ export class DesktopCapturer {
|
|||
return;
|
||||
}
|
||||
|
||||
const videoFrame = new VideoFrame(frame, {
|
||||
lastFrame?.close();
|
||||
lastFrameSentAt = Date.now();
|
||||
lastFrame = new VideoFrame(frame, {
|
||||
format: 'NV12',
|
||||
codedWidth: width,
|
||||
codedHeight: height,
|
||||
timestamp: 0,
|
||||
});
|
||||
drop(writer.write(videoFrame));
|
||||
drop(writer.write(lastFrame.clone()));
|
||||
},
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue