samme
samme
DDeno
Created by samme on 4/28/2024 in #help
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:
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>
),
});
});
2 replies
DDeno
Created by samme on 5/11/2023 in #help
VSCode "quick fix" for missing import doesn't use import map
2 replies