Streaming audio, video, and other data from the browser to the server without WebSockets or WebRTC.
npm install svelte-stream
<script lang="ts">
import { StreamingClient } from 'svelte-stream/client';
import { onMount } from 'svelte';
let client: StreamingClient;
let stream: MediaStream;
let mediaRecorder: MediaRecorder;
let isRecording = false;
onMount(async () => {
client = new StreamingClient('/api');
stream = await navigator.mediaDevices.getUserMedia({ audio: true });
mediaRecorder = new MediaRecorder(stream);
});
async function toggleRecording() {
if (isRecording) {
stopRecording();
} else {
startRecording();
}
}
async function startRecording() {
const readable = new ReadableStream({
start(controller) {
mediaRecorder.ondataavailable = (event) => {
controller.enqueue(event.data);
};
mediaRecorder.onstop = () => {
controller.close();
};
mediaRecorder.start(1000);
}
});
const id = await client.getStarted();
const res = await client.send(id, readable, callback);
const final = await res.json();
console.log(final);
}
function stopRecording() {
isRecording = false;
mediaRecorder.stop();
}
async function callback(res: Response) {
const data = await res.json();
console.log(data);
}
</script>
import { StreamingHandler, StreamingHandleError, FinalizedStreamingData } from 'svelte-stream';
import { error, json, type RequestHandler } from '@sveltejs/kit';
const handler = new StreamingHandler();
export const GET: RequestHandler = async () => {
return handler.start();
};
export const POST: RequestHandler = async (evt) => {
try {
const data = await handler.handle(evt.request);
if (data instanceof FinalizedStreamingData) {
console.log('final', data.id);
return json({ message: `final ${data.id} (${data.all.byteLength} bytes)` });
} else {
console.log('partial', data.id, data.segment);
return json({
message: `partial ${data.id} ${data.segment} (${data.partial.byteLength} bytes)`
});
}
} catch (e) {
if (e instanceof StreamingHandleError) {
return e.response();
} else {
error(500, 'unknown error');
}
}
};