Files
hls.js/tests/unit/controller/timeline-controller.js
Rob WalchandGitHub 21213d55c9 Fix subtitle track selection when reusing media element with mismatched TextTracks (#5880)
* Use subtitle track name and language to find and match subtitle/captions TextTrack rather than subtitleTrack index
Resolves #4571

* Fix regression in dev where AUDIO_TRACKS_UPDATED is re-dispatched with zero tracks
Allow selection of audioTrack on AUDIO_TRACKS_UPDATED (overriding default selection - Resolves #5831)
Cleanup selection of subtitleTrack on SUBTITLE_TRACKS_UPDATED (overriding default selection)

* Fix TextTrack use with ASSOC-LANGUAGE
Match the initial default/forced/autoselect choice made when playing HLS in Safari
2023-10-10 11:27:55 -07:00

182 lines
7.1 KiB
JavaScript

import { TimelineController } from '../../../src/controller/timeline-controller';
import Hls from '../../../src/hls';
import { Events } from '../../../src/events';
describe('TimelineController', function () {
let timelineController;
let hls;
beforeEach(function () {
hls = new Hls();
hls.config.enableWebVTT = true;
hls.config.renderNatively = true;
timelineController = new TimelineController(hls);
timelineController.media = document.createElement('video');
});
describe('reuse text track', function () {
it('should reuse text track when track order is same between manifests', function () {
hls.subtitleTrackController = { subtitleDisplay: false };
timelineController.onSubtitleTracksUpdated(
Events.SUBTITLE_TRACKS_UPDATED,
{
subtitleTracks: [
{ id: 0, name: 'en', attrs: { LANGUAGE: 'en', NAME: 'en' } },
{ id: 1, name: 'ru', attrs: { LANGUAGE: 'ru', NAME: 'ru' } },
],
},
);
// text tracks model contain only newly added manifest tracks, in same order as in manifest
expect(timelineController.textTracks[0].label).to.equal('en');
expect(timelineController.textTracks[1].label).to.equal('ru');
expect(timelineController.textTracks.length).to.equal(2);
// text tracks of the media contain the newly added text tracks
expect(timelineController.media.textTracks[0].label).to.equal('en');
expect(timelineController.media.textTracks[1].label).to.equal('ru');
expect(timelineController.media.textTracks.length).to.equal(2);
timelineController.onSubtitleTracksUpdated(
Events.SUBTITLE_TRACKS_UPDATED,
{
subtitleTracks: [
{ id: 0, name: 'en', attrs: { LANGUAGE: 'en', NAME: 'en' } },
{ id: 1, name: 'ru', attrs: { LANGUAGE: 'ru', NAME: 'ru' } },
],
},
);
// text tracks model contain only newly added manifest tracks, in same order
expect(timelineController.textTracks[0].label).to.equal('en');
expect(timelineController.textTracks[1].label).to.equal('ru');
expect(timelineController.textTracks.length).to.equal(2);
// text tracks of the media contain the previously added text tracks, in same order as the manifest order
expect(timelineController.media.textTracks[0].label).to.equal('en');
expect(timelineController.media.textTracks[1].label).to.equal('ru');
expect(timelineController.media.textTracks.length).to.equal(2);
});
it('should reuse text track when track order is not same between manifests', function () {
hls.subtitleTrackController = { subtitleDisplay: false };
timelineController.onSubtitleTracksUpdated(Events.MANIFEST_LOADED, {
subtitleTracks: [
{
id: 0,
name: 'en',
lang: 'en',
attrs: { LANGUAGE: 'en', NAME: 'en' },
},
{
id: 1,
name: 'ru',
lang: 'ru',
attrs: { LANGUAGE: 'ru', NAME: 'ru' },
},
],
});
// text tracks model contain only newly added manifest tracks, in same order as in manifest
expect(timelineController.textTracks[0].label).to.equal('en');
expect(timelineController.textTracks[1].label).to.equal('ru');
expect(timelineController.textTracks.length).to.equal(2);
// text tracks of the media contain the newly added text tracks
expect(timelineController.media.textTracks[0].label).to.equal('en');
expect(timelineController.media.textTracks[1].label).to.equal('ru');
expect(timelineController.media.textTracks.length).to.equal(2);
timelineController.onSubtitleTracksUpdated(Events.MANIFEST_LOADED, {
subtitleTracks: [
{
id: 0,
name: 'ru',
lang: 'ru',
attrs: { LANGUAGE: 'ru', NAME: 'ru' },
},
{
id: 1,
name: 'en',
lang: 'en',
attrs: { LANGUAGE: 'en', NAME: 'en' },
},
],
});
// text tracks model contain only newly added manifest tracks, in same order
expect(timelineController.textTracks[0].label).to.equal('ru');
expect(timelineController.textTracks[1].label).to.equal('en');
expect(timelineController.textTracks.length).to.equal(2);
// text tracks of the media contain the previously added text tracks).to.equal(in opposite order to the manifest order
expect(timelineController.media.textTracks[0].label).to.equal('en');
expect(timelineController.media.textTracks[1].label).to.equal('ru');
expect(timelineController.media.textTracks.length).to.equal(2);
});
});
describe('text track kind', function () {
it('should be kind captions when there is both transcribes-spoken-dialog and describes-music-and-sound', function () {
hls.subtitleTrackController = { subtitleDisplay: false };
const characteristics =
'public.accessibility.transcribes-spoken-dialog,public.accessibility.describes-music-and-sound';
timelineController.onSubtitleTracksUpdated(Events.MANIFEST_LOADED, {
subtitleTracks: [
{
id: 0,
name: 'en',
characteristics,
attrs: {
CHARACTERISTICS: characteristics,
},
},
],
});
// text tracks model contain only newly added manifest tracks, in same order as in manifest
expect(timelineController.textTracks[0].kind).to.equal('captions');
// text tracks of the media contain the newly added text tracks
expect(timelineController.media.textTracks[0].kind).to.equal('captions');
});
it('should be kind subtitles when there is no describes-music-and-sound', function () {
hls.subtitleTrackController = { subtitleDisplay: false };
timelineController.onSubtitleTracksUpdated(Events.MANIFEST_LOADED, {
subtitleTracks: [
{
id: 0,
name: 'en',
attrs: {
CHARACTERISTICS: 'public.accessibility.transcribes-spoken-dialog',
},
},
],
});
// text tracks model contain only newly added manifest tracks, in same order as in manifest
expect(timelineController.textTracks[0].kind).to.equal('subtitles');
// text tracks of the media contain the newly added text tracks
expect(timelineController.media.textTracks[0].kind).to.equal('subtitles');
});
it('should be kind subtitles when there is no CHARACTERISTICS', function () {
hls.subtitleTrackController = { subtitleDisplay: false };
timelineController.onSubtitleTracksUpdated(Events.MANIFEST_LOADED, {
subtitleTracks: [
{
id: 0,
name: 'en',
attrs: {},
},
],
});
// text tracks model contain only newly added manifest tracks, in same order as in manifest
expect(timelineController.textTracks[0].kind).to.equal('subtitles');
// text tracks of the media contain the newly added text tracks
expect(timelineController.media.textTracks[0].kind).to.equal('subtitles');
});
});
});