123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 |
- import Flash from '../src/plugin';
- import {createTimeRange} from 'video.js';
- import document from 'global/document';
- import window from 'global/window';
- import sinon from 'sinon';
- import QUnit from 'qunit';
- // fake out the <object> interaction but leave all the other logic intact
- class MockFlash extends Flash {
- constructor() {
- super({});
- }
- }
- QUnit.module('Flash');
- QUnit.test('Flash.canPlaySource', function(assert) {
- const canPlaySource = Flash.canPlaySource;
- // Supported
- assert.ok(
- canPlaySource({type: 'video/mp4; codecs=avc1.42E01E,mp4a.40.2' }, {}),
- 'codecs supported'
- );
- assert.ok(canPlaySource({type: 'video/mp4' }, {}), 'video/mp4 supported');
- assert.ok(canPlaySource({type: 'video/x-flv' }, {}), 'video/x-flv supported');
- assert.ok(canPlaySource({type: 'video/flv' }, {}), 'video/flv supported');
- assert.ok(canPlaySource({type: 'video/m4v' }, {}), 'video/m4v supported');
- assert.ok(canPlaySource({type: 'VIDEO/FLV' }, {}), 'capitalized mime type');
- // Not supported
- assert.ok(!canPlaySource({ type: 'video/webm; codecs="vp8, vorbis"' }, {}));
- assert.ok(!canPlaySource({ type: 'video/webm' }, {}));
- });
- QUnit.test('currentTime', function(assert) {
- const getCurrentTime = Flash.prototype.currentTime;
- const setCurrentTime = Flash.prototype.setCurrentTime;
- let seekingCount = 0;
- let seeking = false;
- let setPropVal;
- let getPropVal;
- let result;
- // Mock out a Flash instance to avoid creating the swf object
- const mockFlash = {
- el_: {
- /* eslint-disable camelcase */
- vjs_setProperty(prop, val) {
- setPropVal = val;
- },
- vjs_getProperty() {
- return getPropVal;
- }
- /* eslint-enable camelcase */
- },
- seekable() {
- return createTimeRange(5, 1000);
- },
- trigger(event) {
- if (event === 'seeking') {
- seekingCount++;
- }
- },
- seeking() {
- return seeking;
- }
- };
- // Test the currentTime getter
- getPropVal = 3;
- result = getCurrentTime.call(mockFlash);
- assert.equal(result, 3, 'currentTime is retreived from the swf element');
- // Test the currentTime setter
- setCurrentTime.call(mockFlash, 10);
- assert.equal(setPropVal, 10, 'currentTime is set on the swf element');
- assert.equal(seekingCount, 1, 'triggered seeking');
- // Test current time while seeking
- setCurrentTime.call(mockFlash, 20);
- seeking = true;
- result = getCurrentTime.call(mockFlash);
- assert.equal(
- result,
- 20,
- 'currentTime is retrieved from the lastSeekTarget while seeking'
- );
- assert.notEqual(
- result,
- getPropVal,
- 'currentTime is not retrieved from the element while seeking'
- );
- assert.equal(seekingCount, 2, 'triggered seeking');
- // clamp seeks to seekable
- setCurrentTime.call(mockFlash, 1001);
- result = getCurrentTime.call(mockFlash);
- assert.equal(result, mockFlash.seekable().end(0), 'clamped to the seekable end');
- assert.equal(seekingCount, 3, 'triggered seeking');
- setCurrentTime.call(mockFlash, 1);
- result = getCurrentTime.call(mockFlash);
- assert.equal(result, mockFlash.seekable().start(0), 'clamped to the seekable start');
- assert.equal(seekingCount, 4, 'triggered seeking');
- });
- QUnit.test('dispose removes the object element even before ready fires', function(assert) {
- // This test appears to test bad functionaly that was fixed
- // so it's debateable whether or not it's useful
- const dispose = Flash.prototype.dispose;
- const mockFlash = new MockFlash();
- const noop = function() {};
- // Mock required functions for dispose
- mockFlash.off = noop;
- mockFlash.trigger = noop;
- mockFlash.el_ = {};
- dispose.call(mockFlash);
- assert.strictEqual(mockFlash.el_, null, 'swf el is nulled');
- });
- QUnit.test('ready triggering before and after disposing the tech', function(assert) {
- const checkReady = sinon.stub(Flash, 'checkReady');
- const fixtureDiv = document.getElementById('qunit-fixture');
- const playerDiv = document.createElement('div');
- const techEl = document.createElement('div');
- techEl.id = 'foo1234';
- playerDiv.appendChild(techEl);
- fixtureDiv.appendChild(playerDiv);
- // Mock the swf element
- techEl.tech = {
- el() {
- return techEl;
- }
- };
- playerDiv.player = {
- tech: techEl.tech
- };
- Flash.onReady(techEl.id);
- assert.ok(checkReady.called, 'checkReady should be called before the tech is disposed');
- // remove the tech el from the player div to simulate being disposed
- playerDiv.removeChild(techEl);
- Flash.onReady(techEl.id);
- assert.ok(
- !checkReady.calledTwice,
- 'checkReady should not be called after the tech is disposed'
- );
- Flash.checkReady.restore();
- });
- QUnit.test('should have the source handler interface', function(assert) {
- assert.ok(Flash.registerSourceHandler, 'has the registerSourceHandler function');
- });
- QUnit.test('canPlayType should select the correct types to play', function(assert) {
- const canPlayType = Flash.nativeSourceHandler.canPlayType;
- assert.equal(canPlayType('video/flv'), 'maybe', 'should be able to play FLV files');
- assert.equal(canPlayType('video/x-flv'), 'maybe', 'should be able to play x-FLV files');
- assert.equal(canPlayType('video/mp4'), 'maybe', 'should be able to play MP4 files');
- assert.equal(canPlayType('video/m4v'), 'maybe', 'should be able to play M4V files');
- assert.equal(
- canPlayType('video/ogg'),
- '',
- 'should return empty string if it can not play the video'
- );
- });
- QUnit.test('canHandleSource should be able to work with src objects without a type', function(assert) {
- const canHandleSource = Flash.nativeSourceHandler.canHandleSource;
- assert.equal(
- 'maybe',
- canHandleSource({ src: 'test.video.mp4' }, {}),
- 'should guess that it is a mp4 video'
- );
- assert.equal(
- 'maybe',
- canHandleSource({ src: 'test.video.m4v' }, {}),
- 'should guess that it is a m4v video'
- );
- assert.equal(
- 'maybe',
- canHandleSource({ src: 'test.video.flv' }, {}),
- 'should guess that it is a flash video'
- );
- assert.equal(
- '',
- canHandleSource({ src: 'test.video.wgg' }, {}),
- 'should return empty string if it can not play the video'
- );
- });
- QUnit.test('seekable', function(assert) {
- const seekable = Flash.prototype.seekable;
- let result;
- const mockFlash = {
- duration() {
- return this.duration_;
- }
- };
- // Test a normal duration
- mockFlash.duration_ = 23;
- result = seekable.call(mockFlash);
- assert.equal(result.length, 1, 'seekable is non-empty');
- assert.equal(result.start(0), 0, 'starts at zero');
- assert.equal(result.end(0), mockFlash.duration_, 'ends at the duration');
- // Test a zero duration
- mockFlash.duration_ = 0;
- result = seekable.call(mockFlash);
- assert.equal(
- result.length, mockFlash.duration_,
- 'seekable is empty with a zero duration'
- );
- });
- QUnit.test('play after ended seeks to the beginning', function(assert) {
- let plays = 0;
- const seeks = [];
- Flash.prototype.play.call({
- el_: {
- /* eslint-disable camelcase */
- vjs_play() {
- plays++;
- }
- /* eslint-enable camelcase */
- },
- ended() {
- return true;
- },
- setCurrentTime(time) {
- seeks.push(time);
- }
- });
- assert.equal(plays, 1, 'called play on the SWF');
- assert.equal(seeks.length, 1, 'seeked on play');
- assert.equal(seeks[0], 0, 'seeked to the beginning');
- });
- QUnit.test('duration returns NaN, Infinity or duration according to the HTML standard', function(assert) {
- const duration = Flash.prototype.duration;
- let mockedDuration = -1;
- let mockedReadyState = 0;
- let result;
- const mockFlash = {
- el_: {
- /* eslint-disable camelcase */
- vjs_getProperty() {
- return mockedDuration;
- }
- /* eslint-enable camelcase */
- },
- readyState() {
- return mockedReadyState;
- }
- };
- result = duration.call(mockFlash);
- assert.ok(Number.isNaN(result), 'duration returns NaN when readyState equals 0');
- mockedReadyState = 1;
- result = duration.call(mockFlash);
- assert.ok(
- !Number.isFinite(result),
- 'duration returns Infinity when duration property is less then 0'
- );
- mockedDuration = 1;
- result = duration.call(mockFlash);
- assert.equal(
- result,
- 1,
- 'duration returns duration property when readyState' +
- ' and duration property are both higher than 0'
- );
- });
- QUnit.test('getVideoPlaybackQuality API exists', function(assert) {
- const propertyCalls = [];
- const videoPlaybackQuality = { test: 'test' };
- const mockFlash = {
- el_: {
- /* eslint-disable camelcase */
- vjs_getProperty(attr) {
- propertyCalls.push(attr);
- return videoPlaybackQuality;
- }
- /* eslint-enable camelcase */
- }
- };
- assert.deepEqual(
- Flash.prototype.getVideoPlaybackQuality.call(mockFlash),
- videoPlaybackQuality,
- 'called to get property from flash'
- );
- assert.equal(propertyCalls.length, 1, 'only one property call');
- assert.equal(
- propertyCalls[0],
- 'getVideoPlaybackQuality',
- 'called for getVideoPlaybackQuality'
- );
- });
- QUnit.test('getVideoPlaybackQuality uses best available creationTime', function(assert) {
- const origPerformance = window.performance;
- const origDate = window.Date;
- const videoPlaybackQuality = {};
- const mockFlash = {
- el_: {
- /* eslint-disable camelcase */
- vjs_getProperty(attr) {
- return videoPlaybackQuality;
- }
- /* eslint-enable camelcase */
- }
- };
- window.performance = void 0;
- assert.notOk(
- Flash.prototype.getVideoPlaybackQuality.call(mockFlash).creationTime,
- 'no creationTime when no performance API available'
- );
- window.performance = {
- timing: {}
- };
- assert.notOk(
- Flash.prototype.getVideoPlaybackQuality.call(mockFlash).creationTime,
- 'no creationTime when performance API insufficient'
- );
- window.performance = {
- now: () => 4
- };
- assert.equal(
- Flash.prototype.getVideoPlaybackQuality.call(mockFlash).creationTime,
- 4,
- 'creationTime is performance.now when available'
- );
- window.Date = {
- now: () => 10
- };
- window.performance = {
- timing: {
- navigationStart: 3
- }
- };
- assert.equal(
- Flash.prototype.getVideoPlaybackQuality.call(mockFlash).creationTime,
- 7,
- 'creationTime uses Date.now() - navigationStart when available'
- );
- window.performance.now = () => 4;
- assert.equal(
- Flash.prototype.getVideoPlaybackQuality.call(mockFlash).creationTime,
- 4,
- 'creationTime prioritizes performance.now when available'
- );
- window.Date = origDate;
- window.performance = origPerformance;
- });
|