Permalink
Browse files

Use isDvr in html5, and add module doc comments and tests

JW8-2289
  • Loading branch information...
robwalch committed Oct 26, 2018
1 parent 8c0a443 commit 33e1059a39bbb653bc0b7cb2d805c942585eb9ac
Showing with 74 additions and 32 deletions.
  1. +6 −8 src/js/providers/html5.js
  2. +21 −9 src/js/providers/utils/stream-type.js
  3. +47 −15 test/unit/stream-type-util-test.js
@@ -6,6 +6,7 @@ import { STATE_IDLE, STATE_PLAYING, STATE_STALLED, MEDIA_META, MEDIA_ERROR, MEDI
import VideoEvents from 'providers/video-listener-mixin';
import VideoAction from 'providers/video-actions-mixin';
import VideoAttached from 'providers/video-attached-mixin';
import { isDvr } from 'providers/utils/stream-type';
import { style } from 'utils/css';
import { emptyElement } from 'utils/dom';
import DefaultProvider from 'providers/default';
@@ -70,7 +71,7 @@ function VideoProvider(_playerId, _playerConfig, mediaElement) {
const _this = this;
let minDvrWindow = _playerConfig.minDvrWindow || 120;
let minDvrWindow = _playerConfig.minDvrWindow;
const MediaEvents = {
progress() {
@@ -248,9 +249,6 @@ function VideoProvider(_playerId, _playerConfig, mediaElement) {
},
isLive() {
return _videotag.duration === Infinity;
},
isDVR() {
return _this.isLive() && ((_getSeekableEnd() - _getSeekableStart()) >= minDvrWindow);
}
});
@@ -325,7 +323,7 @@ function VideoProvider(_playerId, _playerConfig, mediaElement) {
const end = _getSeekableEnd();
if (_this.isLive() && end) {
const seekableDuration = end - _getSeekableStart();
if (seekableDuration !== Infinity && seekableDuration > minDvrWindow) {
if (isDvr(seekableDuration, minDvrWindow)) {
// Player interprets negative duration as DVR
duration = -seekableDuration;
}
@@ -369,7 +367,7 @@ function VideoProvider(_playerId, _playerConfig, mediaElement) {
}
function setPlaylistItem(item) {
minDvrWindow = item.minDvrWindow || minDvrWindow;
minDvrWindow = item.minDvrWindow;
_levels = item.sources;
_currentQuality = _pickInitialQuality(_levels);
}
@@ -398,7 +396,7 @@ function VideoProvider(_playerId, _playerConfig, mediaElement) {
function _play() {
const resumingPlayback = _videotag.paused && _videotag.played && _videotag.played.length;
if (resumingPlayback && _this.isLive() && !_this.isDVR()) {
if (resumingPlayback && _this.isLive() && !isDvr(_getSeekableEnd() - _getSeekableStart(), minDvrWindow)) {
_this.clearTracks();
_videotag.load();
}
@@ -564,7 +562,7 @@ function VideoProvider(_playerId, _playerConfig, mediaElement) {
if (unpausing && _this.isLive()) {
const end = _getSeekableEnd();
const seekableDuration = end - _getSeekableStart();
const isLiveNotDvr = seekableDuration < minDvrWindow;
const isLiveNotDvr = !isDvr(seekableDuration, minDvrWindow);
const behindLiveEdge = end - _videotag.currentTime;
if (isLiveNotDvr && end && (behindLiveEdge > 15 || behindLiveEdge < 0)) {
// resume playback at edge of live stream
@@ -1,22 +1,34 @@
/** @module */
// It's DVR if the duration is above the minDvrWindow, Live otherwise
/**
* It's DVR if the duration is not Infinity and above the minDvrWindow, Live otherwise.
* @param {Number} duration - The duration or seekable range of a stream in seconds.
* @param {Number} minDvrWindow - The duration threshold beyond which a stream should be treated as DVR instead of Live.
* @returns {boolean} DVR or not.
*/
export function isDvr(duration, minDvrWindow) {
return Math.abs(duration) >= Math.max(minDvrWindow, 0);
return duration !== Infinity && Math.abs(duration) >= Math.max(validMinDvrWindow(minDvrWindow), 0);
}
// Determine the adaptive type - Live, DVR, or VOD
// Duration can be positive or negative, but minDvrWindow should always be positive
/**
* Determine the adaptive type.
* @param {Number} duration - The duration or seekable range of a stream in seconds. Can be positive or negative.
* Positive or non-infinite values will result in a return value of 'VOD'. Infinite values always return 'LIVE'.
* @param {Number} minDvrWindow - The duration threshold beyond which a stream should be treated as DVR instead of Live.
* minDvrWindow should always be positive.
* @returns {('VOD'|'LIVE'|'DVR')} The stream typeR.
*/
export function streamType(duration, minDvrWindow) {
const _minDvrWindow = (minDvrWindow === undefined) ? 120 : minDvrWindow;
let type = 'VOD';
if (duration === Infinity) {
// Live streams are always Infinity duration
type = 'LIVE';
} else if (duration < 0) {
type = isDvr(duration, _minDvrWindow) ? 'DVR' : 'LIVE';
type = isDvr(duration, validMinDvrWindow(minDvrWindow)) ? 'DVR' : 'LIVE';
}
// Default option is VOD (i.e. positive or non-infinite)
return type;
}
function validMinDvrWindow(minDvrWindow) {
return (minDvrWindow === undefined) ? 120 : Math.max(minDvrWindow, 0);
}
@@ -1,46 +1,78 @@
import * as streamTypeUtil from 'providers/utils/stream-type';
import { streamType, isDvr } from 'providers/utils/stream-type';
describe('stream-type', function() {
it('stream-type.streamType', function() {
it('determines streamType', function() {
const minDvrWindow = 120;
let type = streamTypeUtil.streamType(0, minDvrWindow);
let type = streamType(0, minDvrWindow);
expect(type, 'streamType with 0 and 120').to.equal('VOD');
type = streamTypeUtil.streamType(0, 0);
type = streamType(0, 0);
expect(type, 'streamType with 0 and 0').to.equal('VOD');
type = streamTypeUtil.streamType(10, minDvrWindow);
type = streamType(10, minDvrWindow);
expect(type, 'streamType with 10 and 120').to.equal('VOD');
type = streamTypeUtil.streamType(10, undefined);
type = streamType(10, undefined);
expect(type, 'streamType with 10 and undefined').to.equal('VOD');
type = streamTypeUtil.streamType(-120, minDvrWindow);
type = streamType(-120, minDvrWindow);
expect(type, 'streamType with -120 and 120').to.equal('DVR');
type = streamTypeUtil.streamType(-120, -10);
type = streamType(-120, -10);
expect(type, 'streamType with 120 and -10').to.equal('DVR');
type = streamTypeUtil.streamType(-120, 0);
type = streamType(-120, 0);
expect(type, 'streamType with 120 and 0').to.equal('DVR');
type = streamTypeUtil.streamType(-120, 0);
type = streamType(-120, 0);
expect(type, 'streamType with -120 and 0').to.equal('DVR');
type = streamTypeUtil.streamType(-120, undefined);
type = streamType(-120, undefined);
expect(type, 'streamType with 120 and undefined').to.equal('DVR');
type = streamTypeUtil.streamType(-20, minDvrWindow);
type = streamType(-20, minDvrWindow);
expect(type, 'streamType with -20 and 120').to.equal('LIVE');
type = streamTypeUtil.streamType(-1, minDvrWindow);
type = streamType(-1, minDvrWindow);
expect(type, 'streamType with -1 and 120').to.equal('LIVE');
type = streamTypeUtil.streamType(Infinity, minDvrWindow);
type = streamType(Infinity, minDvrWindow);
expect(type, 'streamType with Infinity').to.equal('LIVE');
type = streamTypeUtil.streamType(-20, undefined);
type = streamType(-20, undefined);
expect(type, 'streamType with -20 and undefined').to.equal('LIVE');
});
it('determines isDvr', function() {
const minDvrWindow = 120;
let dvrMode;
dvrMode = isDvr(0, minDvrWindow);
expect(dvrMode, 'expect false when duration is less than minDvrWindow').to.equal(false);
dvrMode = isDvr(Infinity, minDvrWindow);
expect(dvrMode, 'expect false when duration is Infinity').to.equal(false);
dvrMode = isDvr(-110, minDvrWindow);
expect(dvrMode, 'expect false when absolute duration is less than minDvrWindow').to.equal(false);
dvrMode = isDvr(10, undefined);
expect(dvrMode, 'expect false when duration is greater than 0 and minDvrWindow is undefined').to.equal(false);
dvrMode = isDvr(-10, undefined);
expect(dvrMode, 'expect false when duration is less than 0 and minDvrWindow is undefined').to.equal(false);
dvrMode = isDvr(0, 0);
expect(dvrMode, 'expect true when duration is equal to minDvrWindow').to.equal(true);
dvrMode = isDvr(-120, minDvrWindow);
expect(dvrMode, 'expect true when absolute duration equals minDvrWindow').to.equal(true);
dvrMode = isDvr(-60, -10);
expect(dvrMode, 'expect true when absolute duration is greater than negative minDvrWindow').to.equal(true);
dvrMode = isDvr(-60, 0);
expect(dvrMode, 'expect true when absolute duration is greater than minDvrWindow').to.equal(true);
});
});

0 comments on commit 33e1059

Please sign in to comment.