Streaming video from browser to deno server
Trying to stream video from Chrome to my local Deno server but having trouble understanding how to pipe things up correctly.
When I visit localhost:8000, which hits the /video endpont via the <video> element, the /receive endpoint throws this error:
Here's my setup:
Pasted into Chrome console:
Deno server:
When I visit localhost:8000, which hits the /video endpont via the <video> element, the /receive endpoint throws this error:
TypeError: The destination writable stream closed before all the data could be piped to it.
at readableStreamPipeTo (ext:deno_web/06_streams.js:2784:24)
at ReadableStream.pipeTo (ext:deno_web/06_streams.js:5340:12)TypeError: The destination writable stream closed before all the data could be piped to it.
at readableStreamPipeTo (ext:deno_web/06_streams.js:2784:24)
at ReadableStream.pipeTo (ext:deno_web/06_streams.js:5340:12)Here's my setup:
Pasted into Chrome console:
(async () => {
const video = document.querySelector('video');
if (!video) {
return;
}
const stream = video.captureStream();
if (!stream) {
return;
}
console.log('Streaming video...');
const mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = async (event) => {
if (event.data.size > 0) {
await fetch('http://localhost:8000/receive', {
method: 'POST',
body: event.data
});
}
};
mediaRecorder.start(1000);
video.onended = () => {
mediaRecorder.stop();
console.log('Done streaming video');
};
})();(async () => {
const video = document.querySelector('video');
if (!video) {
return;
}
const stream = video.captureStream();
if (!stream) {
return;
}
console.log('Streaming video...');
const mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = async (event) => {
if (event.data.size > 0) {
await fetch('http://localhost:8000/receive', {
method: 'POST',
body: event.data
});
}
};
mediaRecorder.start(1000);
video.onended = () => {
mediaRecorder.stop();
console.log('Done streaming video');
};
})();Deno server:
/** @jsx h */
import html, { h } from "https://deno.land/x/htm@0.2.3/mod.ts";
const writables = [] as WritableStream[];
Deno.serve({ port: 8000 }, async (request: Request) => {
if (request.url.endsWith("/receive")) {
await Promise.all(writables.map(async (writable) => {
await request.body?.pipeTo(writable)
}));
return new Response(null, { status: 200 });
}
if (request.url.endsWith("/video")) {
const headers = new Headers();
headers.set("Content-Type", "video/mp4");
const { readable, writable } = new TransformStream();
writables.push(writable);
return new Response(readable, { headers });
}
return html({
title: "Stream",
body: (
<body>
<video width="100%" height="100%" src="/video" autoplay controls></video>
</body>
),
});
});/** @jsx h */
import html, { h } from "https://deno.land/x/htm@0.2.3/mod.ts";
const writables = [] as WritableStream[];
Deno.serve({ port: 8000 }, async (request: Request) => {
if (request.url.endsWith("/receive")) {
await Promise.all(writables.map(async (writable) => {
await request.body?.pipeTo(writable)
}));
return new Response(null, { status: 200 });
}
if (request.url.endsWith("/video")) {
const headers = new Headers();
headers.set("Content-Type", "video/mp4");
const { readable, writable } = new TransformStream();
writables.push(writable);
return new Response(readable, { headers });
}
return html({
title: "Stream",
body: (
<body>
<video width="100%" height="100%" src="/video" autoplay controls></video>
</body>
),
});
});