## Install

Add **Udonite Video** from the listing. It brings [Udonite](/docs/compiler) and
[Networking](/docs/net) with it, and uses TextMeshPro, which every VRChat world project already
has.

## Put a player in the scene

**Udonite > Video > Create Video Player** builds one in front of the Scene view camera:

- an AVPro player, which plays YouTube, Twitch, Vimeo, live streams and direct files
- a 16:9 screen, with a status overlay that shows loading, errors and "Nothing playing"
- a speaker
- the control panel and the queue, under the screen
- an empty playlist, ready to fill
- AudioLink, when it is already in the scene and not listening to anything yet

Every piece is an ordinary GameObject. Move the panel to where people stand, scale the screen to
fit a wall, or delete what you do not want. The first player also imports TextMeshPro's essential
resources if the project has not yet.

That one menu item is all there is. Everything else is on the player's Inspector, under
**Add to it**.

## Try it

Press **Build & Test** in the VRChat SDK panel. Paste a link
into the panel's field and press Enter.

```text
https://www.youtube.com/watch?v=aqz-KE-bpKQ
```

Enter adds the link to the queue, or plays it at once when nothing is playing. A link that asks
for a start time starts there for everyone: `?t=90`, `&t=1m30s` and `?start=90` all work, which is
what YouTube's Share button gives you.

Launch two clients from Build & Test to watch them stay together: pause on one, and the other
pauses on the same frame.

A link VRChat does not trust needs **Allow Untrusted URLs** on in each player's settings, and the
panel says so when that is why a video failed. YouTube, Twitch and Vimeo are trusted in an
uploaded world. A local test build logs every domain as untrusted, YouTube included; that warning
alone does not stop a video.

## Add a playlist

The player plays its playlist when the queue runs out. Select the player, fill the
`VideoPlaylist` component's `urls`, and leave `titles` empty for YouTube links: the playlist's
**Fetch YouTube titles** button looks each one up and fills it in.

Turn on `autoplay` on the `VideoPlayer` to start the playlist when the instance opens, and
`shuffle` on the playlist to play it in random order.

From an editor script it is the same thing:

```csharp
VideoPlaylist playlist = VideoSetup.AddPlaylist(player, autoplay: true);
VideoSetup.AddToPlaylist(playlist, "https://www.youtube.com/watch?v=aqz-KE-bpKQ");
VideoSetup.AddToPlaylist(playlist, "https://example.com/intro.mp4", "Welcome");
VideoSetup.FetchTitles(playlist);
```

## Lock it to staff

The lock button on the panel, or `startLocked` on the player, keeps the controls with the
instance owner, the master and the display names in `moderators`. Everyone else can still change
their own volume and reload their own picture.

A locked player also refuses to give its ownership to anyone else, so a modified client cannot
take it over.

## More screens and AudioLink

Drop any renderer on **Another screen** in the player's Inspector: it shows the same video, with
its own letterboxing. A TV mesh, a projector wall and a phone in a player's hand can all show one
player.

AudioLink added after the player gets a **Connect AudioLink to this player** button on the player's
Inspector, which points it at the player's speaker.
