mux-video
Video element for Mux-hosted HLS streams
Video element for playing Mux-hosted HLS streams. Built on hls.js with Mux-specific optimizations.
Load a source
The source param builds the URL for you from a playback ID, an optional custom domain, and playback params. Playback params are just camelCased Mux playback query params; for example, max_resolution becomes maxResolution.
<MuxVideo
source={{
playbackId: 'BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM',
customDomain: 'media.example.com',
playback: { maxResolution: '1080p' }
}}
/>If for some reason you need a bit more control, you can use the src param with a plain ’ol URL, too:
<MuxVideo
src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM.m3u8"
/>MuxVideo fires a sourcechange event when the source actually changes. Setting the same values again, like a fresh object on a React re-render, doesn’t fire it.
MuxVideo takes Mux content two ways: a stream URL through src, or a structured source object.
<mux-video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM.m3u8"></mux-video>The source object builds the URL for you from a playback ID, an optional custom domain, and playback params. Playback params are just camelCased Mux playback query params; for example, max_resolution becomes maxResolution.
const video = document.querySelector('mux-video');
video.source = {
playbackId: 'BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM',
customDomain: 'media.example.com',
playback: { maxResolution: '1080p' },
};MuxVideo fires a sourcechange event when the source actually changes. Setting the same values again doesn’t fire it.
Thumbnails and storyboards
thumbnail and storyboard default to URLs derived from source: the poster image and the storyboard VTT that drives hover previews on the time slider. MuxVideo injects the storyboard <track> automatically, skipping it for live streams. Set either prop to a URL to override the derived one.
Signed playback
For signed playback, put the playback token on source.playback.token. The token replaces every other playback param, so bake modifiers like resolution and time bounds into the token when you sign it.
Thumbnail and storyboard URLs need their own audience-scoped tokens, source.thumbnail.token (aud: 't') and source.storyboard.token (aud: 's'). Without a matching image token, MuxVideo derives no thumbnail or storyboard URL, since an unsigned request would be rejected.
<MuxVideo
source={{
playbackId: 'BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM',
playback: { token: playbackToken },
thumbnail: { token: thumbnailToken },
storyboard: { token: storyboardToken },
}}
/>const video = document.querySelector('mux-video');
video.source = {
playbackId: 'BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM',
playback: { token: playbackToken },
thumbnail: { token: thumbnailToken },
storyboard: { token: storyboardToken },
};Analytics and casting
MuxVideo plays Mux streams. It doesn’t monitor them or cast them — Mux Data and Google Cast are separate components you add to the player alongside it. Mux Data needs no environment key here, since Mux attributes the views to the environment that owns the playback ID:
import { GoogleCast } from '@videojs/react/media/google-cast';
import { MuxData } from '@videojs/react/media/mux-data';
import { MuxVideo } from '@videojs/react/media/mux-video';
<MuxVideo source={{ playbackId: 'BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM' }} playsInline />
<MuxData playerSoftwareName="mux-video" />
<GoogleCast /><mux-video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM.m3u8" playsinline></mux-video>
<mux-data player-software-name="mux-video"></mux-data>
<google-cast></google-cast>Register the elements by importing @videojs/html/media/mux-data and @videojs/html/media/google-cast.
Examples
Basic Usage
import { MuxVideo } from '@videojs/react/media/mux-video';
export default function BasicUsage() {
return (
<MuxVideo
className="mux-video"
src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM.m3u8"
autoPlay
muted
playsInline
loop
crossOrigin="anonymous"
/>
);
}
.mux-video {
width: 100%;
aspect-ratio: 16 / 9;
}
<media-container class="media-container">
<mux-video
src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM.m3u8"
autoplay
muted
playsinline
loop
crossorigin="anonymous"
></mux-video>
</media-container>
.media-container {
position: relative;
display: block;
width: 100%;
aspect-ratio: 16 / 9;
}
import '@videojs/html/media/container';
import '@videojs/html/media/mux-video';
API Reference
Attributes
Forwards these standard media attributes to the internal <video>. See the MDN media element reference: autopictureinpictureautoplaycontrolscontrolslistcrossorigindisablepictureinpicturedisableremoteplaybackloadingloopmutedplaysinlineposterpreloadsrc
These Video.js-specific attributes configure media behavior:
| Attribute | Type | Default | Details |
|---|---|---|---|
stream-type | StreamType | 'unknown' | |
| |||
Properties
| Property | Type | Default | Details |
|---|---|---|---|
audioRenditions | AudioRenditionListLike | undefined | — | |
| |||
audioTracks | AudioTrackListLike | undefined | — | |
| |||
config | HlsMediaConfig | {} | |
| |||
engine | Hls | null | — | |
| |||
error | (ErrorLike & MediaError) | null | — | |
| |||
isFullscreen | boolean | — | |
| |||
isPictureInPicture | boolean | — | |
| |||
liveEdgeStart | number | — | |
| |||
preload | PreloadType | 'metadata' | |
| |||
source | MuxSource | null | null | |
| |||
src | string | '' | |
| |||
storyboard | string | '' | |
| |||
streamType | StreamType | 'unknown' | |
| |||
targetLiveWindow | number | — | |
| |||
thumbnail | string | '' | |
| |||
videoRenditions | VideoRenditionListLike | undefined | — | |
| |||
videoTracks | VideoTrackListLike | undefined | — | |
| |||
webkitCurrentPlaybackTargetIsWireless | boolean | undefined | — | |
| |||
webkitPresentationMode | WebKitPresentationMode | undefined | — | |
| |||
webkitSetPresentationMode | ((mode: WebKitPresentationMode) => void) | undefined | — | |
| |||
Also exposes these properties from the native media API. See HTMLVideoElement for details: autoplaybufferedcontrolscrossOrigincurrentSrccurrentTimedefaultMuteddefaultPlaybackRatedisablePictureInPicturedisableRemotePlaybackdurationendedloopmutedpausedplaybackRateplayedplaysInlineposterreadyStateremoteseekableseekingtextTrackstitlevideoHeightvideoWidthvolume
Methods
Supports these media methods. See HTMLVideoElement for details: addTextTrackcanPlayTypeexitFullscreenexitPictureInPictureloadpauseplayrequestFullscreenrequestPictureInPicture
Events
Re-dispatches these standard media events from the internal media element: abortaddtrackcanplaycanplaythroughchangedurationchangeemptiedendedenterpictureinpictureerrorleavepictureinpictureloadeddataloadedmetadataloadstartpauseplayplayingprogressratechangeremovetrackresizeseekedseekingstalledsuspendtimeupdatevolumechangewaiting
Also emits these Video.js-specific events:
| Event | Description |
|---|---|
sourcechange | Fired when `source` changes, either directly or by parsing a new `src`. Read `source` for the new value. |
streamtypechange | Fired when the detected stream type changes. Read `streamType` for the new value. |
targetlivewindowchange | Fired when the target live window changes. Read `targetLiveWindow` for the new value. |
CSS custom properties
| Variable | Details |
|---|---|
--media-video-border-radius | |
| |
--media-object-fit | |
| |
--media-object-position | |
| |
--media-caption-track-duration | |
| |
--media-caption-track-delay | |
| |
--media-caption-track-y | |
| |