Skip to content
FrameworkStyle

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.

Import

pnpm add @videojs/html @videojs/mux-video
import '@videojs/html/media/mux-video';

Or load it from the CDN:

<script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.0.0-beta.32/media/mux-video.js"></script>

Load a source

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 ignores the same source object when it is assigned again. A new object fires sourcechange even when its values are equal, although an equivalent playback source does not reload.

Posters and storyboards

MuxVideo derives a poster image and a storyboard from the playback ID. source.poster and source.storyboard configure the generated URLs.

When MuxVideo is inside a player, it supplies the poster for the skin to display. Set poster on the player when you want to use your own image instead.

MuxVideo injects the derived storyboard <track> automatically and removes it when the media detects a live stream. Configure the derived URLs through the source object:

const video = document.querySelector('mux-video')!;
video.source = {
  playbackId: 'BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM',
  poster: { time: 2, width: 1280 },
  storyboard: { format: 'webp' },
};

For declarative HTML, poster-time="2" reflects to source.poster.time after the src attribute is parsed.

The storyboard lives on a Mux domain, so MuxVideo has to be CORS-enabled for that cross-origin <track> to load at all. Thumbnail then fetches the sprite sheets its cues point at the same way:

<mux-video
  src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM.m3u8"
  crossorigin="anonymous"
></mux-video>

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.

Signed playback needs a separate token for each image URL. Put the thumbnail token (aud: 't') at source.poster.token and the storyboard token (aud: 's') at source.storyboard.token. If either token is missing or has the wrong audience, MuxVideo does not generate the corresponding URL.

