Skip to content

Commit f2e5ae7

Browse files
authored
videoUploading: add webcam as a source video option (#562)
And add size data about the video frames Tested and working on Chrome/Firefox/Safari on Mac, Chrome on Android.
1 parent 3b3f53e commit f2e5ae7

2 files changed

Lines changed: 43 additions & 6 deletions

File tree

sample/videoUploading/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@
2323
height: 100%; /* make body fill the browser window */
2424
}
2525
canvas {
26-
width: 100%;
27-
height: 100%;
28-
max-width: 100%;
26+
width: min(100vw, 100vh);
27+
aspect-ratio: 4 / 3;
2928
display: block;
3029
}
3130
</style>
@@ -34,5 +33,6 @@
3433
</head>
3534
<body>
3635
<canvas></canvas>
36+
<pre id=videoinfo></pre>
3737
</body>
3838
</html>

sample/videoUploading/main.ts

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,14 @@ const videos = {
2020
url: '../../assets/video/Video_360°._Timelapse._Bled_Lake_in_Slovenia..webm.720p.vp9.webm',
2121
mode: '360',
2222
},
23+
webcam: {
24+
url: '',
25+
mode: 'mirror',
26+
},
2327
} as const;
2428

29+
const videoinfo = document.getElementById('videoinfo') as HTMLPreElement;
30+
2531
const canvas = document.querySelector('canvas') as HTMLCanvasElement;
2632
const context = canvas.getContext('webgpu');
2733
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
@@ -90,7 +96,21 @@ let canReadVideo = false;
9096

9197
async function playVideo(videoName: keyof typeof videos) {
9298
canReadVideo = false;
93-
video.src = videos[videoName].url;
99+
100+
if (video.srcObject) {
101+
(video.srcObject as MediaStream)
102+
.getTracks()
103+
.forEach((track) => track.stop());
104+
video.srcObject = null;
105+
}
106+
107+
if (videoName === 'webcam') {
108+
video.srcObject = await navigator.mediaDevices.getUserMedia({
109+
video: true,
110+
});
111+
} else {
112+
video.src = videos[videoName].url;
113+
}
94114
await video.play();
95115
canReadVideo = true;
96116
}
@@ -120,8 +140,22 @@ function drawVideo() {
120140
const maxSize = device.limits.maxTextureDimension2D;
121141
canvas.width = Math.min(Math.max(1, canvas.offsetWidth), maxSize);
122142
canvas.height = Math.min(Math.max(1, canvas.offsetHeight), maxSize);
123-
const externalTextureSource =
124-
settings.videoSource === 'videoFrame' ? new VideoFrame(video) : video;
143+
const videoFrame =
144+
settings.videoSource === 'videoFrame' ? new VideoFrame(video) : null;
145+
const externalTextureSource = videoFrame ?? video;
146+
videoinfo.textContent = `HTMLVideoElement: ${video.videoWidth}x${video.videoHeight}`;
147+
if (videoFrame) {
148+
videoinfo.textContent +=
149+
'\nVideoFrame: ' +
150+
JSON.stringify(
151+
{
152+
codedRect: videoFrame.codedRect,
153+
visibleRect: videoFrame.visibleRect,
154+
},
155+
undefined,
156+
2
157+
);
158+
}
125159

126160
const mode = videos[settings.video].mode;
127161
const pipeline = mode === '360' ? video360Pipeline : videoCoverPipeline;
@@ -182,6 +216,9 @@ function drawVideo() {
182216
combinedAspect > 1 ? [1 / combinedAspect, 1] : [1, combinedAspect],
183217
mat
184218
);
219+
if (mode === 'mirror') {
220+
mat3.scale(mat, [-1, 1], mat);
221+
}
185222
mat3.translate(mat, [-0.5, -0.5], mat);
186223
device.queue.writeBuffer(uniformBuffer, 0, mat);
187224
}

0 commit comments

Comments
 (0)