chore: consolidate new foundation and archive v1 (#1495)

This commit is contained in:
2026-09-07 12:32:57 -05:00
3511 changed files with 727899 additions and 10 deletions
@@ -0,0 +1,539 @@
---
category: Browser
---
# useMediaControls
Reactive media controls for both `audio` and `video` elements
## Usage
### Basic Usage
```vue
<script setup lang="ts">
import { useMediaControls } from '@vueuse/core';
import { onMounted, useTemplateRef } from 'vue';
const video = useTemplateRef('video');
const { playing, currentTime, duration, volume } = useMediaControls(video, {
src: 'video.mp4',
});
// Change initial media properties
onMounted(() => {
volume.value = 0.5;
currentTime.value = 60;
});
</script>
<template>
<video ref="video" />
<button @click="playing = !playing">Play / Pause</button>
<span>{{ currentTime }} / {{ duration }}</span>
</template>
```
### Providing Captions, Subtitles, etc...
You can provide captions, subtitles, etc in the `tracks` options of the
`useMediaControls` function. The function will return an array of tracks
along with two functions for controlling them, `enableTrack`, `disableTrack`, and `selectedTrack`.
Using these you can manage the currently selected track. `selectedTrack` will
be `-1` if there is no selected track.
```vue
<script setup lang="ts">
import { useMediaControls } from '@vueuse/core';
import { useTemplateRef } from 'vue';
const video = useTemplateRef('video');
const { tracks, enableTrack } = useMediaControls(video, {
src: 'video.mp4',
tracks: [
{
default: true,
src: './subtitles.vtt',
kind: 'subtitles',
label: 'English',
srcLang: 'en',
},
],
});
</script>
<template>
<video ref="video" />
<button v-for="track in tracks" :key="track.id" @click="enableTrack(track)">
{{ track.label }}
</button>
</template>
```
## Type Declarations
```ts
/**
* Many of the jsdoc definitions here are modified version of the
* documentation from MDN(https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement)
*/
export interface UseMediaSource {
/**
* The source url for the media
*/
src: string;
/**
* The media codec type
*/
type?: string;
/**
* Specifies the media query for the resource's intended media.
*/
media?: string;
}
export interface UseMediaTextTrackSource {
/**
* Indicates that the track should be enabled unless the user's preferences indicate
* that another track is more appropriate
*/
default?: boolean;
/**
* How the text track is meant to be used. If omitted the default kind is subtitles.
*/
kind: TextTrackKind;
/**
* A user-readable title of the text track which is used by the browser
* when listing available text tracks.
*/
label: string;
/**
* Address of the track (.vtt file). Must be a valid URL. This attribute
* must be specified and its URL value must have the same origin as the document
*/
src: string;
/**
* Language of the track text data. It must be a valid BCP 47 language tag.
* If the kind attribute is set to subtitles, then srclang must be defined.
*/
srcLang: string;
}
interface UseMediaControlsOptions extends ConfigurableDocument {
/**
* The source for the media, may either be a string, a `UseMediaSource` object, or a list
* of `UseMediaSource` objects.
*/
src?: MaybeRefOrGetter<string | UseMediaSource | UseMediaSource[]>;
/**
* A list of text tracks for the media
*/
tracks?: MaybeRefOrGetter<UseMediaTextTrackSource[]>;
}
export interface UseMediaTextTrack {
/**
* The index of the text track
*/
id: number;
/**
* The text track label
*/
label: string;
/**
* Language of the track text data. It must be a valid BCP 47 language tag.
* If the kind attribute is set to subtitles, then srclang must be defined.
*/
language: string;
/**
* Specifies the display mode of the text track, either `disabled`,
* `hidden`, or `showing`
*/
mode: TextTrackMode;
/**
* How the text track is meant to be used. If omitted the default kind is subtitles.
*/
kind: TextTrackKind;
/**
* Indicates the track's in-band metadata track dispatch type.
*/
inBandMetadataTrackDispatchType: string;
/**
* A list of text track cues
*/
cues: TextTrackCueList | null;
/**
* A list of active text track cues
*/
activeCues: TextTrackCueList | null;
}
export declare function useMediaControls(
target: MaybeRef<HTMLMediaElement | null | undefined>,
options?: UseMediaControlsOptions,
): {
currentTime: ShallowRef<number, number>;
duration: ShallowRef<number, number>;
waiting: ShallowRef<boolean, boolean>;
seeking: ShallowRef<boolean, boolean>;
ended: ShallowRef<boolean, boolean>;
stalled: ShallowRef<boolean, boolean>;
buffered: Ref<[number, number][], [number, number][]>;
playing: ShallowRef<boolean, boolean>;
rate: ShallowRef<number, number>;
volume: ShallowRef<number, number>;
muted: ShallowRef<boolean, boolean>;
tracks: Ref<
{
id: number;
label: string;
language: string;
mode: TextTrackMode;
kind: TextTrackKind;
inBandMetadataTrackDispatchType: string;
cues: {
[x: number]: {
endTime: number;
id: string;
onenter: ((this: TextTrackCue, ev: Event) => any) | null;
onexit: ((this: TextTrackCue, ev: Event) => any) | null;
pauseOnExit: boolean;
startTime: number;
readonly track: {
readonly activeCues: /*elided*/ any | null;
readonly cues: /*elided*/ any | null;
readonly id: string;
readonly inBandMetadataTrackDispatchType: string;
readonly kind: TextTrackKind;
readonly label: string;
readonly language: string;
mode: TextTrackMode;
oncuechange: ((this: TextTrack, ev: Event) => any) | null;
addCue: (cue: TextTrackCue) => void;
removeCue: (cue: TextTrackCue) => void;
addEventListener: {
<K extends keyof TextTrackEventMap>(
type: K,
listener: (this: TextTrack, ev: TextTrackEventMap[K]) => any,
options?: boolean | AddEventListenerOptions,
): void;
(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | AddEventListenerOptions,
): void;
};
removeEventListener: {
<K extends keyof TextTrackEventMap>(
type: K,
listener: (this: TextTrack, ev: TextTrackEventMap[K]) => any,
options?: boolean | EventListenerOptions,
): void;
(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | EventListenerOptions,
): void;
};
dispatchEvent: {
(event: Event): boolean;
(event: Event): boolean;
};
} | null;
addEventListener: {
<K extends keyof TextTrackCueEventMap>(
type: K,
listener: (this: TextTrackCue, ev: TextTrackCueEventMap[K]) => any,
options?: boolean | AddEventListenerOptions,
): void;
(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | AddEventListenerOptions,
): void;
};
removeEventListener: {
<K extends keyof TextTrackCueEventMap>(
type: K,
listener: (this: TextTrackCue, ev: TextTrackCueEventMap[K]) => any,
options?: boolean | EventListenerOptions,
): void;
(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | EventListenerOptions,
): void;
};
dispatchEvent: {
(event: Event): boolean;
(event: Event): boolean;
};
};
readonly length: number;
getCueById: (id: string) => TextTrackCue | null;
[Symbol.iterator]: () => ArrayIterator<TextTrackCue>;
} | null;
activeCues: {
[x: number]: {
endTime: number;
id: string;
onenter: ((this: TextTrackCue, ev: Event) => any) | null;
onexit: ((this: TextTrackCue, ev: Event) => any) | null;
pauseOnExit: boolean;
startTime: number;
readonly track: {
readonly activeCues: /*elided*/ any | null;
readonly cues: /*elided*/ any | null;
readonly id: string;
readonly inBandMetadataTrackDispatchType: string;
readonly kind: TextTrackKind;
readonly label: string;
readonly language: string;
mode: TextTrackMode;
oncuechange: ((this: TextTrack, ev: Event) => any) | null;
addCue: (cue: TextTrackCue) => void;
removeCue: (cue: TextTrackCue) => void;
addEventListener: {
<K extends keyof TextTrackEventMap>(
type: K,
listener: (this: TextTrack, ev: TextTrackEventMap[K]) => any,
options?: boolean | AddEventListenerOptions,
): void;
(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | AddEventListenerOptions,
): void;
};
removeEventListener: {
<K extends keyof TextTrackEventMap>(
type: K,
listener: (this: TextTrack, ev: TextTrackEventMap[K]) => any,
options?: boolean | EventListenerOptions,
): void;
(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | EventListenerOptions,
): void;
};
dispatchEvent: {
(event: Event): boolean;
(event: Event): boolean;
};
} | null;
addEventListener: {
<K extends keyof TextTrackCueEventMap>(
type: K,
listener: (this: TextTrackCue, ev: TextTrackCueEventMap[K]) => any,
options?: boolean | AddEventListenerOptions,
): void;
(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | AddEventListenerOptions,
): void;
};
removeEventListener: {
<K extends keyof TextTrackCueEventMap>(
type: K,
listener: (this: TextTrackCue, ev: TextTrackCueEventMap[K]) => any,
options?: boolean | EventListenerOptions,
): void;
(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | EventListenerOptions,
): void;
};
dispatchEvent: {
(event: Event): boolean;
(event: Event): boolean;
};
};
readonly length: number;
getCueById: (id: string) => TextTrackCue | null;
[Symbol.iterator]: () => ArrayIterator<TextTrackCue>;
} | null;
}[],
| UseMediaTextTrack[]
| {
id: number;
label: string;
language: string;
mode: TextTrackMode;
kind: TextTrackKind;
inBandMetadataTrackDispatchType: string;
cues: {
[x: number]: {
endTime: number;
id: string;
onenter: ((this: TextTrackCue, ev: Event) => any) | null;
onexit: ((this: TextTrackCue, ev: Event) => any) | null;
pauseOnExit: boolean;
startTime: number;
readonly track: {
readonly activeCues: /*elided*/ any | null;
readonly cues: /*elided*/ any | null;
readonly id: string;
readonly inBandMetadataTrackDispatchType: string;
readonly kind: TextTrackKind;
readonly label: string;
readonly language: string;
mode: TextTrackMode;
oncuechange: ((this: TextTrack, ev: Event) => any) | null;
addCue: (cue: TextTrackCue) => void;
removeCue: (cue: TextTrackCue) => void;
addEventListener: {
<K extends keyof TextTrackEventMap>(
type: K,
listener: (this: TextTrack, ev: TextTrackEventMap[K]) => any,
options?: boolean | AddEventListenerOptions,
): void;
(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | AddEventListenerOptions,
): void;
};
removeEventListener: {
<K extends keyof TextTrackEventMap>(
type: K,
listener: (this: TextTrack, ev: TextTrackEventMap[K]) => any,
options?: boolean | EventListenerOptions,
): void;
(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | EventListenerOptions,
): void;
};
dispatchEvent: {
(event: Event): boolean;
(event: Event): boolean;
};
} | null;
addEventListener: {
<K extends keyof TextTrackCueEventMap>(
type: K,
listener: (this: TextTrackCue, ev: TextTrackCueEventMap[K]) => any,
options?: boolean | AddEventListenerOptions,
): void;
(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | AddEventListenerOptions,
): void;
};
removeEventListener: {
<K extends keyof TextTrackCueEventMap>(
type: K,
listener: (this: TextTrackCue, ev: TextTrackCueEventMap[K]) => any,
options?: boolean | EventListenerOptions,
): void;
(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | EventListenerOptions,
): void;
};
dispatchEvent: {
(event: Event): boolean;
(event: Event): boolean;
};
};
readonly length: number;
getCueById: (id: string) => TextTrackCue | null;
[Symbol.iterator]: () => ArrayIterator<TextTrackCue>;
} | null;
activeCues: {
[x: number]: {
endTime: number;
id: string;
onenter: ((this: TextTrackCue, ev: Event) => any) | null;
onexit: ((this: TextTrackCue, ev: Event) => any) | null;
pauseOnExit: boolean;
startTime: number;
readonly track: {
readonly activeCues: /*elided*/ any | null;
readonly cues: /*elided*/ any | null;
readonly id: string;
readonly inBandMetadataTrackDispatchType: string;
readonly kind: TextTrackKind;
readonly label: string;
readonly language: string;
mode: TextTrackMode;
oncuechange: ((this: TextTrack, ev: Event) => any) | null;
addCue: (cue: TextTrackCue) => void;
removeCue: (cue: TextTrackCue) => void;
addEventListener: {
<K extends keyof TextTrackEventMap>(
type: K,
listener: (this: TextTrack, ev: TextTrackEventMap[K]) => any,
options?: boolean | AddEventListenerOptions,
): void;
(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | AddEventListenerOptions,
): void;
};
removeEventListener: {
<K extends keyof TextTrackEventMap>(
type: K,
listener: (this: TextTrack, ev: TextTrackEventMap[K]) => any,
options?: boolean | EventListenerOptions,
): void;
(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | EventListenerOptions,
): void;
};
dispatchEvent: {
(event: Event): boolean;
(event: Event): boolean;
};
} | null;
addEventListener: {
<K extends keyof TextTrackCueEventMap>(
type: K,
listener: (this: TextTrackCue, ev: TextTrackCueEventMap[K]) => any,
options?: boolean | AddEventListenerOptions,
): void;
(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | AddEventListenerOptions,
): void;
};
removeEventListener: {
<K extends keyof TextTrackCueEventMap>(
type: K,
listener: (this: TextTrackCue, ev: TextTrackCueEventMap[K]) => any,
options?: boolean | EventListenerOptions,
): void;
(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | EventListenerOptions,
): void;
};
dispatchEvent: {
(event: Event): boolean;
(event: Event): boolean;
};
};
readonly length: number;
getCueById: (id: string) => TextTrackCue | null;
[Symbol.iterator]: () => ArrayIterator<TextTrackCue>;
} | null;
}[]
>;
selectedTrack: ShallowRef<number, number>;
enableTrack: (track: number | UseMediaTextTrack, disableTracks?: boolean) => void;
disableTrack: (track?: number | UseMediaTextTrack) => void;
supportsPictureInPicture: boolean | undefined;
togglePictureInPicture: () => Promise<unknown>;
isPictureInPicture: ShallowRef<boolean, boolean>;
onSourceError: EventHookOn<Event>;
onPlaybackError: EventHookOn<Event>;
};
export type UseMediaControlsReturn = ReturnType<typeof useMediaControls>;
```