const video = document.querySelector('mux-video')!;
video.source = {
  playbackId: 'BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM',
  playback: { token: playbackToken },
  poster: { token: posterToken },
  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 extensions 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:

Add @videojs/mux-data to the installation before using the telemetry component below:

pnpm add @videojs/mux-data
<script type="module">
  import '@videojs/html/video/player';
  import '@videojs/html/media/mux-video';
  import '@videojs/html/extensions/mux-data';
  import '@videojs/html/extensions/google-cast';
</script>

<video-player>
  <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>
</video-player>

Examples

Basic Usage

<media-container class="media-container">
  <mux-video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM.m3u8" autoplay muted playsinline loop crossorigin="anonymous"></mux-video>
</media-container>

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:

AttributeTypeDefaultDetails
stream-typeMediaStreamType"unknown"

Properties

PropertyTypeDefaultDetails
audioRenditionsAudioRenditionListLike | undefined
audioTracksAudioTrackListLike | undefined
contentData{ poster?: string; storyboard?: string }
disableRemotePlaybackunknownfalse
engineHls | null
errorMediaError | null
isFullscreenboolean
isPictureInPictureboolean
liveEdgeStartnumber
preloadMediaPreloadType'metadata'
source{ drm?: MuxDrmParams } | nullnull
srcstring''
streamTypeMediaStreamType"unknown"
targetLiveWindownumber
videoRenditionsVideoRenditionListLike | undefined
videoTracksVideoTrackListLike | undefined
webkitCurrentPlaybackTargetIsWirelessboolean | undefined
webkitPresentationModeWebKitPresentationMode | undefined
webkitSetPresentationMode((mode: WebKitPresentationMode) => void) | undefined

Also exposes these properties from the native media API. See HTMLVideoElement for details: autoplaybufferedcontrolscrossOrigincurrentSrccurrentTimedefaultMuteddefaultPlaybackRatedisablePictureInPicturedurationendedloopmutedpausedplaybackRateplayedplaysInlineposterreadyStateremoteseekableseekingtextTrackstitlevideoHeightvideoWidthvolume

Engine options

source.engine.hlsJs

Options passed under source.engine.hlsJs.

OptionTypeDetails
abrBandWidthFactornumber | undefined
abrBandWidthUpFactornumber | undefined
abrControllertypeof AbrController | undefined
abrEwmaDefaultEstimatenumber | undefined
abrEwmaDefaultEstimateMaxnumber | undefined
abrEwmaFastLivenumber | undefined
abrEwmaFastVoDnumber | undefined
abrEwmaSlowLivenumber | undefined
abrEwmaSlowVoDnumber | undefined
abrMaxWithRealBitrateboolean | undefined
appendErrorMaxRetrynumber | undefined
assetPlayerIdstring | undefined
audioPreferenceAudioSelectionOption | undefined
audioStreamControllertypeof AudioStreamController | undefined
audioTrackControllertypeof AudioTrackController | undefined
autoStartLoadboolean | undefined
backBufferLengthnumber | undefined
bufferControllertypeof BufferController | undefined
capLevelControllertypeof CapLevelController | undefined
capLevelOnFPSDropboolean | undefined
capLevelToPlayerSizeboolean | undefined
captionsTextTrack1Labelstring | undefined
captionsTextTrack1LanguageCodestring | undefined
captionsTextTrack2Labelstring | undefined
captionsTextTrack2LanguageCodestring | undefined
captionsTextTrack3Labelstring | undefined
captionsTextTrack3LanguageCodestring | undefined
captionsTextTrack4Labelstring | undefined
captionsTextTrack4LanguageCodestring | undefined
certLoadPolicyLoadPolicy | undefined
cmcdCMCDControllerConfig | undefined
cmcdControllertypeof CMCDController | undefined
contentSteeringControllertypeof ContentSteeringController | un...
cueHandlerCuesInterface | undefined
debugboolean | ILogger | undefined
defaultAudioCodecstring | undefined
detectStallWithCurrentTimeMsnumber | undefined
drmSystemOptionsDRMSystemOptions | undefined
drmSystemsDRMSystemsConfiguration | undefined
emeControllertypeof EMEController | undefined
emeEnabledboolean | undefined
enableCEA708Captionsboolean | undefined
enableDateRangeMetadataCuesboolean | undefined
enableEmsgKLVMetadataboolean | undefined
enableEmsgMetadataCuesboolean | undefined
enableID3MetadataCuesboolean | undefined
enableIMSC1boolean | undefined
enableInterstitialPlaybackboolean | undefined
enableSoftwareAESboolean | undefined
enableWebVTTboolean | undefined
enableWorkerboolean | undefined
errorControllertypeof ErrorController | undefined
fetchSetupRequest) | undefined | function
fLoaderFragmentLoaderConstructor | undefined
forceKeyFrameOnDiscontinuityboolean | undefined
fpsControllertypeof FPSController | undefined
fpsDroppedMonitoringPeriodnumber | undefined
fpsDroppedMonitoringThresholdnumber | undefined
fragLoadingMaxRetrynumber | undefined
fragLoadingMaxRetryTimeoutnumber | undefined
fragLoadingRetryDelaynumber | undefined
fragLoadingTimeOutnumber | undefined
fragLoadPolicyLoadPolicy | undefined
frontBufferFlushThresholdnumber | undefined
highBufferWatchdogPeriodnumber | undefined
ignoreDevicePixelRatioboolean | undefined
ignorePlaylistParsingErrorsboolean | undefined
initialLiveManifestSizenumber | undefined
interstitialAppendInPlaceboolean | undefined
interstitialAssetListLoadPolicyLoadPolicy | undefined
interstitialLiveLookAheadnumber | undefined
interstitialsControllertypeof InterstitialsController | unde...
keyLoadPolicyLoadPolicy | undefined
levelLoadingMaxRetrynumber | undefined
levelLoadingMaxRetryTimeoutnumber | undefined
levelLoadingRetryDelaynumber | undefined
levelLoadingTimeOutnumber | undefined
licenseResponseCallbackundefined | function
licenseXhrSetupUint8Array | Promise<Uint8Array | void>) | undefined | function
liveBackBufferLengthnumber | null | undefined
liveDurationInfinityboolean | undefined
liveMaxLatencyDurationnumber | undefined
liveMaxLatencyDurationCountnumber | undefined
liveSyncDurationnumber | undefined
liveSyncDurationCountnumber | undefined
liveSyncMode'edge' | 'buffered' | undefined
liveSyncOnStallIncreasenumber | undefined
loaderobject
lowLatencyModeboolean | undefined
manifestLoadingMaxRetrynumber | undefined
manifestLoadingMaxRetryTimeoutnumber | undefined
manifestLoadingRetryDelaynumber | undefined
manifestLoadingTimeOutnumber | undefined
manifestLoadPolicyLoadPolicy | undefined
maxAudioFramesDriftnumber | undefined
maxBufferHolenumber | undefined
maxBufferLengthnumber | undefined
maxBufferSizenumber | undefined
maxDevicePixelRationumber | undefined
maxFragLookUpTolerancenumber | undefined
maxLiveSyncPlaybackRatenumber | undefined
maxLoadingDelaynumber | undefined
maxMaxBufferLengthnumber | undefined
maxStarvationDelaynumber | undefined
minAutoBitratenumber | undefined
nudgeMaxRetrynumber | undefined
nudgeOffsetnumber | undefined
nudgeOnVideoHoleboolean | undefined
playlistLoadPolicyLoadPolicy | undefined
pLoaderPlaylistLoaderConstructor | undefined
preferManagedMediaSourceboolean | undefined
preserveManualLevelOnErrorboolean | undefined
primarySessionIdstring | undefined
progressiveboolean | undefined
renderTextTracksNativelyboolean | undefined
requestMediaKeySystemAccessFuncMediaKeyFunc | null | undefined
requireKeySystemAccessOnStartboolean | undefined
startFragPrefetchboolean | undefined
startLevelnumber | undefined
startOnSegmentBoundaryboolean | undefined
startPositionnumber | undefined
steeringManifestLoadPolicyLoadPolicy | undefined
stretchShortVideoTrackboolean | undefined
subtitlePreferenceSubtitleSelectionOption | undefined
subtitleStreamControllertypeof SubtitleStreamController | und...
subtitleTrackControllertypeof SubtitleTrackController | unde...
testBandwidthboolean | undefined
timelineControllertypeof TimelineController | undefined
timelineOffsetnumber | undefined
useMediaCapabilitiesboolean | undefined
videoPreferenceVideoSelectionOption | undefined
widevineLicenseUrlstring | undefined
workerPathstring | null | undefined
xhrSetupvoid) | undefined | function

