nsplayer
Version:
NSPlayer, a player which supports quality list of dash and hls
227 lines (177 loc) • 7.16 kB
JavaScript
var global = typeof self !== 'undefined' ? self : globalThis;
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import { toDisposable, Event, DisposableStore } from '@newstudios/common';
import { C as CorePlayer } from './index-ad2cdf19.js';
import { MediaPlayer } from 'dashjs';
import 'delegates';
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 CorePlayer {
static setDefaultMediaPlayerFactory(factory) {
DashPlayer._mediaPlayerFactory = factory;
}
constructor(video, source, fastSwitch = true, capLevelToPlayerSize = false) {
super(video, source);
_defineProperty(this, "_mediaType", 'video');
_defineProperty(this, "_currentLevelIndex", 0);
_defineProperty(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(toDisposable(() => this._dashPlayer.reset()));
}
debugError() {
const onError = Event.fromNodeEventEmitter(this._dashPlayer, MediaPlayer.events.ERROR);
const onPlaybackError = Event.fromNodeEventEmitter(this._dashPlayer, 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 DisposableStore());
const onManifestParsed = Event.fromNodeEventEmitter(dashPlayer, MediaPlayer.events.STREAM_INITIALIZED);
const onLevelSwitched = Event.filter(Event.fromNodeEventEmitter(dashPlayer, MediaPlayer.events.QUALITY_CHANGE_RENDERED), evt => evt.mediaType === this._mediaType);
const onLevelSwitching = Event.filter(Event.fromNodeEventEmitter(dashPlayer, 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(DashPlayer, "_mediaPlayerFactory", MediaPlayer());
export { DashPlayer };