Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add audio tracks API #742

Merged
merged 3 commits into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/vanilla-ts-esm/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ <h1><a href="/">Elements</a></h1>
<li><a href="./mux-player-audio.html" class="player">&lt;mux-player audio&gt;</a></li>
<li><a href="./mux-player-cuepoints.html" class="player">&lt;mux-player&gt; (cuePoints)</a></li>
<li><a href="./mux-player-renditions.html" class="player">&lt;mux-player&gt; (renditions)</a></li>
<li><a href="./mux-player-audio-tracks.html" class="player">&lt;mux-player&gt; (audio tracks)</a></li>
<li><a href="./mux-player-theme.html" class="player">&lt;mux-player&gt; (microvideo theme)</a></li>
<li><a href="./mux-player-theme-2023.html" class="player">&lt;mux-player&gt; (2023 theme)</a></li>
<li><a href="./mux-uploader-simple.html" class="uploader">&lt;mux-uploader&gt;</a></li>
Expand Down
83 changes: 83 additions & 0 deletions examples/vanilla-ts-esm/public/mux-player-audio-tracks.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>&lt;mux-player&gt; audio tracks example</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">
<link rel="stylesheet" href="./styles.css">
<script
defer
src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"
></script>
<script type="module" src="./dist/mux-player.js"></script>
<style>
mux-player {
display: block;
width: 100%;
margin: 1rem 0 2rem;
background-color: #000;
line-height: 0;
}

mux-player:not([audio]) {
aspect-ratio: 16 / 9;
}
</style>
</head>
<body>
<header>
<div class="left-header">
<a class="mux-logo" href="https://www.mux.com/player" target="_blank">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/360826/233653989-11cd8603-c20f-4008-8bf7-dc15b743c52b.svg">
<source media="(prefers-color-scheme: light)" srcset="https://user-images.githubusercontent.com/360826/233653583-50dda726-cbe7-4182-a113-059a91ae83e6.svg">
<img alt="Mux Logo" src="https://user-images.githubusercontent.com/360826/233653583-50dda726-cbe7-4182-a113-059a91ae83e6.svg">
</picture>
</a>
<h1><a href="/">Elements</a></h1>
</div>
<div class="right-header">
<a class="github-logo" href="https://github.com/muxinc/elements" target="_blank">
<img width="32" height="32" src="./images/github-logo.svg" alt="Github logo">
</a>
</div>
</header>

<mux-player
id="muxPlayer"
stream-type="on-demand"
src="https://playertest.longtailvideo.com/adaptive/elephants_dream_v4/index.m3u8"
></mux-player>

<br>

<select id="audioselect"></select>

<br>
<br>

<script type="module">

muxPlayer.audioTracks.addEventListener('removetrack', ({ track }) => {
audioselect.querySelector(`[value="${track.id}"]`).remove();
});

muxPlayer.audioTracks.addEventListener('addtrack', ({ track }) => {
audioselect.append(new Option(
track.label,
track.id,
track.enabled,
track.enabled
));
});

audioselect.addEventListener('change', () => {
for (let track of muxPlayer.audioTracks) {
track.enabled = audioselect.value == track.id;
}
});
</script>