source.engine.nativeHls

Options passed under source.engine.nativeHls.

OptionTypeDetails
drmSystemsDrmSystemsConfig | undefined

Methods

Supports these media methods. See HTMLVideoElement for details: addTextTrackcanPlayTypeexitFullscreenexitPictureInPictureloadpauseplayrefreshContentDatarequestFullscreenrequestPictureInPicture

Events

Re-dispatches these standard media events from the internal media element: abortaddtrackcanplaycanplaythroughchangedurationchangeemptiedendedenterpictureinpictureerrorleavepictureinpictureloadeddataloadedmetadataloadstartpauseplayplayingprogressratechangeremovetrackresizeseekedseekingstalledsuspendtimeupdatevolumechangewaiting

Also emits these Video.js-specific events:

EventDescription
contentdatachangeFired when the derived `contentData` changes. Read `contentData` for the new value.
sourcechangeFired when `source` changes, either directly or by resolving a new `src`. Read `source` for the new value.
streamtypechangeFired when the detected stream type changes. Read `streamType` for the new value.
targetlivewindowchangeFired when the target live window changes. Read `targetLiveWindow` for the new value.

CSS custom properties

VariableDetails
--media-video-border-radius
--media-object-fit
--media-object-position
--media-caption-track-duration
--media-caption-track-delay
--media-caption-track-y