From 028559ccb0427fe3f908bc0a52d0baa4500871d3 Mon Sep 17 00:00:00 2001 From: Carey Hinoki Date: Thu, 3 Nov 2016 12:50:55 -0700 Subject: [PATCH] feat: add ability to get current source object and all source objects (#2678) Adds `currentSource` and `currentSources` methods to the player that return the current source object, containing `currentSrc()` and `currentType()`, and all source objects that were given to the player. Fixes #2443 --- src/js/player.js | 43 ++++++++++++ test/unit/player.test.js | 130 +++++++++++++++++++++++++++++++++++ test/unit/tech/tech-faker.js | 3 + 3 files changed, 176 insertions(+) diff --git a/src/js/player.js b/src/js/player.js index 3ba8a6d8ce..5406a02be5 100644 --- a/src/js/player.js +++ b/src/js/player.js @@ -675,10 +675,13 @@ 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_.sources = null; + this.cache_.source = source; this.cache_.src = source.src; } @@ -1866,7 +1869,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 @@ -1915,6 +1921,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() { @@ -1949,6 +1957,41 @@ class Player extends Component { return this; } + /** + * Returns the current source objects. + * + * @return {Object[]} The current source objects + * @method currentSources + */ + currentSources() { + const source = this.currentSource(); + const sources = []; + + // assume `{}` or `{ src }` + if (Object.keys(source).length !== 0) { + sources.push(source); + } + + return this.cache_.sources || sources; + } + + /** + * Returns the current source object. + * + * @return {Object} The current source object + * @method currentSource + */ + currentSource() { + const source = {}; + const src = this.currentSrc(); + + if (src) { + source.src = src; + } + + return this.cache_.source || 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 2e4af3a12b..8ea322ffe3 100644 --- a/test/unit/player.test.js +++ b/test/unit/player.test.js @@ -120,6 +120,136 @@ 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'); + + // when redefining src expect sources to update accordingly + player.src('http://google.com'); + + assert.ok(player.currentSources()[0].src === 'http://google.com'); + assert.ok(player.currentSources()[0].type === undefined); + assert.ok(player.currentSources()[1] === undefined); +}); + +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); + + player.loadTech_('Html5'); + + // check for matching undefined src + assert.deepEqual(player.currentSource(), {}); + + 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); + + player.loadTech_('Html5'); + + // check for matching undefined src + assert.ok(player.currentSources(), []); + + 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'); + + // when redefining src expect sources to update accordingly + player.src('http://hugo.com'); + + assert.ok(player.currentSources()[0].src === 'http://hugo.com'); + assert.ok(player.currentSources()[0].type === undefined); + assert.ok(player.currentSources()[1] === undefined); +}); + QUnit.test('should asynchronously fire error events during source selection', function(assert) { assert.expect(2); diff --git a/test/unit/tech/tech-faker.js b/test/unit/tech/tech-faker.js index 9b7190121c..b6f47dd021 100644 --- a/test/unit/tech/tech-faker.js +++ b/test/unit/tech/tech-faker.js @@ -39,6 +39,9 @@ class TechFaker extends Tech { src() { return 'movie.mp4'; } + currentSrc() { + return 'movie.mp4'; + } volume() { return 0; }