UNPKG

nsplayer

Version:

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

233 lines (180 loc) 7.53 kB
'use strict'; var global = typeof self !== 'undefined' ? self : globalThis; var _defineProperty = require('@babel/runtime/helpers/defineProperty'); var common = require('@newstudios/common'); var index = require('./index-773e68b1.js'); var dashjs = require('dashjs'); require('delegates'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty); function getBytesLength(request) { return request.trace.reduce((a, b) => a + b.b[0], 0); } function getTime(request) { return request.trace.reduce((a, b) => a + b.d, 0); } function caculateBandWidthFor(player, type) { const metrics = player.getDashMetrics(); const requests = metrics.getHttpRequests(type); const lastCount = 4; const requestWindow = requests.slice(-lastCount * 5).filter(req => { return req.type === 'MediaSegment' && req._stream === type && req.trace.length > 1 && req._tfinish.getTime() - req.tresponse.getTime() > 0; }).slice(-lastCount); if (requestWindow.length === 0) { return 0; } const downloadLengths = requestWindow.map(req => getBytesLength(req) * 8); const downloadTimes = requestWindow.map(req => getTime(req) / 1000); const size = downloadLengths.reduce((a, b) => a + b, 0); const time = downloadTimes.reduce((a, b) => a + b, 0); return Math.round(size / time); } function caculateBandWidth(player) { return caculateBandWidthFor(player, 'video') + caculateBandWidthFor(player, 'audio'); } class DashPlayer extends index.CorePlayer { static setDefaultMediaPlayerFactory(factory) { DashPlayer._mediaPlayerFactory = factory; } constructor(video, source, fastSwitch = true, capLevelToPlayerSize = false) { super(video, source); _defineProperty__default["default"](this, "_mediaType", 'video'); _defineProperty__default["default"](this, "_currentLevelIndex", 0); _defineProperty__default["default"](this, "_initialized", false); this._fastSwitchEnabled = fastSwitch; this._dashPlayer = DashPlayer._mediaPlayerFactory.create(); this._dashPlayer.updateSettings({ streaming: { buffer: { fastSwitchEnabled: this._fastSwitchEnabled }, abr: { limitBitrateByPortal: capLevelToPlayerSize, usePixelRatioInLimitBitrateByPortal: capLevelToPlayerSize } } }); // debug error this.debugError(); this._register(common.toDisposable(() => this._dashPlayer.reset())); } debugError() { const onError = common.Event.fromNodeEventEmitter(this._dashPlayer, dashjs.MediaPlayer.events.ERROR); const onPlaybackError = common.Event.fromNodeEventEmitter(this._dashPlayer, dashjs.MediaPlayer.events.PLAYBACK_ERROR); this._register(onError(err => console.info(err))); this._register(onPlaybackError(err => console.info(err))); } get levels() { return this._initialized ? this._dashPlayer.getBitrateInfoListFor(this._mediaType) : []; } get currentLevel() { return this.levels[this._currentLevelIndex]; } get nextLevel() { return this._initialized ? this.levels[this._dashPlayer.getQualityFor(this._mediaType)] : undefined; } get autoQualityEnabled() { var _this$_dashPlayer$get, _this$_dashPlayer$get2; const autoSwitchBitrate = (_this$_dashPlayer$get = this._dashPlayer.getSettings().streaming) === null || _this$_dashPlayer$get === void 0 ? void 0 : (_this$_dashPlayer$get2 = _this$_dashPlayer$get.abr) === null || _this$_dashPlayer$get2 === void 0 ? void 0 : _this$_dashPlayer$get2.autoSwitchBitrate; if (autoSwitchBitrate) { return typeof autoSwitchBitrate[this._mediaType] === 'boolean' ? autoSwitchBitrate[this._mediaType] : true; } return true; } levelToQuality(bitrateInfo) { const level = { bitrate: bitrateInfo.bitrate, width: bitrateInfo.width, height: bitrateInfo.height, type: bitrateInfo.mediaType }; return level; } 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) { const dashPlayer = this._dashPlayer; dashPlayer.updateSettings({ streaming: { buffer: { fastSwitchEnabled: this._fastSwitchEnabled }, abr: { autoSwitchBitrate: { [this._mediaType]: auto } } } }); } setNextLevelIndex(index) { const dashPlayer = this._dashPlayer; if (index >= 0) { dashPlayer.setQualityFor(this._mediaType, index); } } onInit(video, source) { const dashPlayer = this._dashPlayer; dashPlayer.initialize(video, source.src, this.video.autoplay); this._initialized = true; this.log('onInit', 'initialized'); const disposables = this._register(new common.DisposableStore()); const onManifestParsed = common.Event.fromNodeEventEmitter(dashPlayer, dashjs.MediaPlayer.events.STREAM_INITIALIZED); const onLevelSwitched = common.Event.filter(common.Event.fromNodeEventEmitter(dashPlayer, dashjs.MediaPlayer.events.QUALITY_CHANGE_RENDERED), evt => evt.mediaType === this._mediaType); const onLevelSwitching = common.Event.filter(common.Event.fromNodeEventEmitter(dashPlayer, dashjs.MediaPlayer.events.QUALITY_CHANGE_REQUESTED), evt => evt.mediaType === this._mediaType); onManifestParsed(this.updatePlayList, this, disposables); onManifestParsed(this.setReady, this, disposables); onLevelSwitching(this.updateNextQualityLevel, this, disposables); onLevelSwitched(evt => { this._currentLevelIndex = evt.newQuality; this.updateQualityLevel(); }, null, disposables); } setInitialBitrate(bitrate) { const dashPlayer = this._dashPlayer; dashPlayer.updateSettings({ streaming: { buffer: { fastSwitchEnabled: this._fastSwitchEnabled }, abr: { initialBitrate: { [this._mediaType]: bitrate / 1000 } } } }); } setCapLevelToPlayerSize(capLevelToPlayerSize) { const dashPlayer = this._dashPlayer; dashPlayer.updateSettings({ streaming: { abr: { limitBitrateByPortal: capLevelToPlayerSize, usePixelRatioInLimitBitrateByPortal: capLevelToPlayerSize } } }); } get capLevelToPlayerSize() { var _this$_dashPlayer$get3, _this$_dashPlayer$get4, _this$_dashPlayer$get5; return (_this$_dashPlayer$get3 = (_this$_dashPlayer$get4 = this._dashPlayer.getSettings().streaming) === null || _this$_dashPlayer$get4 === void 0 ? void 0 : (_this$_dashPlayer$get5 = _this$_dashPlayer$get4.abr) === null || _this$_dashPlayer$get5 === void 0 ? void 0 : _this$_dashPlayer$get5.limitBitrateByPortal) !== null && _this$_dashPlayer$get3 !== void 0 ? _this$_dashPlayer$get3 : false; } get bandwidthEstimate() { return caculateBandWidth(this._dashPlayer); } get name() { return `DASHPlayer (${this._dashPlayer.getVersion()})`; } get supportAutoQuality() { return true; } } _defineProperty__default["default"](DashPlayer, "_mediaPlayerFactory", dashjs.MediaPlayer()); exports.DashPlayer = DashPlayer;