Source code

Revision control

Copy as Markdown

Other Tools

function createAudioStream(t) {
const ac = new AudioContext();
const { stream } = ac.createMediaStreamDestination();
const [track] = stream.getTracks();
t.add_cleanup(() => {
ac.close();
track.stop();
});
return { stream };
}
function createFlowingAudioStream(t) {
const ac = new AudioContext();
const dest = ac.createMediaStreamDestination();
const osc = ac.createOscillator();
osc.connect(dest);
osc.start();
const [track] = dest.stream.getTracks();
t.add_cleanup(() => {
ac.close();
track.stop();
});
return { stream: dest.stream };
}
function createVideoStream(t) {
const canvas = document.createElement("canvas");
canvas.id = "canvas";
document.body.appendChild(canvas);
const ctx = canvas.getContext("2d");
const stream = canvas.captureStream();
const [track] = stream.getTracks();
t.add_cleanup(() => {
document.body.removeChild(canvas);
track.stop();
});
const addVideoFrame = () => {
ctx.fillStyle = "red";
ctx.fillRect(0, 0, canvas.width, canvas.height);
};
return { stream, control: { addVideoFrame } };
}
function createFlowingVideoStream(t) {
const { stream } = createVideoStream(t);
const [track] = stream.getTracks();
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
ctx.fillStyle = "green";
requestAnimationFrame(function draw() {
ctx.fillRect(0, 0, canvas.width, canvas.height);
if (track.readyState == "live") {
requestAnimationFrame(draw);
}
});
return { stream };
}
function createAudioVideoStream(t) {
const { stream: audio } = createAudioStream(t);
const { stream: video, control } = createVideoStream(t);
return {
stream: new MediaStream([...audio.getTracks(), ...video.getTracks()]),
control,
};
}
function createFlowingAudioVideoStream(t) {
return {
stream: new MediaStream([
...createFlowingAudioStream(t).stream.getTracks(),
...createFlowingVideoStream(t).stream.getTracks(),
]),
};
}