Skip to content

Commit c0cdfbb

Browse files
authored
Merge pull request #359 from Dramalf/main
fix: resolve size mismatch issue in MediaStreamClip during tab recording#343
2 parents 2bfbab7 + a6b088d commit c0cdfbb

File tree

4 files changed

+37
-15
lines changed

4 files changed

+37
-15
lines changed

.changeset/seven-olives-worry.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@webav/av-cliper': patch
3+
---
4+
5+
fix: Initialize MediaStreamClip's width, height and cvs in the first call of onChunk with the firstFrame information #343

.changeset/thin-cows-hug.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@webav/av-cliper': patch
3+
---
4+
5+
resolve size mismatch issue in MediaStreamClip during tab recording #343

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,8 @@
1111
},
1212
"[jsonc]": {
1313
"editor.defaultFormatter": "esbenp.prettier-vscode"
14+
},
15+
"[typescript]": {
16+
"editor.defaultFormatter": "vscode.typescript-language-features"
1417
}
1518
}

packages/av-cliper/src/clips/media-stream-clip.ts

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,24 +44,22 @@ export class MediaStreamClip implements IClip {
4444
#ms: MediaStream;
4545
constructor(ms: MediaStream) {
4646
this.#ms = ms;
47+
this.audioTrack = ms.getAudioTracks()[0] ?? null;
48+
this.#meta.duration = Infinity;
4749
const videoTrack = ms.getVideoTracks()[0];
4850
if (videoTrack != null) {
49-
const { width, height } = videoTrack.getSettings();
5051
videoTrack.contentHint = 'motion';
51-
this.#meta.width = width ?? 0;
52-
this.#meta.height = height ?? 0;
53-
54-
this.#cvs = new OffscreenCanvas(width ?? 0, height ?? 0);
55-
this.#stopRenderCvs = renderVideoTrackToCvs(
56-
this.#cvs.getContext('2d')!,
57-
videoTrack,
58-
);
52+
this.ready = new Promise((resolve) => {
53+
this.#stopRenderCvs = renderVideoTrackToCvs(videoTrack, (cvs) => {
54+
this.#meta.width = cvs.width;
55+
this.#meta.height = cvs.height;
56+
this.#cvs = cvs;
57+
resolve(this.meta);
58+
});
59+
});
60+
} else {
61+
this.ready = Promise.resolve(this.meta);
5962
}
60-
61-
this.audioTrack = ms.getAudioTracks()[0] ?? null;
62-
63-
this.#meta.duration = Infinity;
64-
this.ready = Promise.resolve(this.meta);
6563
}
6664

6765
async tick(): Promise<{
@@ -91,15 +89,26 @@ export class MediaStreamClip implements IClip {
9189
}
9290

9391
function renderVideoTrackToCvs(
94-
cvsCtx: OffscreenCanvasRenderingContext2D,
9592
track: MediaStreamVideoTrack,
93+
onOffscreenCanvasReady: (cvs: OffscreenCanvas) => void,
9694
) {
95+
let emitFF = false;
96+
let cvsCtx: OffscreenCanvasRenderingContext2D;
9797
return autoReadStream(
9898
new MediaStreamTrackProcessor({
9999
track,
100100
}).readable,
101101
{
102102
onChunk: async (frame) => {
103+
if (!emitFF) {
104+
const { displayHeight, displayWidth } = frame;
105+
const width = displayWidth ?? 0;
106+
const height = displayHeight ?? 0;
107+
const cvs = new OffscreenCanvas(width, height);
108+
cvsCtx = cvs.getContext('2d')!;
109+
onOffscreenCanvasReady(cvs);
110+
emitFF = true;
111+
}
103112
cvsCtx.drawImage(frame, 0, 0);
104113
frame.close();
105114
},

0 commit comments

Comments
 (0)