<a href="../">Browse Elements</a>
</body>
</html>
12 changes: 6 additions & 6 deletions packages/playback-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ import type { HlsInterface } from './hls';
import { MediaError } from './errors';
import { setupAutoplay } from './autoplay';
import { setupPreload } from './preload';
import { setupRenditions } from './renditions';
import { setupMediaTracks } from './media-tracks';
import {
setupTracks,
setupTextTracks,
addTextTrack,
removeTextTrack,
addCuePoints,
getCuePoints,
getActiveCuePoint,
setupCuePoints,
getCuePointsTrack,
} from './tracks';
} from './text-tracks';
import { getStartDate, getCurrentPdt } from './pdt';
import {
inSeekableRange,
Expand All @@ -35,7 +35,6 @@ import {
type PlaybackCore,
type MuxMediaProps,
type MuxMediaPropsInternal,
type MediaTracks,
HlsPlaylistTypes,
MediaTypes,
} from './types';
Expand Down Expand Up @@ -534,6 +533,7 @@ export const loadMedia = (
| 'subtitleTracks'
| 'subtitleTrack'
| 'userConfig'
| 'audioTrack'
| 'autoLevelEnabled'
| 'nextLevel'
| 'levels'
Expand Down Expand Up @@ -636,8 +636,8 @@ export const loadMedia = (
});
mediaEl.addEventListener('error', handleInternalError);

setupRenditions(props as HTMLMediaElement, hls);
setupTracks(mediaEl, hls);
setupMediaTracks(props as HTMLMediaElement, hls);
setupTextTracks(mediaEl, hls);

hls.attachMedia(mediaEl);
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import Hls from './hls';
import type { VideoRenditionList } from 'media-tracks';

export function setupRenditions(
export function setupMediaTracks(
customMediaEl: HTMLMediaElement,
hls: Pick<Hls, 'autoLevelEnabled' | 'nextLevel' | 'levels' | 'on' | 'once'>
hls: Pick<Hls, 'audioTrack' | 'autoLevelEnabled' | 'nextLevel' | 'levels' | 'on' | 'once'>
) {
if (!('videoTracks' in customMediaEl)) return;

Expand All @@ -13,7 +13,7 @@
const levelIdMap = new WeakMap();

hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) {
removeAllVideoTracks();
removeAllMediaTracks();

Check warning on line 16 in packages/playback-core/src/media-tracks.ts

View check run for this annotation

Codecov / codecov/patch

packages/playback-core/src/media-tracks.ts#L16

Added line #L16 was not covered by tests

const videoTrack = customMediaEl.addVideoTrack('main');
videoTrack.selected = true;
Expand All @@ -31,6 +31,21 @@
levelIdMap.set(level, `${id}`);
videoRendition.id = `${id}`;
}

for (const [id, a] of data.audioTracks.entries()) {
// hls.js doesn't return a `kind` property for audio tracks yet.
const kind = a.default ? 'main' : 'alternative';
const audioTrack = customMediaEl.addAudioTrack(kind, a.name, a.lang);
audioTrack.id = `${id}`;

if (a.default) {
audioTrack.enabled = true;
}
}
});

customMediaEl.audioTracks.addEventListener('change', () => {
hls.audioTrack = [...customMediaEl.audioTracks].find((t) => t.enabled).id;

Check warning on line 48 in packages/playback-core/src/media-tracks.ts

View check run for this annotation

Codecov / codecov/patch

packages/playback-core/src/media-tracks.ts#L34-L48

Added lines #L34 - L48 were not covered by tests
});

// Fired when a level is removed after calling `removeLevel()`
Expand Down Expand Up @@ -61,14 +76,15 @@

customMediaEl.videoRenditions.addEventListener('change', switchRendition);

const removeAllVideoTracks = () => {
const removeAllMediaTracks = () => {

Check warning on line 79 in packages/playback-core/src/media-tracks.ts

View check run for this annotation

Codecov / codecov/patch

packages/playback-core/src/media-tracks.ts#L79

Added line #L79 was not covered by tests
for (const videoTrack of customMediaEl.videoTracks) {
customMediaEl.removeVideoTrack(videoTrack);
}
for (const audioTrack of customMediaEl.audioTracks) {
customMediaEl.removeAudioTrack(audioTrack);
}

Check warning on line 85 in packages/playback-core/src/media-tracks.ts

View check run for this annotation

Codecov / codecov/patch

packages/playback-core/src/media-tracks.ts#L83-L85

Added lines #L83 - L85 were not covered by tests
};

// NOTE: Since this is only relevant for hls, using destroying event (CJP).
hls.once(Hls.Events.DESTROYING, () => {
removeAllVideoTracks();
});
hls.once(Hls.Events.DESTROYING, removeAllMediaTracks);

Check warning on line 89 in packages/playback-core/src/media-tracks.ts

View check run for this annotation

Codecov / codecov/patch

packages/playback-core/src/media-tracks.ts#L89

Added line #L89 was not covered by tests
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Hls from './hls';
import { CuePoint } from './types';
import { addEventListenerWithTeardown } from './util';

export function setupTracks(
export function setupTextTracks(
mediaEl: HTMLMediaElement,
hls: Pick<Hls, 'on' | 'once' | 'subtitleTracks' | 'subtitleTrack'>
) {
Expand Down
2 changes: 1 addition & 1 deletion packages/playback-core/test/tracks.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { assert, nextFrame, oneEvent, aTimeout, waitUntil } from '@open-wc/testing';
import { addCuePoints, getCuePoints, getActiveCuePoint } from '../src/tracks.ts';
import { addCuePoints, getCuePoints, getActiveCuePoint } from '../src/text-tracks.ts';

describe('textTracks', () => {
describe('cuePoints', () => {
Expand Down
Loading