diff --git a/src/videojs-http-streaming.js b/src/videojs-http-streaming.js index 85fed8ff..d90db611 100644 --- a/src/videojs-http-streaming.js +++ b/src/videojs-http-streaming.js @@ -724,6 +724,9 @@ class VhsHandler extends Component { this.masterPlaylistController_.on('selectedinitialmedia', () => { // Add the manual rendition mix-in to VhsHandler renditionSelectionMixin(this); + }); + + this.masterPlaylistController_.sourceUpdater_.on('ready', () => { setupEmeOptions(this); }); diff --git a/test/playback.test.js b/test/playback.test.js index 38fe6dc7..ffe7d0a4 100644 --- a/test/playback.test.js +++ b/test/playback.test.js @@ -3,6 +3,7 @@ import videojs from 'video.js'; import window from 'global/window'; import document from 'global/document'; import '../src/videojs-http-streaming'; +import 'videojs-contrib-eme'; const playFor = function(player, time, cb) { if (player.paused()) { @@ -63,6 +64,7 @@ QUnit.module('Playback', { } }); + this.player.eme(); this.player.ready(done, true); }, afterEach() { @@ -286,9 +288,50 @@ QUnit[testFn]('DASH sidx with alt audio should end', function(assert) { }); }); -// TODO: why does this make the next test -// throw an "The operation was aborted." on firefox if (!videojs.browser.IS_FIREFOX) { + QUnit[testFn]('DRM Dash', function(assert) { + const done = assert.async(); + const player = this.player; + + player.one('ended', () => { + assert.ok(true, 'triggered ended'); + assert.equal(player.error(), null, 'no errors'); + done(); + }); + + /* eslint-disable max-nested-callbacks */ + playFor(player, 1, () => { + // switch audio playlist + player.audioTracks()[1].enabled = true; + + playFor(player, 1, () => { + player.currentTime(player.duration() - 5); + }); + }); + /* eslint-enable max-nested-callbacks */ + + player.src({ + src: 'https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest.mpd', + type: 'application/dash+xml', + keySystems: { + 'com.microsoft.playready': { + url: 'https://drm-widevine-licensing.axtest.net/AcquireLicense', + licenseHeaders: { + 'X-AxDRM-Message': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2ZXJzaW9uIjoxLCJjb21fa2V5X2lkIjoiYjMzNjRlYjUtNTFmNi00YWUzLThjOTgtMzNjZWQ1ZTMxYzc4IiwibWVzc2FnZSI6eyJ0eXBlIjoiZW50aXRsZW1lbnRfbWVzc2FnZSIsImtleXMiOlt7ImlkIjoiOWViNDA1MGQtZTQ0Yi00ODAyLTkzMmUtMjdkNzUwODNlMjY2IiwiZW5jcnlwdGVkX2tleSI6ImxLM09qSExZVzI0Y3Iya3RSNzRmbnc9PSJ9XX19.4lWwW46k-oWcah8oN18LPj5OLS5ZU-_AQv7fe0JhNjA' + } + }, + 'com.widevine.alpha': { + url: 'https://drm-widevine-licensing.axtest.net/AcquireLicense', + licenseHeaders: { + 'X-AxDRM-Message': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2ZXJzaW9uIjoxLCJjb21fa2V5X2lkIjoiYjMzNjRlYjUtNTFmNi00YWUzLThjOTgtMzNjZWQ1ZTMxYzc4IiwibWVzc2FnZSI6eyJ0eXBlIjoiZW50aXRsZW1lbnRfbWVzc2FnZSIsImtleXMiOlt7ImlkIjoiOWViNDA1MGQtZTQ0Yi00ODAyLTkzMmUtMjdkNzUwODNlMjY2IiwiZW5jcnlwdGVkX2tleSI6ImxLM09qSExZVzI0Y3Iya3RSNzRmbnc9PSJ9XX19.4lWwW46k-oWcah8oN18LPj5OLS5ZU-_AQv7fe0JhNjA' + } + } + } + }); + }); + + // TODO: why does this make the next test + // throw an "The operation was aborted." on firefox QUnit[testFn]('loops', function(assert) { const done = assert.async(); const player = this.player; diff --git a/test/videojs-http-streaming.test.js b/test/videojs-http-streaming.test.js index a2cc24c6..674ccfb6 100644 --- a/test/videojs-http-streaming.test.js +++ b/test/videojs-http-streaming.test.js @@ -6,7 +6,13 @@ import testDataManifests from 'create-test-data!manifests'; import { muxed as muxedSegment, encryptionKey, - encrypted as encryptedSegment + encrypted as encryptedSegment, + audio as audioSegment, + video as videoSegment, + mp4VideoInit as mp4VideoInitSegment, + mp4Video as mp4VideoSegment, + mp4AudioInit as mp4AudioInitSegment, + mp4Audio as mp4AudioSegment } from 'create-test-data!segments'; import { useFakeEnvironment, @@ -4254,7 +4260,7 @@ QUnit.test('populates quality levels list when available', function(assert) { ); }); -QUnit.test('configures eme for DASH if present on selectedinitialmedia', function(assert) { +QUnit.test('configures eme for DASH if present on sourceUpdater ready', function(assert) { this.player.eme = { options: { previousSetting: 1 @@ -4300,7 +4306,7 @@ QUnit.test('configures eme for DASH if present on selectedinitialmedia', functio } }; - this.player.tech_.vhs.masterPlaylistController_.trigger('selectedinitialmedia'); + this.player.tech_.vhs.masterPlaylistController_.sourceUpdater_.trigger('ready'); assert.deepEqual(this.player.eme.options, { previousSetting: 1 @@ -4320,7 +4326,7 @@ QUnit.test('configures eme for DASH if present on selectedinitialmedia', functio }, 'set source eme options'); }); -QUnit.test('configures eme for HLS if present on selectedinitialmedia', function(assert) { +QUnit.test('configures eme for HLS if present on sourceUpdater ready', function(assert) { this.player.eme = { options: { previousSetting: 1 @@ -4351,7 +4357,7 @@ QUnit.test('configures eme for HLS if present on selectedinitialmedia', function }) }; - this.player.tech_.vhs.masterPlaylistController_.trigger('selectedinitialmedia'); + this.player.tech_.vhs.masterPlaylistController_.sourceUpdater_.trigger('ready'); assert.deepEqual(this.player.eme.options, { previousSetting: 1 @@ -4371,7 +4377,7 @@ QUnit.test('configures eme for HLS if present on selectedinitialmedia', function }, 'set source eme options'); }); -QUnit.test('integration: configures eme for DASH if present on selectedinitialmedia', function(assert) { +QUnit.test('integration: configures eme for DASH if present on sourceUpdater ready', function(assert) { assert.timeout(3000); const done = assert.async(); @@ -4389,9 +4395,9 @@ QUnit.test('integration: configures eme for DASH if present on selectedinitialme } } }); - this.clock.tick(1); + openMediaSource(this.player, this.clock); - this.player.tech_.vhs.masterPlaylistController_.on('selectedinitialmedia', () => { + this.player.tech_.vhs.masterPlaylistController_.sourceUpdater_.on('ready', () => { assert.deepEqual(this.player.eme.options, { previousSetting: 1 }, 'did not modify plugin options'); @@ -4414,9 +4420,15 @@ QUnit.test('integration: configures eme for DASH if present on selectedinitialme this.standardXHRResponse(this.requests[0]); // this allows the audio playlist loader to load this.clock.tick(1); + + // respond to segement request to get trackinfo + this.standardXHRResponse(this.requests[1], mp4VideoInitSegment()); + this.standardXHRResponse(this.requests[2], mp4VideoSegment()); + this.standardXHRResponse(this.requests[3], mp4AudioInitSegment()); + this.standardXHRResponse(this.requests[4], mp4AudioSegment()); }); -QUnit.test('integration: configures eme for HLS if present on selectedinitialmedia', function(assert) { +QUnit.test('integration: configures eme for HLS if present on sourceUpdater ready', function(assert) { assert.timeout(3000); const done = assert.async(); @@ -4434,9 +4446,9 @@ QUnit.test('integration: configures eme for HLS if present on selectedinitialmed } } }); - this.clock.tick(1); + openMediaSource(this.player, this.clock); - this.player.tech_.vhs.masterPlaylistController_.on('selectedinitialmedia', () => { + this.player.tech_.vhs.masterPlaylistController_.sourceUpdater_.on('ready', () => { assert.deepEqual(this.player.eme.options, { previousSetting: 1 }, 'did not modify plugin options'); @@ -4467,6 +4479,10 @@ QUnit.test('integration: configures eme for HLS if present on selectedinitialmed // this allows the audio playlist loader to load this.clock.tick(1); + + // respond to segement request to get trackinfo + this.standardXHRResponse(this.requests.shift(), videoSegment()); + this.standardXHRResponse(this.requests.shift(), audioSegment()); }); QUnit.test( @@ -4511,7 +4527,7 @@ QUnit.test( } } }; - this.player.tech_.vhs.masterPlaylistController_.trigger('selectedinitialmedia'); + this.player.tech_.vhs.masterPlaylistController_.sourceUpdater_.trigger('ready'); assert.deepEqual(this.player.currentSource(), { src: 'manifest/master.mpd',