UNPKG

nsplayer

Version:

NSPlayer, a player which supports quality list of dash and hls

312 lines (247 loc) 11.3 kB
'use strict'; var global = typeof self !== 'undefined' ? self : globalThis; var _defineProperty = require('@babel/runtime/helpers/defineProperty'); var index = require('./index-773e68b1.js'); var shaka = require('shaka-player'); 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); var shaka__default = /*#__PURE__*/_interopDefaultLegacy(shaka); 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 ShakaPlayer extends index.CorePlayer { // private _maxWidth = 1e5 // private _maxHeight = 1e5 constructor(video, source, _fastSwitch = true, // private _capLevelToPlayerSize = false capLevelToPlayerSize = false) { super(video, source); _defineProperty__default["default"](this, "_videoSizeObserverTimer", this._register(new common.IntervalTimer())); _defineProperty__default["default"](this, "_initialBitrateMutable", this._register(new common.MutableDisposable())); _defineProperty__default["default"](this, "_videoWidth", 0); _defineProperty__default["default"](this, "_videoHeight", 0); _defineProperty__default["default"](this, "_bufferMutable", this._register(new common.MutableDisposable())); _defineProperty__default["default"](this, "_onVideoLevelSwitched", this._register(new common.Emitter())); _defineProperty__default["default"](this, "onVideoLevelSwitched", this._onVideoLevelSwitched.event); _defineProperty__default["default"](this, "videoSizeHandler", () => { let changed = false; if (this._videoWidth !== this.video.videoWidth) { this._videoWidth = this.video.videoWidth; changed = true; } if (this._videoHeight !== this.video.videoHeight) { this._videoHeight = this.video.videoHeight; changed = true; } if (changed && !isNaN(this._videoWidth) && !isNaN(this._videoHeight)) { this._onVideoLevelSwitched.fire(); } // // capLevelToPlayerSize // const maxWidth = this._capLevelToPlayerSize // ? this.video.clientWidth * this.devicePixelRatio // : 1e5 // const maxHeight = this._capLevelToPlayerSize // ? this.video.clientHeight * this.devicePixelRatio // : 1e5 // if (maxWidth !== this._maxWidth && !isNaN(maxWidth)) { // this._maxWidth = maxWidth // this._shakaPlayer.configure('abr.restrictions.maxWidth', maxWidth) // } // if (maxHeight !== this._maxHeight && !isNaN(maxHeight)) { // this._maxHeight = maxHeight // this._shakaPlayer.configure('abr.restrictions.maxHeight', maxHeight) // } }); this._fastSwitch = _fastSwitch; const player = new shaka__default["default"].Player(); this._shakaPlayer = player; // https://github.com/google/shaka-player/pull/2330/commits/4f8e1286610e4ae667f0bb82f4f4fa97b451595c this._shakaPlayer.configure({ manifest: { dash: { ignoreEmptyAdaptationSet: true, ignoreMinBufferTime: true } }, streaming: { bufferingGoal: 15, inaccurateManifestTolerance: 1 }, abr: { restrictToElementSize: capLevelToPlayerSize, restrictToScreenSize: capLevelToPlayerSize } }); this.debugError(); this._register(common.toDisposable(() => player.destroy())); } debugError() { const onError = common.Event.fromDOMEventEmitter(this._shakaPlayer, 'error'); this._register(onError(err => { var _err$detail; return console.warn('shaka error', ((_err$detail = err.detail) === null || _err$detail === void 0 ? void 0 : _err$detail.message) || ''); })); } startObserveVideoSize() { this._videoSizeObserverTimer.cancelAndSet(this.videoSizeHandler, 1000); } // private get devicePixelRatio() { // const w = window as any as Record<string, number> // return ( // w.devicePixelRatio || // w.mozDevicePixelRatio || // w.webkitDevicePixelRatio || // w.msDevicePixelRatio || // 1 // ) // } stopObserveVideoSize() { this._videoSizeObserverTimer.cancel(); } get name() { return `SHAKAPlayer (${shaka__default["default"].Player.version})`; } get supportAutoQuality() { // return shaka.Player.isBrowserSupported() return true; } get bandwidthEstimate() { return this._shakaPlayer.getStats().estimatedBandwidth; } setInitialBitrate(bitrate) { // abr control doc https://github.com/shaka-project/shaka-player/issues/629 this._shakaPlayer.configure('abr.defaultBandwidthEstimate', bitrate); // if (this.ready) { // return // } // this._initialBitrateMutable.value = this.onOncePlayListReady(() => { // let index = 0 // const levels = this.levels // for (let i = 0; i < levels.length; i++) { // if ((levels[i].videoBandwidth || levels[i].bandwidth) <= bitrate) { // index = i // } else { // break // } // } // this.log('setInitialBitrate', 'async start level:', index) // const isAuto = this.autoQualityEnabled // if (isAuto) { // this._shakaPlayer.configure('abr.enabled', false) // } // this._shakaPlayer.selectVariantTrack(levels[index], true) // if (isAuto) { // this._shakaPlayer.configure('abr.enabled', true) // } // }) } setCapLevelToPlayerSize(capLevelToPlayerSize) { this.log('setCapLevelToPlayerSize', capLevelToPlayerSize); this._shakaPlayer.configure({ abr: { restrictToElementSize: capLevelToPlayerSize, restrictToScreenSize: capLevelToPlayerSize } }); // this._capLevelToPlayerSize = capLevelToPlayerSize } get capLevelToPlayerSize() { return this._shakaPlayer.getConfiguration().abr.restrictToElementSize || this._shakaPlayer.getConfiguration().abr.restrictToScreenSize || false; // return this._capLevelToPlayerSize } get levels() { return this._shakaPlayer.getVariantTracks().filter(track => track.type === 'variant' && typeof track.videoId === 'number' && typeof track.videoCodec === 'string'); } get currentLevel() { return this._shakaPlayer.getVariantTracks().find(track => track.type === 'variant' && typeof track.videoId === 'number' && track.active); } get nextLevel() { return this._nextTrack; } get autoQualityEnabled() { return this._shakaPlayer.getConfiguration().abr.enabled; } levelToQuality(level) { const fps = index.computeFPS(level.frameRate); return _objectSpread({ bitrate: typeof level.videoId === 'number' ? level.videoBandwidth || level.bandwidth : typeof level.audioId === 'number' ? level.audioBandwidth || level.bandwidth : level.bandwidth, width: level.width || 0, height: level.height || 0, type: typeof level.videoId === 'number' ? 'video' : typeof level.audioId === 'number' ? 'audio' : undefined }, fps ? { fps } : {}); } findLevelIndexByQualityLevel(playLevel) { // bitrate match const idx = this.levels.findIndex(level => level.bandwidth === playLevel.bitrate); if (idx >= 0) { return idx; } // short side match const shortSide = Math.min(playLevel.width, playLevel.height); return this.levels.findIndex(level => Math.min(level.width || 0, level.height || 0) === shortSide); } setAutoQualityState(auto) { this._shakaPlayer.configure('abr.enabled', auto); if (!auto) { this._initialBitrateMutable.value = undefined; } } setNextLevelIndex(index) { const track = this.levels[index]; if (track) { this._nextTrack = track; if (this.ready) { this._shakaPlayer.selectVariantTrack(track, true, this._fastSwitch ? 5 : 8); } else if (!this.autoQualityEnabled) { this.log('setNextLevelIndex', 'start level:', index, `${track.width}x${track.height}`); this._shakaPlayer.selectVariantTrack(track); } this._initialBitrateMutable.value = undefined; } } onInit(video, source) { const player = this._shakaPlayer; player.attach(video); player.load(source.src, 0, source.mime); const disposables = this._register(new common.DisposableStore()); common.Event.fromDOMEventEmitter(video, 'play')(this.startObserveVideoSize, this, disposables); common.Event.fromDOMEventEmitter(video, 'pause')(this.stopObserveVideoSize, this, disposables); const onTracksChanged = common.Event.fromDOMEventEmitter(player, 'trackschanged'); const onAutoLevelSwitched = common.Event.fromDOMEventEmitter(player, 'adaptation'); const onLoad = common.Event.fromDOMEventEmitter(player, 'loaded'); const onBuffering = common.Event.fromDOMEventEmitter(player, 'buffering'); const onManualLevelSwitched = common.Event.fromDOMEventEmitter(player, 'variantchanged'); // hack video event, workaround onBuffering(evt => { if (evt.buffering) { this._bufferMutable.value = common.Event.fromDOMEventEmitter(video, ['playing', 'canplaythrough'])(() => { video.dispatchEvent(new window.Event('waiting')); }); if (!video.paused) { video.dispatchEvent(new window.Event('waiting')); } } else { this._bufferMutable.value = undefined; if (!video.paused) { video.dispatchEvent(new window.Event('playing')); } } }, null, disposables); onTracksChanged(this.updatePlayList, this, disposables); onLoad(() => { video.autoplay && video.play(); this.setReady(); }, null, disposables); onAutoLevelSwitched(() => this._nextTrack = this.currentLevel, null, disposables); // FIXME should quote out this because onVideoLevelSwitched is already existed // onAutoLevelSwitched(this.updateNextQualityLevel, this, disposables) onManualLevelSwitched(this.updateNextQualityLevel, this, disposables); this.onVideoLevelSwitched(this.updateQualityLevel, this, disposables); } } _defineProperty__default["default"](ShakaPlayer, "_fixed", function fixPlayer() { if (typeof window !== 'undefined') { shaka__default["default"].polyfill.installAll(); // if (shaka.Player.isBrowserSupported()) { // return true // } else { // console.warn('Shaka player not supported') // } return true; } return false; }()); exports.ShakaPlayer = ShakaPlayer;