Video Players¶
Show video in your world — a cinema screen, a lobby trailer, a jukebox — from a direct file or a YouTube/Twitch link, with spatial speakers you place anywhere, and control it with no scripting. Drop a SSVideoPlayer (Add Component ▸ Social Scape/Video Player) and point it at a URL.
Windows PC. Synced is on by default — everyone shares the URL + play state + playhead (a watch‑party), and controls (load/play/seek) route through the server so they apply for all. Turn Synced off for a purely local video (e.g. a per‑player background).
The video player¶
On SSVideoPlayer:
| Field | What it does |
|---|---|
| Video Name | A handle to control this video from triggers / UI / other players' speakers (e.g. lobbyScreen). |
| Url + Source | A direct video URL (…/movie.mp4, an .m3u8 stream) or a page link (YouTube/Twitch — resolved automatically). Source = Streaming Assets plays a file you shipped under StreamingAssets/. |
| Auto Play / Loop | Start on load · repeat. |
| Muted / Volume | Master audio (per‑speaker volume is on each speaker's AudioSource). |
| Speakers | A convenience list — or use the standalone Video Speaker below. |
| Playback Rate | 1 = normal speed. |
| Screens | The objects that display the video (see below). |
The component object isn't automatically the screen
The video shows on whatever is in Screens. (If you leave Screens empty and the player's own object has a Renderer, it uses that.)
Screens¶
Add any object with a Renderer (a quad, a plane, a mesh "TV") to Screens. The video system auto‑applies the right shader — you don't need to set up a material. (If you already made a video material with the video shader, it's kept.)
Speakers — spatial audio¶
Sound comes out of speakers you place in the world. Add an SSVideoSpeaker (Add Component ▸ Social Scape/Video Speaker) to any object — it adds an AudioSource automatically — and pick which video it plays from the dropdown of video players in your scene. Use as many as you like:
- One video → speakers all over a room/world (they all play that video).
- Several video players → each with its own speakers.
- Channel mask splits a stereo video across speakers (left wall vs right wall); leave it at
-1for a normal mono speaker that plays everything.
Each speaker is a normal Unity AudioSource, so its 3D blend, volume and rolloff are your usual audio settings. No speaker on a video → it plays plain (non‑spatial) audio.
Doppler Level is always off
The platform sets every video speaker's Doppler Level to 0 automatically (it isn't yours to configure) — a
realistic Doppler pitch shift from running past a speaker isn't something anyone wants here, so it's disabled
platform-wide the same way it is for voice and regular Speakers.
Controlling video (no code)¶
From the inspector — wire UI components directly¶
The video player exposes methods you can hook from a UnityEvent on any UI control — no scripting:
| UI control | Its event | Pick on the SSVideoPlayer |
|---|---|---|
| Input field | On End Edit (string) | Load Url — type/paste a link, press Enter, it loads |
| Button | On Click | Play / Pause / Stop / Toggle Play / Restart |
| Slider | On Value Changed (float) | Seek / Set Volume / Set Rate |
| Toggle | On Value Changed (bool) | Set Muted |
In‑world UI just works — no camera setup
Put your buttons/sliders on a World Space Canvas in the world; the platform auto‑binds the player's camera so it's interactable with no setup. Players click it by looking at it (the reticle) during normal play, or with the mouse while the cursor is free (hold Alt). It works the same in 1st and 3rd person, and your avatar never blocks it.
So an in‑world "paste a link" box is just an Input Field whose On End Edit calls the player's Load Url.
From triggers — the Video Control action¶
In a World Trigger or Interactable, add an action Video Control: pick the Video name, a Command (Play / Pause / Stop / Toggle / Restart / Load / Seek / Set Volume / …), and an Argument (a URL for Load, seconds for Seek, a value for Set Volume). e.g. On zone enter → Video Control(lobbyScreen, Play), or a button On use → Video Control(lobbyScreen, TogglePlay).
From a script (NexusScript)¶
Scripts drive video through the Video.* API — the same synced path as a button or a trigger, so everyone stays in sync:
Video.Load("lobbyScreen", "https://youtu.be/..."); // resolves + plays for everyone
Video.Pause("lobbyScreen");
Video.Seek("lobbyScreen", 90); // jump to 1:30
Video.SetVolume("lobbyScreen", 0.5);
if (Video.IsPlaying("lobbyScreen")) { /* … */ }
float t = Video.GetTime("lobbyScreen"); // approx playhead (seconds)
Address a player by its Video Name. Video.GetTime is the server's playhead estimate (the exact duration / frame live on each player's machine). Full reference: NexusScript ▸ Video.
Showing playback (progress bar, time, state)¶
The player also pushes its playback data out to UnityEvents you wire to UI — so a progress bar, a time label, a play/pause icon all update themselves with no scripting. On SSVideoPlayer under UI output:
| Show this | Output event | Wire to |
|---|---|---|
| Progress bar | On Progress (float 0–1) | Slider ▸ Set Value Without Notify (dynamic float) |
Time label 1:23 / 4:56 |
On Time Text (string) | Text / TMP Text ▸ text |
| Play / pause icon | On Playing Changed (bool) | a GameObject ▸ SetActive, or your icon swapper |
| "Loading…" spinner | On Buffering (bool) | a spinner GameObject ▸ SetActive |
| Custom displays | On Time / On Duration (seconds), On Frame (int) | any float/int sink |
| React once | On Started / Finished / Ready / Error | anything |
A scrub bar that both shows progress AND seeks
Wire the slider's On Value Changed → Seek (input), and the player's On Progress → Slider.Set Value Without Notify (display). Using Set Value Without Notify (not value) stops the display update from re‑triggering a seek — no feedback loop.
Reacting to video events¶
The video raises custom signals named "<videoName>:<event>" — so you react with an On custom trigger:
lobbyScreen:started·lobbyScreen:finished·lobbyScreen:ready·lobbyScreen:error·lobbyScreen:bufferingstart/:bufferingend·:paused/:unpaused
Example — auto‑advance a playlist: On custom "lobbyScreen:finished" → Video Control(lobbyScreen, Load, next url). Or On custom "lobbyScreen:bufferingstart" → show a "loading…" object.
Examples¶
- Lobby trailer:
SSVideoPlayeron a screen quad, Url = your mp4, Auto Play + Loop on. Add aSSVideoSpeakeron a speaker prop, pick the player. Done. - Cinema with controls: a screen + speakers, plus a Button → Toggle Play, a Slider → Seek, a Slider → Set Volume.
- Paste‑a‑link board: an Input Field whose On End Edit → Load Url, so visitors queue videos (YouTube links resolve automatically).
Notes¶
- YouTube/Twitch links are resolved on each player's PC automatically — direct
.mp4/.m3u8links play instantly. - Windows PC only for now.
- Synced (default): everyone shares the same video + time; a player who falls behind on a slow connection keeps playing smoothly and can resync (they're never yanked). Turn Auto Resync on if you'd rather a behind player snap to live. Uncheck Synced for a local‑only video.
Next¶
- Drive video from logic → World Triggers & Logic · Interactables
- World setup → Worlds