Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

arxstream

A two-person watch party. Upload a video to the server, and both of you get the same playhead, a chat sidebar, and each other's webcam.

  • Upload from the browser — drag a file anywhere onto the page, or hit in the toolbar. It streams straight to disk with a progress bar, then loads on both screens automatically. 🗑 removes it again.
  • Or paste a direct link — paste a video URL anywhere outside the chat box (or use 🔗) and the server downloads it, so a big file never has to make the round trip through your browser. Both people see the progress bar; either can cancel.
  • Synced playback — play, pause, seek, and file selection propagate to the other person. The server holds the authoritative playhead, so whoever joins second (or reconnects) lands at the right spot. Drift is corrected silently every 3s.
  • Chat — WebSocket, last 50 messages replayed on join.
  • Webcam + mic — peer-to-peer WebRTC; the server only relays signaling.
  • Room of 2 — a third connection is turned away.

Run locally

npm install
npm start        # http://localhost:3000

Open two browser tabs, join with different names, drag in a video.

Camera/mic need a secure context: localhost works, plain http://<lan-ip> does not. Over HTTPS on Render both work fine.

Deploy to Render

  1. Push the repo to GitHub (videos are gitignored — you upload them after deploy).
  2. On Render: New → Web Service, point it at the repo. render.yaml already sets build npm install and start npm start; otherwise enter those manually.
  3. Open the URL, upload your video, share the link.

Optional: set a ROOM_PASSWORD env var in the Render dashboard to gate the room — the join screen shows a password field automatically when it's set.

Things to know about the free plan

  • The disk is ephemeral. Uploads live in media/ on the instance and are wiped by any redeploy or restart — including the restart after the instance sleeps. Plan on re-uploading before a session, or attach a Render persistent disk mounted at /opt/render/project/src/media (a paid feature) to keep files around.
  • Free instances sleep after ~15 min idle and cold-start in ~30s.
  • Big uploads over a slow link can time out at Render's proxy. If a large file keeps failing, compress it first (ffmpeg -i in.mkv -c:v libx264 -crf 24 out.mp4) or upload from the faster of your two connections. Pasting a link avoids this entirely — the transfer happens server-to-server.
  • Free instances have only a few GB of ephemeral disk. A 3–4 GB movie may not fit at all, and the download will die partway with a disk error. Re-encode to something in the 1–2 GB range, or attach a persistent disk.
  • Bandwidth: two people streaming a movie is a few GB. Watch the free tier's 100 GB/month cap.
  • WebRTC without TURN: the webcam link uses public STUN only. That connects for most home networks; behind symmetric NAT or strict corporate firewalls it won't, and the camera panel will read failed. Chat and video sync are unaffected — they go through the server. Add a TURN server (Twilio, Metered, or coturn) to RTC_CONFIG in public/app.js if you need it.

Controls

Action
Space play / pause
← / → seek 5s
Resync jump to the server's playhead
↑ / drag-drop upload a video
🔗 / paste a URL server-side download from a link
fullscreen

Accepted formats are whatever the browser can play: .mp4, .webm, .mkv, .mov, .m4v, .ogv. H.264 .mp4 is the safest bet.

.mkv is the usual source of "video plays, no sound." Chrome can't decode AC-3 or E-AC-3 audio, which most .mkv releases ship. Remux to .mp4 with AAC audio first — this is fast and doesn't re-encode the video:

ffmpeg -i in.mkv -c:v copy -c:a aac -b:a 192k -movflags +faststart out.mp4

+faststart matters: it moves the index to the front so the file starts playing before it's fully buffered, and seeking stays snappy.

Layout

  • server.js — static files with range requests, upload/delete/list API, and the WebSocket room (state, chat, signaling relay).
  • public/app.js — player sync, upload, chat UI, WebRTC negotiation.
  • public/index.html, public/style.css — UI.
  • media/ — uploaded videos land here.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages