Skip to content

Custom Controls

The controls slot lets you replace the entire controls row with your own UI while keeping the player's state and logic intact.

Basic Example

vue
<script setup lang="ts">
import { VideoPlayer } from '@vue-player/vue'
</script>

<template>
  <VideoPlayer src="https://example.com/video.mp4">
    <template #controls="{ state, player }">
      <div class="my-controls">
        <button @click="state.isPlaying ? player.pause() : player.play()">
          {{ state.isPlaying ? 'Pause' : 'Play' }}
        </button>
        <span>{{ Math.floor(state.currentTime) }}s / {{ Math.floor(state.duration) }}s</span>
        <button @click="player.toggleFullscreen()">Fullscreen</button>
      </div>
    </template>
  </VideoPlayer>
</template>

Slot Props

The controls slot receives two objects:

ts
{
  state: PlayerState   // readonly reactive player state
  player: PlayerControls  // methods to control playback
}

state — PlayerState

PropertyTypeDescription
isPlayingbooleanVideo is currently playing
isPausedbooleanVideo is paused
isEndedbooleanPlayback has reached the end
isLoadingbooleanSource is loading
isBufferingbooleanWaiting for data mid-playback
currentTimenumberCurrent playback position (seconds)
durationnumberTotal video duration (seconds)
bufferednumberBuffered time (seconds)
volumenumberVolume level 0–1
isMutedbooleanAudio is muted
isFullscreenbooleanFullscreen is active
isPiPbooleanPicture-in-Picture is active
isLivebooleanSource is a live stream
playbackRatenumberCurrent playback speed
currentTrackTrack | nullActive subtitle track
currentQualitynumber | 'auto'Active quality level
availableQualitiesQuality[]Quality levels from HLS manifest
errorPlayerError | nullCurrent error, if any

player — PlayerControls

MethodDescription
play()Start playback
pause()Pause playback
seek(seconds)Jump to a specific time
setVolume(value)Set volume 0–1
toggleMute()Toggle mute on/off
setSpeed(rate)Set playback speed
setQuality(value)Set quality level or 'auto'
setTrack(track)Set active subtitle track (null to disable)
toggleFullscreen()Toggle fullscreen
togglePiP()Toggle Picture-in-Picture
retry()Retry after a playback error

Mixing Default and Custom Controls

You can use the built-in control components alongside custom elements. They are exported from @vue-player/vue:

vue
<script setup>
import { VideoPlayer, VpPlayButton, VpTimeDisplay, VpFullscreenButton } from '@vue-player/vue'
</script>

<template>
  <VideoPlayer src="https://example.com/video.mp4">
    <template #controls="{ state, player }">
      <VpPlayButton :is-playing="state.isPlaying" @click="state.isPlaying ? player.pause() : player.play()" />
      <VpTimeDisplay :current-time="state.currentTime" :duration="state.duration" />
      <div style="flex: 1" />
      <VpFullscreenButton :is-fullscreen="state.isFullscreen" @click="player.toggleFullscreen()" />
    </template>
  </VideoPlayer>
</template>

Other Slots

SlotDescription
loadingCustom content inside the loading overlay
errorCustom content inside the error overlay. Receives { error: PlayerError }

Released under the MIT License.