<bmx-media-player>
A video and audio player for training, help centres, product tours, town halls, podcasts and recorded meetings, built on the browser's own media element so it plays whatever the browser plays (MP4, WebM, MP3, AAC, Ogg, and HLS where the browser supports it).
25 properties · 11 events · 20 methods · 7 parts
Example
A 74-second induction with English captions, French subtitles, chapters, scrub thumbnails and text descriptions. Press ? in the player for its keyboard shortcuts.
Show markup
<bmx-media-player
id="ex-player"
label="Site safety induction"
src="assets/media/induction.mp4"
poster="assets/media/induction-poster.jpg"
transcript="auto"
style="--bmx-media-player-panel-height: 16rem"
></bmx-media-player>
<p class="note" id="ex-player-out" role="status">A 74-second induction with English captions, French subtitles, chapters, scrub thumbnails and text descriptions. Press ? in the player for its keyboard shortcuts.</p>
<div class="row" style="gap: 0.75rem; flex-wrap: wrap; align-items: center; margin-block: 0.5rem 1.5rem">
<label><input type="checkbox" id="ex-player-audio" /> Show it as an audio player</label>
<button type="button" id="ex-player-find">Find "forklift" in the transcript</button>
<button type="button" id="ex-player-loop">Repeat "On the floor"</button>
</div>
<script type="module">
await customElements.whenDefined('bmx-media-player');
const player = document.getElementById('ex-player');
const out = document.getElementById('ex-player-out');
player.tracks = [
{ kind: 'captions', src: 'assets/media/induction.en.vtt', srclang: 'en', label: 'English', default: true },
{ kind: 'subtitles', src: 'assets/media/induction.fr.vtt', srclang: 'fr', label: 'Français' },
{ kind: 'chapters', src: 'assets/media/induction.chapters.vtt', srclang: 'en' },
{ kind: 'thumbnails', src: 'assets/media/induction.thumbnails.vtt' },
{ kind: 'descriptions', src: 'assets/media/induction.descriptions.vtt', srclang: 'en' },
];
// Bookmarks belong to the viewer: keep them wherever the application keeps the viewer's things.
player.bookmarks = [{ id: 'b1', time: 23.3, note: 'Protective equipment' }];
player.addEventListener('bmxChapterChange', e => e.detail.chapter && (out.textContent = `Chapter: ${e.detail.chapter.title}.`));
player.addEventListener('bmxBookmarksChange', e => (out.textContent = `${e.detail.bookmarks.length} bookmark${e.detail.bookmarks.length === 1 ? '' : 's'}: ${e.detail.bookmarks.map(b => b.note || 'no note').join(', ')}.`));
document.getElementById('ex-player-audio').addEventListener('change', e => (player.kind = e.target.checked ? 'audio' : 'video'));
document.getElementById('ex-player-find').addEventListener('click', async () => {
const n = await player.find('forklift');
out.textContent = `${n} match${n === 1 ? '' : 'es'} in the transcript.`;
});
document.getElementById('ex-player-loop').addEventListener('click', async () => {
const chapter = (await player.getChapters()).find(c => c.title === 'On the floor');
if (!chapter) return;
await player.setLoop(chapter.start, chapter.end);
await player.seek(chapter.start);
await player.play();
});
</script>
WHAT IT ADDS TO THE BROWSER'S PLAYER
- Captions and subtitles from WebVTT or SRT files (or cues given directly), drawn by the player so they look the same everywhere, with the reader's choice of size, colour and background, and voice tags shown as speakers.
- A transcript beside or below the player that follows along, can be searched, seeks when a line is chosen, and downloads as text.
- Chapters on the timeline and in a menu, with the chapter name shown as it plays; scrub thumbnails from a thumbnails track (sprite sheets too).
- Speed, quality (several sources), a repeated section (A to B), bookmarks with notes, picture in picture and full screen.
- Text descriptions read out by screen readers as they come up, for viewers who cannot see the picture.
Nothing is sent anywhere: tracks are read from the addresses given, in the
page, and bookmarks are kept on the element (bookmarks, bmxBookmarksChange)
for the page to save if it wants to.
KEYBOARD
Every control is a button or a slider. Inside the player: Space or K plays
and pauses, J and L skip seek-step seconds, the arrows skip 5 seconds and
change the volume, M mutes, C toggles captions, T the transcript, B adds a
bookmark, F goes full screen, Shift+N/P move between chapters, Shift+. and
Shift+, change speed, 0-9 jump to that tenth, [ and ] set a section to repeat
and \ stops it, ? lists the shortcuts.
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
allowBookmarks |
allow-bookmarks |
boolean |
true |
Offer bookmarks: the B key, a button, and a tab beside the transcript. |
autoplay |
autoplay |
boolean |
false |
Start playing as soon as possible. Browsers allow this only for muted media, or after the reader has used the page. |
bookmarks |
bookmarks |
readonly BmxMediaBookmark[] | string |
— | The viewer's bookmarks (an array, or its JSON). Kept up to date; save them from bmxBookmarksChange. |
captionStyle |
caption-style |
BmxCaptionStyle | string |
— | How captions look (an object, or its JSON). |
captionTrack |
caption-track |
string |
— | The captions or subtitles shown, by label or language; off for none. Unset, the default track (or none). |
controls |
controls |
'auto' | 'always' |
'auto' |
Hide the controls of a playing video when the pointer is still: auto, or always show them. |
crossorigin |
crossorigin |
'anonymous' | 'use-credentials' |
— | How media and track files are requested from another site: anonymous or use-credentials. |
describe |
describe |
boolean |
false |
Read description tracks out to screen readers as they come up. |
fileName |
file-name |
string |
'transcript' |
The file name the transcript downloads as, without its extension. |
kind |
kind |
'video' | 'audio' |
'video' |
video shows a picture; audio is a compact bar with the transcript below. |
label |
label |
string |
— | The player's accessible name, and the title of an audio player. |
loop |
loop |
boolean |
false |
Start again at the end. |
muted |
muted |
boolean |
false |
Sound off. |
poster |
poster |
string |
— | A picture shown before a video plays, or beside an audio player. |
preload |
preload |
'none' | 'metadata' | 'auto' |
'metadata' |
How much to load before play is pressed. |
rate |
rate |
number |
1 |
Playback speed. |
rates |
rates |
readonly number[] | string |
— | The speeds offered (an array, or a comma-separated list). |
seekStep |
seek-step |
number |
10 |
Seconds J, L and the skip buttons move. |
sources |
sources |
readonly BmxMediaSource[] | string |
— | Files the media can be played from, best first (an array, or its JSON). Labelled ones are offered as qualities. |
src |
src |
string |
— | The media file. Use sources instead for a choice of quality or format. |
startTime |
start-time |
number |
0 |
Seconds into the media to start from. |
strings |
strings |
Partial<BmxMediaPlayerStrings> | string |
— | Replacements for any of the wording (an object, or its JSON). |
tracks |
tracks |
readonly BmxMediaTrack[] | string |
— | Captions, subtitles, chapters, thumbnails and descriptions (an array, or its JSON). <track> children are read too. |
transcript |
transcript |
BmxTranscriptLayout |
'off' |
The transcript panel: off, auto (beside when there is room, else below), side or below. |
volume |
volume |
number |
1 |
Loudness, 0 to 1. |
Events
| Event | Detail | Description |
|---|---|---|
bmxBookmarksChange |
BmxMediaBookmarksDetail |
Fired when a bookmark is added, its note edited, or removed. |
bmxCaptionStyleChange |
BmxCaptionStyle |
Fired when the reader changes the caption style in the settings, so the page can remember it. |
bmxChapterChange |
BmxMediaChapterDetail |
Fired when playback moves into another chapter. |
bmxCueChange |
BmxMediaCueDetail |
Fired when the captions showing change. |
bmxEnded |
BmxMediaTimeDetail |
Fired at the end of the media. |
bmxMediaError |
BmxMediaErrorDetail |
Fired when the media or a track cannot be loaded or played. |
bmxPause |
BmxMediaTimeDetail |
Fired when playback pauses (including at the end). |
bmxPlay |
BmxMediaTimeDetail |
Fired when playback starts or resumes. |
bmxRateChange |
{ rate: number; } |
Fired when the speed changes. |
bmxTimeUpdate |
BmxMediaTimeDetail |
Fired as playback moves, about four times a second, and after a seek. |
bmxVolumeChange |
BmxMediaVolumeDetail |
Fired when the volume or mute changes. |
Methods
| Method | Signature | Description |
|---|---|---|
addBookmark |
addBookmark(note?: string, time?: number) => Promise<BmxMediaBookmark> |
Adds a bookmark at a time (now, when omitted). Returns it. |
clearLoop |
clearLoop() => Promise<void> |
Stops repeating a section. |
downloadTranscript |
downloadTranscript(format?: BmxCaptionFormat) => Promise<void> |
Saves the transcript as a file. |
enterFullscreen |
enterFullscreen() => Promise<void> |
Full screen, for the player only. |
exitFullscreen |
exitFullscreen() => Promise<void> |
Leaves full screen. |
find |
find(query: string) => Promise<number> |
Searches the transcript, opening it, and returns the number of matches. |
getBookmarks |
getBookmarks() => Promise<BmxMediaBookmark[]> |
The bookmarks, in time order. |
getChapters |
getChapters() => Promise<BmxChapter[]> |
The chapters, from the chapters track. |
getCues |
getCues(kind?: BmxMediaTrackKind) => Promise<BmxCue[]> |
The cues of the captions showing (or of the first captions track), sorted. |
getMedia |
getMedia() => Promise<HTMLMediaElement | null> |
The media element, for anything this element does not offer (media sessions, audio processing). |
getTranscript |
getTranscript(format?: BmxCaptionFormat) => Promise<string> |
The transcript (or captions) as text, in a format: txt, vtt, srt or json. |
pause |
pause() => Promise<void> |
Pauses playback. |
play |
play() => Promise<void> |
Starts or resumes playback. Resolves when it has started (or the browser refused). |
removeBookmark |
removeBookmark(id: string) => Promise<void> |
Removes a bookmark by id. |
seek |
seek(time: number) => Promise<void> |
Moves to a time, in seconds. |
setFocus |
setFocus(options?: FocusOptions) => Promise<void> |
Focuses the play button. |
setLoop |
setLoop(from: number, to: number) => Promise<void> |
Repeats the section between two times until clearLoop. |
skip |
skip(seconds: number) => Promise<void> |
Moves by a number of seconds, back when negative. |
toggle |
toggle() => Promise<void> |
Plays when paused, pauses when playing. |
togglePictureInPicture |
togglePictureInPicture() => Promise<void> |
Picture in picture on or off (video, where the browser offers it). |
Slots
| Slot | Description |
|---|---|
label |
Rich content for the title shown above an audio player, in place of label. |
CSS shadow parts
| Part | Description |
|---|---|
captions |
The captions over the picture. |
controls |
The control bar. |
player |
The player: picture and controls. |
settings |
The settings panel. |
stage |
The picture (video only). |
timeline |
The seek bar. |
transcript |
The transcript and bookmarks panel. |
CSS custom properties
| Property | Description |
|---|---|
--bmx-media-player-accent |
The played part of the timeline, the volume and the current transcript line. |
--bmx-media-player-aspect-ratio |
The picture's shape before the video has loaded. |
--bmx-media-player-background |
Behind the picture (letterboxing). |
--bmx-media-player-caption-font |
The captions' typeface. |
--bmx-media-player-caption-size |
The captions' size at 100%. |
--bmx-media-player-control-color |
Icons and text over the picture. |
--bmx-media-player-panel-height |
The transcript's height below the player. |
--bmx-media-player-panel-width |
The transcript's width beside the player. |
--bmx-media-player-radius |
Corner radius of the player and the panel. |