nsplayer
Version:
NSPlayer, a player which supports quality list of dash and hls
231 lines (179 loc) • 7.02 kB
JavaScript
'use strict';
var global = typeof self !== 'undefined' ? self : globalThis;
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var index = require('./index-773e68b1.js');
var common = require('@newstudios/common');
require('delegates');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty__default["default"](target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
class BasePlayer extends index.CorePlayer {
constructor(_video, sources) {
super(_video, sources[0]);
_defineProperty__default["default"](this, "_capLevelToPlayerSize", false);
_defineProperty__default["default"](this, "_changeQualityDisposable", this._register(new common.MutableDisposable()));
this._video = _video;
this._sources = sources.map(({
bitrate,
width,
height,
src,
mime: _mime = 'video/mp4'
}) => {
if (!bitrate || !width || !height) {
throw new Error(`we need bitrate / width / height info for source ${src}`);
}
return {
bitrate,
width,
height,
src,
mime: _mime
};
}).sort((a, b) => a.bitrate - b.bitrate);
this._currentLevelIndex = 0;
this._nextLevelIndex = 0;
this._startLevelIndex = 0;
this._register(common.toDisposable(() => _video.pause()));
}
get levels() {
return this._sources;
}
get currentLevel() {
return this.levels[this._currentLevelIndex];
}
get nextLevel() {
return this.levels[this._nextLevelIndex];
}
get autoQualityEnabled() {
return false;
}
levelToQuality(source) {
const fps = index.computeFPS(source.fps);
return _objectSpread({
width: source.width,
height: source.height,
bitrate: source.bitrate,
type: 'video'
}, fps ? {
fps
} : {});
}
findLevelIndexByQualityLevel(playLevel) {
const levels = this.levels; // bitrate match
const idx = levels.findIndex(level => level.bitrate === playLevel.bitrate);
if (idx >= 0) {
return idx;
} // short side match
const shortSide = Math.min(playLevel.width, playLevel.height);
return levels.findIndex(level => Math.min(level.width, level.height) === shortSide);
}
setAutoQualityState(auto) {
if (auto) {
throw new Error('unsupported auto quality');
}
}
setInitialBitrate(bitrate) {
let index = 0;
const levels = this.levels.slice().sort((a, b) => a.bitrate - b.bitrate);
for (let i = 0; i < levels.length; i++) {
// FIXME levels should be safe
if (levels[i].bitrate <= bitrate) {
index = i;
} else {
break;
}
}
this.log('setInitialBitrate', 'start level:', index);
this._startLevelIndex = index;
}
setNextLevelIndex(index) {
this._nextLevelIndex = index;
if (!this.ready) {
this.log('setNextLevelIndex', 'start level:', index);
this._startLevelIndex = index; // should not change any source
return;
}
const source = this.nextLevel;
if (source) {
const video = this._video;
const currentTime = video.currentTime;
const autoplay = video.autoplay;
const playbackRate = video.playbackRate;
const paused = video.paused;
video.pause();
video.autoplay = true;
video.src = source.src;
const reset = () => {
this._currentLevelIndex = index;
this._changeQualityDisposable.value = undefined;
video.currentTime = currentTime;
video.autoplay = autoplay;
video.playbackRate = playbackRate;
if (paused) {
video.pause();
} else {
video.play();
}
};
const onCanPlay = common.Event.fromDOMEventEmitter(video, 'canplay');
this._changeQualityDisposable.value = onCanPlay(reset);
} else {
console.error(`pause the video due to the next level ${index} unresolved in normalplayer`);
this.video.pause();
}
}
onInit(video, source) {
source = this.levels[this._startLevelIndex] || source;
this._nextLevelIndex = this._startLevelIndex;
this._currentLevelIndex = this._nextLevelIndex;
this.updateQualityLevel(); // initialize
if (video.canPlayType(source.mime)) {
var _this$currentLevel;
const disposables = this._register(new common.DisposableStore());
const onLoadStart = common.Event.fromDOMEventEmitter(video, 'loadstart');
const onLoadEnd = common.Event.fromDOMEventEmitter(video, 'loadedmetadata');
onLoadStart(this.updateNextQualityLevel, this, disposables);
onLoadEnd(() => {
this._currentLevelIndex = this._nextLevelIndex;
this.updateQualityLevel();
}, null, disposables); // may lead a new next level
this.updatePlayList(); // must init the current level because next level may changed while play list changed
this._currentLevelIndex = this._nextLevelIndex >= 0 && this._nextLevelIndex < this._sources.length ? this._nextLevelIndex : this._startLevelIndex;
this.updateQualityLevel(); // FIXME currentTime restore
video.src = ((_this$currentLevel = this.currentLevel) === null || _this$currentLevel === void 0 ? void 0 : _this$currentLevel.src) || source.src;
if (video.autoplay) {
video.play();
}
this.setReady();
} else {
throw new Error(`cannot play this video with mime type ${source.mime}`);
}
}
/** FIXME cap level safe begin */
// private isLevelSizeSafe(width: number, height: number): boolean {
// if (!this._capLevelToPlayerSize) {
// return true
// }
// return true
// }
setCapLevelToPlayerSize(capLevelToPlayerSize) {
this.log('setCapLevelToPlayerSize', capLevelToPlayerSize);
this._capLevelToPlayerSize = capLevelToPlayerSize;
}
get capLevelToPlayerSize() {
return this._capLevelToPlayerSize;
}
/** FIXME cap level safe end */
get bandwidthEstimate() {
return NaN;
}
get name() {
return 'MP4Player (1.3)';
}
get supportAutoQuality() {
return false;
}
}
exports.BasePlayer = BasePlayer;