[@layout]: ../docs.layout.md

# Video

Install and activate the optional Video Plugin with `bun run pmx plugins add video`
before using `@video` in your project.

Embed a video with a titled Markdown link. This supplied motion study includes
captions and loads when you press Play:

[@video(captions="../../examples/video/easing.en.vtt" language="en" width=640) Compare linear and eased motion](../../examples/video/easing.mp4)

The caption describes the movement; ordinary video links remain links. YouTube,
Vimeo, Loom, and local files use the same directive with provider-specific options.

---

## Setup

```sh
bun run pmx plugins add video
```

This installs `@pathmx/video` and activates it in `package.json`. Start from an
initialized [Quickstart project](../start/first-site.guide.md).

Save the supplied [MP4](../../examples/video/easing.mp4) and
[WebVTT captions](../../examples/video/easing.en.vtt) into `paths/video/`, keeping
the filenames `easing.mp4` and `easing.en.vtt`. Create `paths/motion.page.md`:

```md
# Compare two movements

[@video(captions="./video/easing.en.vtt" language="en") Linear and eased motion](./video/easing.mp4)
```

Run `bun run dev`, open `/motion.page`, and play the video. Use CC to hide/show
captions; pause and resume to compare the two motions. The actual caption file
starts with `WEBVTT` and contains timed text cues; it is ready to use beside the
supplied clip.

---

## Thumbnails

YouTube, Vimeo, and Loom use their provider thumbnails automatically. Choose a
different preview with `thumbnail`, using a path relative to the Source or an
HTTPS image URL:

```md
[@video(thumbnail="./images/presentation.jpg") Recording a presentation](https://www.loom.com/share/e00c8856f48049519ca6bece165b449a)
```

The image appears before playback. A missing thumbnail leaves the Play button
available. Changing the preview during a live edit does not restart playback.

---

## Video files

Local files and HTTPS video-file URLs use the same directive:

```md
[@video(thumbnail="./motion-preview.svg" width=640) Motion study](./motion.mp4)
```

MP4, WebM, MOV, and M4V file URLs are supported. Playback depends on the browser's
support for the file's codecs. `width` sets a maximum width in CSS pixels; the
video still shrinks to fit its container. At widths of 360px or less, shared
playback controls sit below the picture so touch targets do not obscure it. Without it, the video uses the content
width. Playback shows the complete picture without cropping.

---

## Captions for video files

Attach one WebVTT caption track and its language:

```md
[@video(captions="./lesson.en.vtt" language="en") Lesson](./lesson.mp4)
```

`captions` accepts a local `.vtt` path or an HTTPS URL. `language` is required;
use a language tag such as `en`, `es-MX`, or `fr`. Paths resolve relative to the
Source, just like thumbnails.

Captions are enabled initially and can be toggled with the CC control. Editing
the caption reference preserves the video's playback position. Automatically
positioned captions stay clear of visible controls; explicit positions in the
WebVTT file remain as authored. If the track fails to load, playback remains
available and a caption error appears.

When a captioned video or its track comes from another origin, that server must
allow anonymous cross-origin requests (CORS). Serving both files with your site
avoids additional server configuration.

YouTube, Vimeo, and Loom use captions supplied by their providers. The `captions`
and `language` parameters apply to video files.

---

## Start at a moment

Put the starting time in the URL, using seconds or hours, minutes, and seconds:

```md
[@video Layout & Composition](https://youtu.be/a5KYlHNKQB8?t=1m)

[@video Alike](https://vimeo.com/194276412#t=1m)

[@video Motion study](./motion.mp4?t=1)
```

YouTube watch, short, Shorts, live, and embed URLs are supported, along with Loom
share and embed URLs. Vimeo video-page and player URLs are also supported. For
an unlisted Vimeo video, keep the complete sharing URL, including its privacy hash:

```md
[@video Vimeo film](https://vimeo.com/194276412)

[@video Unlisted recording](https://player.vimeo.com/video/76979871?h=8272103f6e)
```

Use a single video rather than a playlist or channel.

---

## Playback

The authored title names the player for assistive technology. Give each video a
clear title describing its content.

YouTube and video files use a compact floating control island for playback,
seeking, speed, volume, and fullscreen. It fades after a short period of idle
playback and returns on pointer movement, a tap, or keyboard interaction. It
stays visible while paused or while its controls are focused or being adjusted.
The volume slider appears when its control is hovered or focused. Browsers
that require device volume controls omit the slider. Video files also offer
picture-in-picture when the browser supports it. On narrow players, additional
controls wrap below the timeline to preserve touch targets.

YouTube captions are requested on when available; open YouTube to change caption
settings when using the floating controls. On browsers without page
fullscreen support, YouTube uses its native player. On iPhone Safari, playback
opens in the system fullscreen player; closing it returns to the page. Safari
may require a second tap on YouTube’s Play button after loading the embed.
Vimeo and Loom use their
built-in controls, including the options allowed by the video owner.

If a video using the floating controls cannot play, a link to open the video
appears. Native provider players handle their own playback errors.
For broad device support, use H.264 video in an MP4 file. WebM support depends
on the browser and device. A browser that reports WebM as unsupported shows
the open-video fallback.

Embedded videos remain subject to their provider's access restrictions.

Try the [video example](../../examples/video.demo.md).


---

## Focus and Slides

When Player is active, a standalone video is one Beat with its authored title.
Its preview and playing instance share the same place in the sequence. Authored
Beat groups remain groups. Activating the Beat does not start playback.

Focus dims the surrounding page and expands the active video to fit the
viewport. Use the expand/reduce icon to compare this immersive view with the
authored size and normal Focus lighting. Fullscreen remains a separate playback control. A video-only slide centers
the video against a dark background, preserving the complete picture.

Play/Pause and expansion appear as icon-and-label [Beat actions](../learning/player.reference.md#beat-actions).
Keyboard input inside video controls stays with the video. Moving to another
Beat or opening the Block Grid pauses controllable playback; returning keeps its
position. Switching modes preserves the media instance, and finishing a video
does not automatically advance. Provider-native iframes retain their own playback
controls and may not support pausing when leaving a Beat.

Try the [short video lesson](../../examples/video-focus.demo.md?play=focus).
