Skip to content
FrameworkStyle

Autoplay

Start playback automatically and handle browser autoplay restrictions.

Start playback automatically when the media is ready.

For the best chance of autoplay succeeding, start playback muted and enable inline playback. Autoplay is a request, not a guarantee: browsers can block it based on audio state, prior interaction with your site, browser settings, and platform policy.

Set autoplay, muted, and inline playback on the media element, and keep a manual play control available for when autoplay is blocked.

import { Container, PlayButton } from '@videojs/react';
import { Video, VideoPlayer } from '@videojs/react/video';

export default function BasicUsage() {
  return (
    <VideoPlayer>
      <Container className="media-container">
        <Video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4" autoPlay muted playsInline />
        <PlayButton
          className="media-play-button"
          render={(props, state) => (
            <button {...props}>{state.ended ? 'Replay' : state.paused ? 'Play' : 'Pause'}</button>
          )}
        />
      </Container>
    </VideoPlayer>
  );
}

How it works

The autoPlay, muted, and playsInline props on Video and similar media components pass through to the underlying media element. When the media element supports them, they’re applied, and playback is requested as soon as the media has enough data.

The playback feature reflects the result in player state. When autoplay succeeds, paused becomes false and started becomes true. When the browser blocks autoplay, the player stays paused: true with started: false, and the Play button renders its play state. There is no separate autoplay failure event: a blocked autoplay looks like media that never started.

Calling play() from player state returns the native promise from the media element. When the browser blocks playback, that promise rejects with a NotAllowedError.

Availability and constraints

  • Autoplay can fail. Browsers decide per page load based on audio state, whether the user has interacted with your site before, browser settings, and platform policy.
  • Muted autoplay is broadly allowed. Unmuted autoplay is blocked on first visit in most browsers; do not rely on it.
  • Without inline playback, iPhone Safari opens the video in fullscreen when playback starts.
  • Low-power mode and data-saver settings can block even muted autoplay. This is why the recommended approach keeps a manual play control.
  • Programmatic volume control is unsupported on some platforms. The volume feature exposes this as volumeAvailability: 'available' | 'unavailable' | 'unsupported'; iOS Safari reports 'unsupported', and 'unavailable' means the feature hasn’t attached to a media element yet.
  • This guide applies to media components that render a video element (Video, HlsJsVideo, DashVideo, MuxVideo, and the like). Embed components (YouTube, Vimeo, TikTok, Twitch) forward autoplay to the third-party player, which applies its own autoplay rules; muted and inline behavior varies by provider.

Common variations

Background video

Background video autoplays, loops, stays muted, and omits interactive controls. Use HlsBackgroundVideo instead of configuring these behaviors yourself: it applies them by default and streams an HLS source, picking one rendition that fits the screen for the whole session.

Install the SPF adapter with the React façade:

pnpm add @videojs/react @videojs/spf
import { HlsBackgroundVideo } from '@videojs/react/media/hls-background-video';

export default function Hero() {
  return <HlsBackgroundVideo src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM.m3u8" />;
}

If you have a progressive MP4 or WebM file instead of an HLS stream, BackgroundVideo is the same component without the streaming engine. See BackgroundVideo for opt-out attributes and sizing.

Autoplay with sound

Do not rely on unmuted autoplay for a user’s first visit. Start playback from an explicit user action instead.

Call play() from the player store returned by usePlayer:

import { Container } from '@videojs/react';
import { usePlayer, Video, VideoPlayer } from '@videojs/react/video';

function StartPlaybackButton() {
  const store = usePlayer();

  return (
    <button type="button" onClick={() => store.play()}>
      Play video
    </button>
  );
}

export default function App() {
  return (
    <VideoPlayer>
      <Container>
        <Video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4" playsInline />
        <StartPlaybackButton />
      </Container>
    </VideoPlayer>
  );
}

Because playback starts from a user gesture, the browser allows it unmuted.

Troubleshooting

Playback does not start

Confirm that:

  • The media is muted.
  • Inline playback is enabled.
  • The source loads (check the network panel).
  • A manual play control is available as a fallback.

If autoplay is blocked, the player stays paused and the Play button remains in its play state; there is no error state to handle.

The video opens fullscreen on iPhone

Enable inline playback with the playsInline prop on the media component.

The video starts without sound

Expected with muted autoplay. Let the user unmute through a Mute button or Volume slider rather than unmuting programmatically; programmatic volume changes are unsupported on some platforms.