mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-20 16:57:25 +03:00
71af24f82b
More info in https://chromium-review.googlesource.com/c/chromium/src/+/4577759 and https://issues.chromium.org/issues/40261162 According to the source code and empirical testing, SMOOTH is supported with clear content and Widevine, but not with PlayReady.
350 lines
12 KiB
JavaScript
350 lines
12 KiB
JavaScript
/*! @license
|
|
* Shaka Player
|
|
* Copyright 2016 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
describe('Codec Switching', () => {
|
|
const Util = shaka.test.Util;
|
|
|
|
/** @type {!HTMLVideoElement} */
|
|
let video;
|
|
/** @type {shaka.Player} */
|
|
let player;
|
|
/** @type {!shaka.util.EventManager} */
|
|
let eventManager;
|
|
|
|
let compiledShaka;
|
|
|
|
/** @type {!shaka.test.Waiter} */
|
|
let waiter;
|
|
|
|
beforeAll(async () => {
|
|
video = shaka.test.UiUtils.createVideoElement();
|
|
document.body.appendChild(video);
|
|
compiledShaka =
|
|
await shaka.test.Loader.loadShaka(getClientArg('uncompiled'));
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
await shaka.test.TestScheme.createManifests(compiledShaka, '_compiled');
|
|
player = new compiledShaka.Player();
|
|
await player.attach(video);
|
|
|
|
// Disable allow MediaSource recoveries, which can interfere with playback
|
|
// tests.
|
|
player.configure('streaming.allowMediaSourceRecoveries', false);
|
|
|
|
// Disable stall detection, which can interfere with playback tests.
|
|
player.configure('streaming.stallEnabled', false);
|
|
|
|
eventManager = new shaka.util.EventManager();
|
|
waiter = new shaka.test.Waiter(eventManager);
|
|
waiter.setPlayer(player);
|
|
|
|
const onErrorSpy = jasmine.createSpy('onError');
|
|
onErrorSpy.and.callFake((event) => fail(event.detail));
|
|
eventManager.listen(player, 'error', Util.spyFunc(onErrorSpy));
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await player.unload();
|
|
eventManager.release();
|
|
await player.destroy();
|
|
});
|
|
|
|
afterAll(() => {
|
|
document.body.removeChild(video);
|
|
});
|
|
|
|
describe('for audio and only-audio content aac -> opus', () => {
|
|
it('can switch codecs RELOAD', async () => {
|
|
if (!await Util.isTypeSupported('audio/webm; codecs="opus"')) {
|
|
pending('Codec OPUS in WEBM is not supported by the platform.');
|
|
}
|
|
|
|
// English is AAC MP4.
|
|
const preferredAudioLanguage = 'en';
|
|
player.configure({preferredAudioLanguage: preferredAudioLanguage});
|
|
player.configure('manifest.disableVideo', true);
|
|
player.configure('mediaSource.codecSwitchingStrategy',
|
|
shaka.config.CodecSwitchingStrategy.RELOAD);
|
|
|
|
await player.load('/base/test/test/assets/dash-multi-codec/dash.mpd', 9);
|
|
await video.play();
|
|
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
|
|
expect(player.isLive()).toBe(false);
|
|
|
|
let audioTracks = player.getAudioTracks();
|
|
|
|
expect(audioTracks.length).toBe(2);
|
|
expect(audioTracks.find((t) => !!t.active).language).toBe('en');
|
|
|
|
// Spanish is Opus WebM.
|
|
const newAudioTrack = audioTracks.find((t) => t.language == 'es');
|
|
goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
|
|
player.selectAudioTrack(newAudioTrack);
|
|
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 10, 45);
|
|
|
|
audioTracks = player.getAudioTracks();
|
|
|
|
expect(audioTracks.find((t) => !!t.active).language).toBe('es');
|
|
});
|
|
|
|
it('can switch codecs SMOOTH', async () => {
|
|
if (!deviceDetected.supportsSmoothCodecSwitching('')) {
|
|
pending('SourceBuffer.changeType is not supported');
|
|
}
|
|
if (!await Util.isTypeSupported('audio/webm; codecs="opus"')) {
|
|
pending('Codec OPUS in WEBM is not supported by the platform.');
|
|
}
|
|
|
|
// English is AAC MP4.
|
|
const preferredAudioLanguage = 'en';
|
|
player.configure({preferredAudioLanguage: preferredAudioLanguage});
|
|
player.configure('manifest.disableVideo', true);
|
|
player.configure('mediaSource.codecSwitchingStrategy',
|
|
shaka.config.CodecSwitchingStrategy.SMOOTH);
|
|
|
|
await player.load('/base/test/test/assets/dash-multi-codec/dash.mpd', 9);
|
|
await video.play();
|
|
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
|
|
expect(player.isLive()).toBe(false);
|
|
|
|
let audioTracks = player.getAudioTracks();
|
|
|
|
expect(audioTracks.length).toBe(2);
|
|
expect(audioTracks.find((t) => !!t.active).language).toBe('en');
|
|
|
|
// Spanish is Opus WebM.
|
|
const newAudioTrack = audioTracks.find((t) => t.language == 'es');
|
|
goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
|
|
player.selectAudioTrack(newAudioTrack);
|
|
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 10, 45);
|
|
|
|
audioTracks = player.getAudioTracks();
|
|
|
|
expect(audioTracks.find((t) => !!t.active).language).toBe('es');
|
|
});
|
|
});
|
|
|
|
describe('for audio opus -> aac', () => {
|
|
it('can switch codecs RELOAD', async () => {
|
|
if (!await Util.isTypeSupported('audio/webm; codecs="opus"')) {
|
|
pending('Codec OPUS in WEBM is not supported by the platform.');
|
|
}
|
|
|
|
// English is AAC MP4.
|
|
const preferredAudioLanguage = 'en';
|
|
player.configure({preferredAudioLanguage: preferredAudioLanguage});
|
|
player.configure('mediaSource.codecSwitchingStrategy',
|
|
shaka.config.CodecSwitchingStrategy.RELOAD);
|
|
|
|
await player.load('/base/test/test/assets/dash-multi-codec/dash.mpd', 9);
|
|
await video.play();
|
|
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
|
|
expect(player.isLive()).toBe(false);
|
|
|
|
let audioTracks = player.getAudioTracks();
|
|
|
|
expect(audioTracks.length).toBe(2);
|
|
expect(audioTracks.find((t) => !!t.active).language).toBe('en');
|
|
|
|
// Spanish is Opus WebM.
|
|
const newAudioTrack = audioTracks.find((t) => t.language == 'es');
|
|
goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
|
|
player.selectAudioTrack(newAudioTrack);
|
|
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 10, 45);
|
|
|
|
audioTracks = player.getAudioTracks();
|
|
|
|
expect(audioTracks.find((t) => !!t.active).language).toBe('es');
|
|
});
|
|
|
|
it('can switch codecs SMOOTH', async () => {
|
|
if (!deviceDetected.supportsSmoothCodecSwitching('')) {
|
|
pending('SourceBuffer.changeType is not supported');
|
|
}
|
|
if (!await Util.isTypeSupported('audio/webm; codecs="opus"')) {
|
|
pending('Codec OPUS in WEBM is not supported by the platform.');
|
|
}
|
|
|
|
// English is AAC MP4.
|
|
const preferredAudioLanguage = 'en';
|
|
player.configure({preferredAudioLanguage: preferredAudioLanguage});
|
|
player.configure('mediaSource.codecSwitchingStrategy',
|
|
shaka.config.CodecSwitchingStrategy.SMOOTH);
|
|
|
|
await player.load('/base/test/test/assets/dash-multi-codec/dash.mpd', 9);
|
|
await video.play();
|
|
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
|
|
expect(player.isLive()).toBe(false);
|
|
|
|
let audioTracks = player.getAudioTracks();
|
|
|
|
expect(audioTracks.length).toBe(2);
|
|
expect(audioTracks.find((t) => !!t.active).language).toBe('en');
|
|
|
|
// Spanish is Opus WebM.
|
|
const newAudioTrack = audioTracks.find((t) => t.language == 'es');
|
|
goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
|
|
player.selectAudioTrack(newAudioTrack);
|
|
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 10, 45);
|
|
|
|
audioTracks = player.getAudioTracks();
|
|
|
|
expect(audioTracks.find((t) => !!t.active).language).toBe('es');
|
|
});
|
|
});
|
|
|
|
describe('for audio aac -> ec3', () => {
|
|
it('can switch codecs RELOAD', async () => {
|
|
if (!await Util.isTypeSupported('audio/mp4; codecs="ec-3"')) {
|
|
pending('Codec EC3 in MP4 is not supported by the platform.');
|
|
}
|
|
|
|
// English is AAC MP4.
|
|
const preferredAudioLanguage = 'en';
|
|
player.configure({preferredAudioLanguage: preferredAudioLanguage});
|
|
player.configure('mediaSource.codecSwitchingStrategy',
|
|
shaka.config.CodecSwitchingStrategy.RELOAD);
|
|
|
|
await player.load(
|
|
'/base/test/test/assets/dash-multi-codec-ec3/dash.mpd', 1);
|
|
await video.play();
|
|
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
|
|
expect(player.isLive()).toBe(false);
|
|
|
|
let audioTracks = player.getAudioTracks();
|
|
|
|
expect(audioTracks.length).toBe(2);
|
|
expect(audioTracks.find((t) => !!t.active).language).toBe('en');
|
|
|
|
// Spanish is EC3.
|
|
const newAudioTrack = audioTracks.find((t) => t.language == 'es');
|
|
goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
|
|
player.selectAudioTrack(newAudioTrack);
|
|
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 2, 45);
|
|
|
|
audioTracks = player.getAudioTracks();
|
|
|
|
expect(audioTracks.find((t) => !!t.active).language).toBe('es');
|
|
});
|
|
|
|
it('can switch codecs SMOOTH', async () => {
|
|
if (!deviceDetected.supportsSmoothCodecSwitching('')) {
|
|
pending('SourceBuffer.changeType is not supported');
|
|
}
|
|
if (!await Util.isTypeSupported('audio/mp4; codecs="ec-3"')) {
|
|
pending('Codec EC3 in MP4 is not supported by the platform.');
|
|
}
|
|
|
|
// English is AAC MP4.
|
|
const preferredAudioLanguage = 'en';
|
|
player.configure({preferredAudioLanguage: preferredAudioLanguage});
|
|
player.configure('mediaSource.codecSwitchingStrategy',
|
|
shaka.config.CodecSwitchingStrategy.SMOOTH);
|
|
|
|
await player.load(
|
|
'/base/test/test/assets/dash-multi-codec-ec3/dash.mpd', 1);
|
|
await video.play();
|
|
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
|
|
expect(player.isLive()).toBe(false);
|
|
|
|
let audioTracks = player.getAudioTracks();
|
|
|
|
expect(audioTracks.length).toBe(2);
|
|
expect(audioTracks.find((t) => !!t.active).language).toBe('en');
|
|
|
|
// Spanish is EC3.
|
|
const newAudioTrack = audioTracks.find((t) => t.language == 'es');
|
|
goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
|
|
player.selectAudioTrack(newAudioTrack);
|
|
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 2, 45);
|
|
|
|
audioTracks = player.getAudioTracks();
|
|
|
|
expect(audioTracks.find((t) => !!t.active).language).toBe('es');
|
|
});
|
|
});
|
|
|
|
describe('for audio ec3 -> aac', () => {
|
|
it('can switch codecs RELOAD', async () => {
|
|
if (!await Util.isTypeSupported('audio/mp4; codecs="ec-3"')) {
|
|
pending('Codec EC3 in MP4 is not supported by the platform.');
|
|
}
|
|
|
|
// Spanish is EC3.
|
|
const preferredAudioLanguage = 'es';
|
|
player.configure({preferredAudioLanguage: preferredAudioLanguage});
|
|
player.configure('mediaSource.codecSwitchingStrategy',
|
|
shaka.config.CodecSwitchingStrategy.RELOAD);
|
|
|
|
await player.load(
|
|
'/base/test/test/assets/dash-multi-codec-ec3/dash.mpd', 1);
|
|
await video.play();
|
|
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
|
|
expect(player.isLive()).toBe(false);
|
|
|
|
let audioTracks = player.getAudioTracks();
|
|
|
|
expect(audioTracks.length).toBe(2);
|
|
expect(audioTracks.find((t) => !!t.active).language).toBe('es');
|
|
|
|
// English is AAC MP4.
|
|
const newAudioTrack = audioTracks.find((t) => t.language == 'en');
|
|
goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
|
|
player.selectAudioTrack(newAudioTrack);
|
|
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 2, 45);
|
|
|
|
audioTracks = player.getAudioTracks();
|
|
|
|
expect(audioTracks.find((t) => !!t.active).language).toBe('en');
|
|
});
|
|
|
|
it('can switch codecs SMOOTH', async () => {
|
|
if (!deviceDetected.supportsSmoothCodecSwitching('')) {
|
|
pending('SourceBuffer.changeType is not supported');
|
|
}
|
|
if (!await Util.isTypeSupported('audio/mp4; codecs="ec-3"')) {
|
|
pending('Codec EC3 in MP4 is not supported by the platform.');
|
|
}
|
|
|
|
// Spanish is EC3.
|
|
const preferredAudioLanguage = 'es';
|
|
player.configure({preferredAudioLanguage: preferredAudioLanguage});
|
|
player.configure('mediaSource.codecSwitchingStrategy',
|
|
shaka.config.CodecSwitchingStrategy.SMOOTH);
|
|
|
|
await player.load(
|
|
'/base/test/test/assets/dash-multi-codec-ec3/dash.mpd', 1);
|
|
await video.play();
|
|
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
|
|
expect(player.isLive()).toBe(false);
|
|
|
|
let audioTracks = player.getAudioTracks();
|
|
|
|
expect(audioTracks.length).toBe(2);
|
|
expect(audioTracks.find((t) => !!t.active).language).toBe('es');
|
|
|
|
// English is AAC MP4.
|
|
const newAudioTrack = audioTracks.find((t) => t.language == 'en');
|
|
goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
|
|
player.selectAudioTrack(newAudioTrack);
|
|
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 2, 45);
|
|
|
|
audioTracks = player.getAudioTracks();
|
|
|
|
expect(audioTracks.find((t) => !!t.active).language).toBe('en');
|
|
});
|
|
});
|
|
});
|