From be8341d2dd8580273fe879cccaf1acd7ce670ed6 Mon Sep 17 00:00:00 2001 From: Carey Hinoki Date: Fri, 26 Aug 2016 15:23:23 -0700 Subject: [PATCH 1/3] =?UTF-8?q?@chemoish=20add=20the=20ability=20to=20obta?= =?UTF-8?q?in=20current=20source=20object=20+=20current=20source=20objects?= =?UTF-8?q?=E2=80=94when=20using=20``=20or=20`src()`.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is needed for source retrival for two use cases: - preroll - resolution switch (kind of) Currently there is no way of accessing the source object for any DRM specified content. Plugin access only has API methods to `currentSrc` and `currentType`. This will allow for `currentSource` and `currentSources` to return unverified source object(s). # Conflicts: # src/js/player.js # test/unit/player.js --- src/js/player.js | 25 +++++++++ test/unit/player.test.js | 112 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) diff --git a/src/js/player.js b/src/js/player.js index 0118c985d7..2ad507dda7 100644 --- a/src/js/player.js +++ b/src/js/player.js @@ -614,10 +614,12 @@ class Player extends Component { if (source) { this.currentType_ = source.type; + if (source.src === this.cache_.src && this.cache_.currentTime > 0) { techOptions.startTime = this.cache_.currentTime; } + this.cache_.source = source; this.cache_.src = source.src; } @@ -1975,6 +1977,7 @@ class Player extends Component { // the tech loop to check for a compatible technology this.sourceList_([source]); } else { + this.cache_.source = source; this.cache_.src = source.src; this.currentType_ = source.type || ''; @@ -2025,6 +2028,8 @@ class Player extends Component { // load this technology with the chosen source this.loadTech_(sourceTech.tech, sourceTech.source); } + + this.cache_.sources = sources; } else { // We need to wrap this in a timeout to give folks a chance to add error event handlers this.setTimeout(function() { @@ -2061,6 +2066,26 @@ class Player extends Component { return this; } + /** + * Returns the current source objects. + * + * @return {Object[]} The current source objects + * @method currentSources + */ + currentSources() { + return this.cache_.sources || [this.currentSource()]; + } + + /** + * Returns the current source object. + * + * @return {Object} The current source object + * @method currentSource + */ + currentSource() { + return this.cache_.source || {}; + } + /** * Returns the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4 * Can be used in conjuction with `currentType` to assist in rebuilding the current source object. diff --git a/test/unit/player.test.js b/test/unit/player.test.js index efa724c3e2..6013131a19 100644 --- a/test/unit/player.test.js +++ b/test/unit/player.test.js @@ -120,6 +120,118 @@ QUnit.test('should get tag, source, and track settings', function(assert) { assert.equal(player.el(), null, 'player el killed'); }); +QUnit.test('should get current source from source tag', function(assert) { + const fixture = document.getElementById('qunit-fixture'); + + const html = [ + '' + ].join(''); + + fixture.innerHTML += html; + + const tag = document.getElementById('example_1'); + const player = TestHelpers.makePlayer({}, tag); + + assert.ok(player.currentSource().src === 'http://google.com'); + assert.ok(player.currentSource().type === 'video/mp4'); +}); + +QUnit.test('should get current sources from source tag', function(assert) { + const fixture = document.getElementById('qunit-fixture'); + + const html = [ + '' + ].join(''); + + fixture.innerHTML += html; + + const tag = document.getElementById('example_1'); + const player = TestHelpers.makePlayer({}, tag); + + assert.ok(player.currentSources()[0].src === 'http://google.com'); + assert.ok(player.currentSources()[0].type === 'video/mp4'); + assert.ok(player.currentSources()[1].src === 'http://hugo.com'); + assert.ok(player.currentSources()[1].type === 'video/webm'); +}); + +QUnit.test('should get current source from src set', function(assert) { + const fixture = document.getElementById('qunit-fixture'); + + const html = ''; + + fixture.innerHTML += html; + + const tag = document.getElementById('example_1'); + const player = TestHelpers.makePlayer({}, tag); + + // check for empty object + assert.ok(Object.keys(player.currentSource()).length === 0); + + player.src('http://google.com'); + + assert.ok(player.currentSource().src === 'http://google.com'); + assert.ok(player.currentSource().type === undefined); + + player.src({ + src: 'http://google.com' + }); + + assert.ok(player.currentSource().src === 'http://google.com'); + assert.ok(player.currentSource().type === undefined); + + player.src({ + src: 'http://google.com', + type: 'video/mp4' + }); + + assert.ok(player.currentSource().src === 'http://google.com'); + assert.ok(player.currentSource().type === 'video/mp4'); +}); + +QUnit.test('should get current sources from src set', function(assert) { + const fixture = document.getElementById('qunit-fixture'); + + const html = ''; + + fixture.innerHTML += html; + + const tag = document.getElementById('example_1'); + const player = TestHelpers.makePlayer({}, tag); + + // check for empty object + assert.ok(Object.keys(player.currentSources()[0]).length === 0); + + player.src([{ + src: 'http://google.com' + }, { + src: 'http://hugo.com' + }]); + + assert.ok(player.currentSources()[0].src === 'http://google.com'); + assert.ok(player.currentSources()[0].type === undefined); + assert.ok(player.currentSources()[1].src === 'http://hugo.com'); + assert.ok(player.currentSources()[1].type === undefined); + + player.src([{ + src: 'http://google.com', + type: 'video/mp4' + }, { + src: 'http://hugo.com', + type: 'video/webm' + }]); + + assert.ok(player.currentSources()[0].src === 'http://google.com'); + assert.ok(player.currentSources()[0].type === 'video/mp4'); + assert.ok(player.currentSources()[1].src === 'http://hugo.com'); + assert.ok(player.currentSources()[1].type === 'video/webm'); +}); + QUnit.test('should asynchronously fire error events during source selection', function(assert) { assert.expect(2); From 5248d86f9e7e14d2f9bfeef6591034e7c5fc17bc Mon Sep 17 00:00:00 2001 From: Carey Hinoki Date: Fri, 26 Aug 2016 15:41:22 -0700 Subject: [PATCH 2/3] @chemoish when the src redefines the current source, with a single source, have the current sources be set to null. When the `currentSources()` are called after `src('http://example.com')`, expect the `currentSources()` to only return the newly set source. This way sources, via `` or `src([...])` list, should never be out of sync when redefining a single source. Updating tests to specify behavior changes. Remove autoplay from fixtures to bypass `loadTech()` ramifications. # Conflicts: # src/js/player.js # test/unit/player.js --- src/js/player.js | 5 ++++- test/unit/player.test.js | 34 ++++++++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/js/player.js b/src/js/player.js index 2ad507dda7..0ef7d61691 100644 --- a/src/js/player.js +++ b/src/js/player.js @@ -619,6 +619,7 @@ class Player extends Component { techOptions.startTime = this.cache_.currentTime; } + this.cache_.sources = null; this.cache_.source = source; this.cache_.src = source.src; } @@ -1977,8 +1978,10 @@ class Player extends Component { // the tech loop to check for a compatible technology this.sourceList_([source]); } else { + this.cache_.sources = null; this.cache_.source = source; this.cache_.src = source.src; + this.currentType_ = source.type || ''; // wait until the tech is ready to set the source @@ -2083,7 +2086,7 @@ class Player extends Component { * @method currentSource */ currentSource() { - return this.cache_.source || {}; + return this.cache_.source || { src: this.currentSrc() }; } /** diff --git a/test/unit/player.test.js b/test/unit/player.test.js index 6013131a19..d64948b286 100644 --- a/test/unit/player.test.js +++ b/test/unit/player.test.js @@ -124,7 +124,7 @@ QUnit.test('should get current source from source tag', function(assert) { const fixture = document.getElementById('qunit-fixture'); const html = [ - '