Examples
Camera
About
A live camera, from RTP to the page.
quillo run media.qwe --watch then open http://localhost:8080
Then send it a stream. A test picture and a tone, with ffmpeg:
ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 -f lavfi -i sine=frequency=440
-map 0:v -c:v libx264 -tune zerolatency -profile:v baseline -pix_fmt yuv420p -g 60
-f rtp rtp://127.0.0.1:5004 -map 1:a -c:a libopus -f rtp rtp://127.0.0.1:5006
or this Mac's camera and microphone (-f v4l2 -i /dev/video0 on Linux):
ffmpeg -f avfoundation -framerate 30 -video_size 1280x720 -i "0:0"
-map 0:v -c:v libx264 -tune zerolatency -profile:v baseline -pix_fmt yuv420p -g 60
-f rtp rtp://127.0.0.1:5004 -map 0:a -c:a libopus -f rtp rtp://127.0.0.1:5006
The server takes the RTP and passes the frames on to every page watching, over WebTransport where the browser has it: no transcoding, no HLS segments, a fraction of a second behind the camera. A page that starts watching gets the frames since the last keyframe, so it shows a picture at once. Each <quillo-media> decodes with the browser's own decoders (WebCodecs); click it for sound.
Run it
$ quillo run media.qwe --watchSource
media.rtp("cam", { video: 5004, audio: 5006 })server fn live_streams() -> list = media.streams()// How the stream is going, asked for every second.component Stats() { state streams = live_streams() every(1000, () => { streams = live_streams() ?? streams }) <p.stats> {for s in streams => <span key={s.name}> <b>{s.video.fps}</b> fps · <b>{s.video.kbps + s.audio.kbps}</b> kbit/s · <b>{s.viewers}</b> watching · <b>{s.video.lost + s.audio.lost}</b> packets lost </span>} </p>}let style = css`* { box-sizing: border-box; }body { font: 15px/1.4 system-ui, sans-serif; max-width: 60rem; margin: 2rem auto; padding: 0 1rem; color: #1f2328; }h1 { font-size: 1.4rem; margin: 0 0 1rem; }quillo-media { width: 100%; border-radius: 10px; overflow: hidden; background: #000; aspect-ratio: 16 / 9; }quillo-media[data-state="connecting"]::after, quillo-media[data-state="waiting"]::after { content: "Waiting for the stream…"; position: absolute; inset: 0; display: grid; place-items: center; color: #aaa;}.stats { color: #57606a; font-variant-numeric: tabular-nums; } .stats b { color: #1f2328; }@media (prefers-color-scheme: dark) { body { background: #0d1117; color: #e6edf3; } .stats { color: #8b949e; } .stats b { color: #e6edf3; } }`route GET / = <html> <head> <meta charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <title>Camera</title> <style>{style}</style> </head> <body> <h1>Camera</h1> <quillo-media stream="cam" controls muted/> <Stats/> </body> </html>Thread 0 posts
On Camera: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.