xgplayer-mp4
Version:
xgplayer plugin for mp4 transform to fmp4
1,064 lines (1,063 loc) • 41.9 kB
JavaScript
import { inherits as _inherits, createSuper as _createSuper, createClass as _createClass, classCallCheck as _classCallCheck, defineProperty as _defineProperty, assertThisInitialized as _assertThisInitialized, objectSpread2 as _objectSpread2, asyncToGenerator as _asyncToGenerator, regeneratorRuntime as _regeneratorRuntime } from "./_virtual/_rollupPluginBabelHelpers.js";
import { BasePlugin, Events, Sniffer, Util, Errors } from "xgplayer";
import MP4, { MP4_EVENTS } from "./mp4.js";
import { ERROR_TYPES, ERROR_CODES } from "./error.js";
import { MSE } from "xgplayer-streaming-shared";
import util from "./util/index.js";
import Timer from "./util/timer.js";
import ProxyPromise from "./util/proxy-promise.js";
import { log } from "./util/logger.js";
var DESTROYED = "DESTROYED";
var _playerPlayNext = null;
var _playerStartInit2 = null;
var _playerChangeDefinition = null;
var _playerSwitchUrl = null;
var Mp4Plugin = /* @__PURE__ */ function(_BasePlugin) {
_inherits(Mp4Plugin2, _BasePlugin);
var _super = _createSuper(Mp4Plugin2);
function Mp4Plugin2(options) {
var _this;
_classCallCheck(this, Mp4Plugin2);
_this = _super.call(this, options);
_defineProperty(_assertThisInitialized(_this), "_onMp4DataCallBack", function() {
if (_this._isMseInit) {
_this._onTimeUpdate();
}
});
_defineProperty(_assertThisInitialized(_this), "_onMp4MetaReady", function(meta) {
var _assertThisInitialize = _assertThisInitialized(_this), config = _assertThisInitialize.config;
var isH265 = _this.mp4.checkCodecH265();
try {
if (isH265 && !_this.config.supportHevc) {
var message = "browser not support HEVC";
var _err = new Errors(_this.player, {
errorType: "runtime",
errorTypeCode: ERROR_TYPES.runtime,
errorCode: ERROR_CODES.h265Error,
errorMessage: message,
vid: config.vid,
mediaError: {
code: ERROR_CODES.h265Error,
message
}
});
_this._errorHandler(_err);
} else {
_this._initMse(meta);
_this._initPromise.resolve();
}
} catch (e) {
var _err2 = new Errors(_this.player, {
errorType: "runtime",
errorTypeCode: ERROR_TYPES.runtime,
errorCode: ERROR_CODES.mse,
errorMessage: e === null || e === void 0 ? void 0 : e.message,
vid: config.vid,
mediaError: {
code: ERROR_CODES.other1,
message: e === null || e === void 0 ? void 0 : e.message
}
});
_this._errorHandler(_err2);
return;
}
_this._loadData();
});
_defineProperty(_assertThisInitialized(_this), "_onMp4Error", function(err) {
var vid = _this.playerConfig.vid;
console.error("[Index] _onMp4Error", vid, err);
_this._errorHandler(err);
});
_defineProperty(_assertThisInitialized(_this), "_loadDataSuccess", function(data) {
if (_this.isDestroy || !_this.mse) {
return;
}
_this.log("[loadFragment] _loadDataSuccess ", JSON.stringify(data.context.range), ",dataLen,", data.buffer ? data.buffer.byteLength : 0, data.state);
try {
if (data.initSeg) {
_this._appendInitSeg(data.initSeg);
if (!data.buffer || data.buffer.byteLength < 1) {
_this.log("no data, must load data");
_this._onTimeUpdate();
}
}
var buffer = data.buffer, state = data.state, context = data.context;
if (_this.mse && state && (!buffer || buffer.byteLength <= 0) && context.fragIndex === _this.mp4.timeRange.length - 1) {
var buffered = _this.player.buffered;
if (buffered && buffered.length > 0) {
_this.bufferEndTime = buffered.end(buffered.length - 1);
}
_this._isEnded();
_this.log("loaded ended !!!==>>>", JSON.stringify(context.range), ", fragIndex,", context.fragIndex, ", bufferEndTime,", _this.bufferEndTime, ",meta_duration,", _this.mp4.meta.duration);
}
if (_this.mse && state && context.fragIndex === _this.mp4.timeRange.length - 1 && (!buffer || buffer.byteLength <= 0)) {
var _buffered = _this.player.buffered;
if (_buffered && _buffered.length > 0) {
_this.bufferEndTime = _buffered.end(_buffered.length - 1);
}
_this._isEnded();
_this.log("load ended !!!==>>>", _this.playerConfig.vid, JSON.stringify(context.range), ", fragIndex,", context.fragIndex, ", bufferEndTime,", _this.bufferEndTime, ",meta_duration,", _this.mp4.meta.duration);
}
if (buffer && _this.mse) {
if (buffer && buffer.byteLength > 0) {
_this._appendBuffer(MSE.VIDEO, buffer, context, state);
}
}
} catch (e) {
_this.log("appendBuffer error", e);
var _err = new Errors(_this.player, {
errorType: "runtime",
errorTypeCode: ERROR_TYPES.runtime,
errorCode: ERROR_CODES.mse,
vid: _this.player.config.vid,
errorMessage: e.message,
mediaError: {
code: ERROR_CODES.mse,
message: e.message
}
});
_this._errorHandler(_err);
}
if (data !== null && data !== void 0 && data.state) {
_this._onTimeUpdate();
}
});
_defineProperty(_assertThisInitialized(_this), "_onWaiting", function() {
var _assertThisInitialize2 = _assertThisInitialized(_this), player = _assertThisInitialize2.player, config = _assertThisInitialize2.config;
clearTimeout(_this._waitInBufferTimer);
_this._waitInBufferTimer = null;
var curTime = player.currentTime;
var buffer = player.bufferedPoint;
if (buffer.end > 0 && buffer.end - player.currentTime >= 2) {
if (_this._waitAdjustTimeCnt < config.waitJampBufferMaxCnt) {
_this._waitInBufferTimer = setTimeout(function() {
_this._waitAdjustTimeCnt++;
player.currentTime = player.currentTime + 0.5;
_this.log("[waitInBufferTimeout], waitAdjustTimeCnt,", _this._waitAdjustTimeCnt, ",curtime,", curTime, util.nowTime());
}, config.waitingInBufferTimeOut);
}
}
});
_defineProperty(_assertThisInitialized(_this), "_onSeeking", /* @__PURE__ */ _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee() {
var _assertThisInitialize3, player, mp4, curTime, buffered, hasBuffered, fragIndex, _assertThisInitialize4, mse, bufferList, bufferRange;
return _regeneratorRuntime().wrap(function _callee$(_context) {
while (1)
switch (_context.prev = _context.next) {
case 0:
_assertThisInitialize3 = _assertThisInitialized(_this), player = _assertThisInitialize3.player, mp4 = _assertThisInitialize3.mp4;
curTime = player.currentTime;
_this.log("[seekTime], curTime,", curTime, ",buffer,", player.buffered2.bufferedList);
if (!(!mp4 || !mp4.meta)) {
_context.next = 5;
break;
}
return _context.abrupt("return");
case 5:
_this.endofstream = false;
mp4.bufferLoadedPos = -1;
mp4._metaLoading = false;
buffered = player.bufferedPoint;
hasBuffered = false;
fragIndex = 0;
if (!(buffered.end > 0)) {
_context.next = 25;
break;
}
hasBuffered = true;
if (!(mp4.meta.duration - buffered.end < 0.5)) {
_context.next = 17;
break;
}
_this._startProgress();
_this.log("[seeking in buffered range], buffer end,", buffered.end, ", duration,", mp4.meta.duration);
return _context.abrupt("return");
case 17:
fragIndex = mp4.getFragmentIdx(buffered.end);
if (!(_this._curLoadSegmentIdx === fragIndex)) {
_context.next = 22;
break;
}
_this._startProgress();
_this.log("[seeking in buffered range], seek fragIndex is current load segmentIdx", fragIndex);
return _context.abrupt("return");
case 22:
mp4.seekTime = buffered.end;
fragIndex < 0 && (fragIndex = _this._curLoadSegmentIdx);
_this.log("[seeking in buffered range], seekTime ", curTime, ",bufferRange,", buffered.start, "-", buffered.end, ", fragIndex,", fragIndex);
case 25:
if (!hasBuffered) {
mp4.seekTime = curTime;
fragIndex = mp4.getFragmentIdx(curTime);
fragIndex < 0 && (fragIndex = _this._curLoadSegmentIdx);
_this.log("[seekTime out buffer range], curTime,", curTime, ", Idx,", fragIndex);
_assertThisInitialize4 = _assertThisInitialized(_this), mse = _assertThisInitialize4.mse;
if (mse && mse.isFull()) {
bufferList = player.buffered2.bufferedList;
bufferRange = bufferList[bufferList.length - 1];
mse.clearOpQueues(MSE.VIDEO);
_this._checkRemoveSourceBuffer([bufferRange.start, bufferRange.end], player.currentTime, true, true);
}
}
_context.next = 28;
return mp4.cancelLoading();
case 28:
mp4.resetFragmentLoadState(fragIndex);
_this._curLoadSegmentIdx = fragIndex;
_this._onTimeUpdate();
_this._startProgress();
_this._isEnded();
case 33:
case "end":
return _context.stop();
}
}, _callee);
})));
_defineProperty(_assertThisInitialized(_this), "changeDefineCanPlay", function(currentTime, paused, from, to) {
var _assertThisInitialize5 = _assertThisInitialized(_this), player = _assertThisInitialize5.player;
if (player.ended) {
player.currentTime = 0;
return;
}
_this.log("[oldChangeDefinition],this._changeDefState,", _this._changeDefState);
player.currentTime = _this._changeDefState ? _this._changeDefState.currentTime : currentTime;
var isPause = _this._changeDefState ? _this._changeDefState.paused : paused;
if (isPause) {
player.pause();
} else {
player.play();
}
_this._changeDefState = null;
player.emit(Events.AFTER_DEFINITION_CHANGE, {
from,
to
});
});
_defineProperty(_assertThisInitialized(_this), "changeDefinition", /* @__PURE__ */ function() {
var _ref2 = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee2(to, from) {
var _assertThisInitialize6, player, config, mp4, timeStart, fragIndex, buffered;
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
while (1)
switch (_context2.prev = _context2.next) {
case 0:
_assertThisInitialize6 = _assertThisInitialized(_this), player = _assertThisInitialize6.player, config = _assertThisInitialize6.config, mp4 = _assertThisInitialize6.mp4;
if (!from) {
from = player.curDefinition;
}
_this._MSEError = false;
if (!config.witchBitRateWay) {
_context2.next = 6;
break;
}
_this.oldChangeDefinition(to, from);
return _context2.abrupt("return");
case 6:
player.emit(Events.DEFINITION_CHANGE, {
from,
to
});
timeStart = player.currentTime;
fragIndex = mp4.getFragmentIdx(timeStart);
fragIndex < 0 && (fragIndex = _this._curLoadSegmentIdx);
_this.log("switchBitrate:point,fragIndex,", fragIndex, ",startTime,", mp4.timeRange[fragIndex].startTime, ",currentTime,", player.currentTime);
if (!mp4) {
_context2.next = 16;
break;
}
_this.mp4.changeBitRateTime = timeStart;
_context2.next = 15;
return mp4.cancelLoading();
case 15:
mp4._metaLoading && (mp4._metaLoading = false);
case 16:
_this._removeBuffeEndTime = mp4.timeRange[fragIndex].startTime;
_this._isChangeDefinition = true;
buffered = player.getBufferedRange(player.buffered);
if (buffered[1] > 0 && buffered[1] - player.currentTime > 5) {
_this.mse.clearOpQueues(MSE.VIDEO);
_this.mse.remove(MSE.VIDEO, player.currentTime + 5, buffered[1]);
}
_this.log("switchBitrate: resetFragmentLoadState,", fragIndex);
mp4.resetFragmentLoadState(fragIndex);
_this._curLoadSegmentIdx = fragIndex;
_context2.next = 25;
return _this.mp4.changeBitRate(to);
case 25:
_this._onTimeUpdate();
player.emit("RESOLUTION_UPDATE", to);
case 27:
case "end":
return _context2.stop();
}
}, _callee2);
}));
return function(_x, _x2) {
return _ref2.apply(this, arguments);
};
}());
_defineProperty(_assertThisInitialized(_this), "_replayHook", function() {
var _this$player;
(_this$player = _this.player) === null || _this$player === void 0 ? void 0 : _this$player.play();
return false;
});
_defineProperty(_assertThisInitialized(_this), "_retryHook", function() {
_this.beforePlayerInit();
return false;
});
_this.mp4 = null;
_this.mse = null;
_this._waitAdjustTimeCnt = 0;
_this._lastCheckTime = util.nowTime();
_this._removeBuffeEndTime = 0;
_this._pendingPromises = [];
return _this;
}
_createClass(Mp4Plugin2, [{
key: "afterCreate",
value: function afterCreate() {
var _this2 = this;
window.__mp4player = this;
try {
BasePlugin.defineGetterOrSetter(this.player, {
__url: {
get: function get() {
try {
return _this2.mse ? _this2.mse.url : _this2.config.url;
} catch (error) {
return null;
}
}
}
});
} catch (e) {
}
this._proxyPlayer();
}
}, {
key: "attachEvents",
value: function attachEvents() {
this.off(Events.SEEKING, this._onSeeking);
this.on(Events.SEEKING, this._onSeeking);
this.on(Events.WAITING, this._onWaiting);
this.off(Events.URL_CHANGE, this.switchURL);
this.on(Events.URL_CHANGE, this.switchURL);
}
}, {
key: "detachEvents",
value: function detachEvents() {
this.off(Events.SEEKING, this._onSeeking);
this.off(Events.WAITING, this._onWaiting);
this.off(Events.URL_CHANGE, this.switchURL);
}
}, {
key: "_proxyPlayer",
value: function _proxyPlayer() {
var _this3 = this;
if (typeof this.player.playNext === "function") {
_playerPlayNext = this.player.playNext;
}
this.player.playNext = function() {
_this3.playNext.apply(_this3, arguments);
};
_playerStartInit2 = this.player._startInit;
_playerSwitchUrl = this.player.switchURL;
_playerChangeDefinition = this.player.changeDefinition;
this.player._startInit = this._playerStartInit.bind(this);
this.player.switchURL = this.switchURL.bind(this);
this.player.changeDefinition = this.changeDefinition.bind(this);
this.player.removeHooks("replay", this._replayHook);
this.player.removeHooks("retry", this._retryHook);
}
}, {
key: "_playerStartInit",
value: function _playerStartInit(url) {
var _this4 = this;
var config = this.config, playerConfig = this.playerConfig;
if (config.supportHevc === void 0) {
if (Sniffer !== null && Sniffer !== void 0 && Sniffer.isHevcSupported && Sniffer.isHevcSupported()) {
config.supportHevc = true;
}
}
var ret = this.initMp4();
this._initPromise = ret;
this._addPendingPromise(this._initPromise);
if (this.mse && Util.typeOf(url) === "String" && /^blob/.test(url) && url !== this.mse.url) {
url = playerConfig.url;
}
ret.then(function() {
if (_this4.mse) {
url = _this4.mse.url;
}
_this4.attachEvents();
_this4._startProgress();
}).catch(function(e) {
var isBreak = _this4._initPromise ? _this4._initPromise.isBreak : false;
if (_this4.isDestroy || isBreak) {
return;
}
var err = e;
if (!err.errorCode) {
err = new Errors(_this4.player, {
errorType: ERROR_TYPES.RUNTIME,
errorCode: (e === null || e === void 0 ? void 0 : e.errorCode) || ERROR_CODES.other,
vid: _this4.playerConfig.vid,
errorMessage: (e === null || e === void 0 ? void 0 : e.errorMessage) || (e === null || e === void 0 ? void 0 : e.message),
mediaError: {
code: (e === null || e === void 0 ? void 0 : e.httpCode) || ERROR_CODES.other,
message: (e === null || e === void 0 ? void 0 : e.errorMessage) || (e === null || e === void 0 ? void 0 : e.message),
errorType: e === null || e === void 0 ? void 0 : e.errorType
}
});
err.url = url;
}
_this4.useVideoLoad = true;
_this4.player.vtype = "MP4_1";
_this4.player.emit("playCatch", _this4.player.vtype, err);
}).finally(function() {
if (!_this4._initPromise) {
return;
}
var isBreak = _this4._initPromise.isBreak;
if (isBreak) {
return;
}
_this4._initPromise && _this4._removePendingPromise(_this4._initPromise);
_this4._initPromise = null;
!_this4.isDestroy && !isBreak && _playerStartInit2.call(_this4.player, url);
});
}
}, {
key: "initMp4",
value: function initMp4() {
var _this5 = this;
var player = this.player;
if (!player.config.vid) {
player.config.vid = Date.now();
}
var _promise = new ProxyPromise();
if (this.mp4) {
this.mp4.off(MP4_EVENTS.META_READY, this._onMp4MetaReady);
this.mp4.off(MP4_EVENTS.ERROR, this._onMp4Error);
this.mp4.off(MP4_EVENTS.MOOV_REQ_PROGRESS, this._onMp4DataCallBack);
this.mp4.destroy();
this.mp4 = null;
}
this.mp4 = new MP4(player.config.url, _objectSpread2(_objectSpread2({}, this.config), {}, {
vid: player.config.vid
}));
this.mp4.on(MP4_EVENTS.META_READY, this._onMp4MetaReady);
this.mp4.on(MP4_EVENTS.ERROR, this._onMp4Error);
this.mp4.on(MP4_EVENTS.MOOV_REQ_PROGRESS, this._onMp4DataCallBack);
this.mp4.on(MP4_EVENTS.UPDATE_LOAD_IDX, function(fragment) {
_this5._curLoadSegmentIdx = fragment;
_this5.log("[update curLoadSegmentIdx]", fragment);
});
this.mp4.init();
return _promise;
}
}, {
key: "setConfig",
value: function setConfig(newConfig) {
this.config = Object.assign(this.config, newConfig);
}
}, {
key: "playNext",
value: function playNext(newConfig) {
var player = this.player;
this._defInited = false;
player.resetState();
player._currentTime = 0;
player._duration = 0;
player.isPlaying = false;
this._MSEError = false;
player.pause();
this._reset();
player.setConfig(newConfig);
this.log("[Index] playNext", newConfig);
player.play();
this.emit("playnext");
}
}, {
key: "checkDegrade",
value: function checkDegrade(error) {
var closeDowngrade = this.config.closeDowngrade;
return !closeDowngrade || error.httpCode === "networkError";
}
}, {
key: "_errorHandler",
value: function _errorHandler(err) {
var _this$mp;
var player = this.player, config = this.config;
if (!player || this.useVideoLoad) {
return;
}
if (!err.url && (_this$mp = this.mp4) !== null && _this$mp !== void 0 && _this$mp.url) {
err.url = this.mp4.url;
}
var preState = player.paused;
console.error("final error !!!!, ", config.vid, err);
this.player.vtype = "MP4_2";
this.player.emit("playCatch", this.player.vtype, err);
var isDegrade = this.checkDegrade(err);
if (isDegrade) {
if (this._initPromise) {
this._removeAndRejectInitPromise(err);
} else {
this._startDegradedPlayback(err, preState);
}
} else {
this.player.pause();
this._reset();
var currentTime = player.currentTime;
this.destroyMSE();
player.currentTime = currentTime;
this.emit("error", err);
}
}
}, {
key: "_startDegradedPlayback",
value: function _startDegradedPlayback(err, preState) {
var _this6 = this;
console.log(">>>_startDegradedPlayback");
var player = this.player, playerConfig = this.playerConfig;
this.useVideoLoad = true;
this.destroyMSE();
this._currentTime = player.currentTime;
this.__onmetadataHandle = function() {
if (_this6._currentTime) {
player.currentTime = _this6._currentTime;
}
if (preState) {
_this6.player.pause();
} else {
_this6.player.play();
}
player.media.removeEventListener("loadedmetadata", _this6.__onmetadataHandle);
_this6.__onmetadataHandle = null;
};
player.media.addEventListener("loadedmetadata", this.__onmetadataHandle);
var _url = playerConfig.url;
player.media.src = _url;
}
}, {
key: "_addPendingPromise",
value: function _addPendingPromise(p) {
this._pendingPromises.push(p);
}
}, {
key: "_removePendingPromise",
value: function _removePendingPromise(p) {
var idx = this._pendingPromises.indexOf(p);
if (idx > -1) {
this._pendingPromises.splice(idx, 1);
}
}
}, {
key: "_cancelPendingPromises",
value: function _cancelPendingPromises() {
if (this._pendingPromises.length > 0) {
this._pendingPromises.forEach(function(promise) {
promise.reject(DESTROYED);
});
}
this._pendingPromises = [];
}
}, {
key: "_removeAndRejectInitPromise",
value: function _removeAndRejectInitPromise(error) {
if (this._initPromise) {
this._removePendingPromise(this._initPromise);
this._initPromise.reject(error);
}
}
}, {
key: "_initMse",
value: function() {
var _initMse2 = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee3(meta) {
var _this7 = this;
var hasVideo, hasAudio, codec, contentTypes, openPromise;
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
while (1)
switch (_context3.prev = _context3.next) {
case 0:
if (!this.mse) {
_context3.next = 4;
break;
}
_context3.next = 3;
return this.mse.unbindMedia();
case 3:
this.mse = null;
case 4:
hasVideo = !!meta.videoCodec;
hasAudio = !!meta.audioCodec;
if (hasVideo && hasAudio) {
codec = 'video/mp4; codecs="'.concat(meta.videoCodec, ', mp4a.40.5"');
} else if (hasVideo) {
codec = 'video/mp4; codecs="'.concat(meta.videoCodec, '"');
} else {
codec = 'video/mp4; codecs="mp4a.40.5"';
}
contentTypes = _defineProperty({}, MSE.VIDEO, {
mimeType: "video/mp4",
codec
});
this.mse = new MSE(null, {
preferMMS: this.config.preferMMS
});
openPromise = this.mse.bindMedia(this.player.video);
openPromise.then(function() {
var contentTypesLocal = Object.keys(contentTypes);
try {
for (var i = 0; i < contentTypesLocal.length; i++) {
var type = contentTypesLocal[i];
_this7.mse.createSource(type, contentTypes[type].codec);
}
} catch (e) {
console.error("MSE error: ", e);
_this7._errorHandler(e);
}
_this7._isMseInit = true;
_this7._onTimeUpdate();
});
case 11:
case "end":
return _context3.stop();
}
}, _callee3, this);
}));
function _initMse(_x3) {
return _initMse2.apply(this, arguments);
}
return _initMse;
}()
}, {
key: "destroyMSE",
value: function() {
var _destroyMSE = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee4() {
var _this$mse;
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
while (1)
switch (_context4.prev = _context4.next) {
case 0:
_context4.next = 2;
return (_this$mse = this.mse) === null || _this$mse === void 0 ? void 0 : _this$mse.unbindMedia();
case 2:
this.mse = null;
case 3:
case "end":
return _context4.stop();
}
}, _callee4, this);
}));
function destroyMSE() {
return _destroyMSE.apply(this, arguments);
}
return destroyMSE;
}()
}, {
key: "_onTimeUpdate",
value: function _onTimeUpdate() {
var _this8 = this;
var mse = this.mse, mp4 = this.mp4, player = this.player, config = this.config;
if (!mp4)
return;
var timeRange = mp4.timeRange;
var range = player.getBufferedRange(player.buffered2);
if (mse && mp4 && mp4.canDownload) {
if (util.nowTime() - this._lastCheckTime > 1e3) {
this._lastCheckTime = util.nowTime();
this._loadStuckCheck();
this._checkRemoveSourceBuffer(range, player.currentTime);
}
var cacheMaxTime = player.paused ? player.currentTime + config.minBufferLength : player.currentTime + config.maxBufferLength;
if (range[1] - cacheMaxTime < 0) {
timeRange.every(function(item, idx) {
if (item.downloaded) {
return true;
}
if (!_this8._isChangeDefinition && item.endTime - item.startTime > 1 && _this8._isInBuffer(item)) {
item.downloaded = true;
item.isLoading = true;
_this8.log("onTimeUpdate, ".concat(idx, " download segment, has buffer"), item.startTime, item.endTime);
return true;
}
if (item.startTime - player.currentTime < config.maxBufferLength) {
_this8._curLoadSegmentIdx = idx;
_this8.log("[onTimeUpdate],load index==>>>, ", idx, ",IdxTimeRange, ", item.startTime, "-", item.endTime, ",buffEnd, ", range[1], ",playCurTime,", player.currentTime, ", bufferLen,", range[1] - player.currentTime, ",bufferRangeList,", _this8.player.buffered2 ? _this8.player.buffered2.bufferedList : null);
_this8._loadData();
}
});
}
this._isEnded();
}
this.checkRemoveOldBitrateBuffer();
}
}, {
key: "checkRemoveOldBitrateBuffer",
value: function checkRemoveOldBitrateBuffer() {
var mse = this.mse, player = this.player;
if (mse && this._removeBuffeEndTime > 0 && player.currentTime > this._removeBuffeEndTime + 1) {
this.log("remove old bitrate buffer", this._removeBuffeEndTime);
mse.remove(MSE.VIDEO, 0, this._removeBuffeEndTime - 1);
this._removeBuffeEndTime = 0;
}
}
}, {
key: "_isInBuffer",
value: function _isInBuffer(item) {
var gap = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0;
var inbuffer = false;
var buffered = this.player.video.buffered;
for (var i = 0; i < buffered.length; i++) {
var start = buffered.start(i) - gap;
var end = buffered.end(i) + gap;
if (start <= item.startTime && item.endTime <= end) {
inbuffer = true;
break;
}
}
return inbuffer;
}
}, {
key: "_loadData",
value: function() {
var _loadData2 = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee5() {
return _regeneratorRuntime().wrap(function _callee5$(_context5) {
while (1)
switch (_context5.prev = _context5.next) {
case 0:
if (!(!this.mp4 || !this._isMseInit)) {
_context5.next = 3;
break;
}
this.log("loadData, player.mp4 null", this._isMseInit);
return _context5.abrupt("return");
case 3:
_context5.prev = 3;
_context5.next = 6;
return this.mp4.load(this._curLoadSegmentIdx, this._loadDataSuccess);
case 6:
_context5.next = 11;
break;
case 8:
_context5.prev = 8;
_context5.t0 = _context5["catch"](3);
console.error("[Index] _loadData error", this.playerConfig.vid, _context5.t0);
case 11:
case "end":
return _context5.stop();
}
}, _callee5, this, [[3, 8]]);
}));
function _loadData() {
return _loadData2.apply(this, arguments);
}
return _loadData;
}()
}, {
key: "_appendInitSeg",
value: function _appendInitSeg(initSeg) {
var _this9 = this;
if (!this.mp4 || !this.mse)
return;
this.mse.append(MSE.VIDEO, initSeg, {
vid: this.playerConfig.vid,
range: null,
dataLen: initSeg.byteLength,
isinit: true
}).then(function(data) {
_this9.log("appendInitSeg end ==>>>", data === null || data === void 0 ? void 0 : data.context, " costTime,", data === null || data === void 0 ? void 0 : data.costtime);
});
}
}, {
key: "_appendBuffer",
value: function _appendBuffer(codec, buffer) {
var _this10 = this;
var context = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {};
var state = arguments.length > 3 ? arguments[3] : void 0;
var mse = this.mse, config = this.config;
mse.append(codec, buffer, {
vid: config.vid,
fragIndex: context.fragIndex,
range: context.range,
dataLen: buffer.byteLength,
state
}).then(function(data) {
_this10.log("player appendBuffer end ==>>>", data.context ? data.context : null, ", costTime,", data.costtime, ", opt,", data.name, ",bufferRange,", _this10.player.getBufferedRange());
if (_this10.mse && context.state && context.fragIndex === _this10.mp4.timeRange.length - 1) {
var buffered = _this10.player.buffered;
if (buffered && buffered.length > 0) {
_this10.bufferEndTime = buffered.end(buffered.length - 1);
}
_this10._isEnded();
_this10.log("loaded ended !!!==>>>", context.range, ", fragIndex,", context.fragIndex, ", bufferEndTime,", _this10.bufferEndTime, ",meta_duration,", _this10.mp4.meta.duration);
}
}).catch(function(error) {
console.log("[MSE error]", error);
if (error && mse !== null && mse !== void 0 && mse.isFull()) {
var bufferRange = _this10.player.getBufferedRange(_this10.player.buffered2);
_this10._checkRemoveSourceBuffer(bufferRange, _this10.player.currentTime, true);
}
});
}
}, {
key: "_checkRemoveSourceBuffer",
value: function _checkRemoveSourceBuffer(sourceBufferRange, currentTime, mustClear) {
var _this11 = this;
var mse = this.mse, mp4 = this.mp4, player = this.player;
if (!mse || !mp4 || !player)
return;
if (mustClear) {
clearTimeout(this._removeBufferTimer);
this._removeBufferTimer = null;
}
if (!sourceBufferRange)
sourceBufferRange = player.getBufferedRange(player.buffered2);
if (!currentTime)
currentTime = player.currentTime;
if (!mustClear && util.nowTime() - this._checkRemoveBufferLastTime <= this.config.removeBufferLen || this.endofstream)
return;
this._checkRemoveBufferLastTime = util.nowTime();
if (sourceBufferRange && sourceBufferRange[0] >= 0 && (currentTime - sourceBufferRange[0] > this.config.removeBufferLen || mse.isFull())) {
var time = sourceBufferRange[1];
var segmentIdx = mp4.getFragmentIdx(time);
if (segmentIdx >= 0 && mp4.timeRange[segmentIdx].startTime < currentTime) {
var clearEnd = Math.floor(Math.min(mp4.timeRange[segmentIdx].startTime, sourceBufferRange[1]));
if (sourceBufferRange[0] < clearEnd) {
this.log("[checkremoveSourceBuffer], remove range==>>>", sourceBufferRange[0], clearEnd);
mse.remove(MSE.VIDEO, sourceBufferRange[0], clearEnd);
} else if (mse.isFull() && !this._removeBufferTimer) {
this._removeBufferTimer = setTimeout(function() {
_this11._checkRemoveSourceBuffer(null, null, true);
}, 10 * 1e3);
}
}
}
}
}, {
key: "_isEnded",
value: function _isEnded() {
var player = this.player, mp4 = this.mp4;
var buffered = player.bufferedPoint;
var _end = buffered ? buffered.end : 0;
if (!this.endofstream && this.mse && mp4.meta.duration - player.currentTime < 0.5) {
this.log("[check player isEnded],deal mse.endOfStream, currentTime,", player.currentTime, ", bufferend,", _end, ", duration,", mp4.meta.duration);
this.endofstream = true;
this.mse.endOfStream();
}
if (mp4 && mp4.meta && mp4.meta.duration - player.currentTime < 0.5) {
this._stopProgress();
this.log("[check player isEnded],stopProgress and endOfStream,currentTime, ", player.currentTime, ", bufferend,", _end, ", duration,", mp4.meta.duration);
this.mse && this.mse.endOfStream();
return true;
}
return false;
}
}, {
key: "switchURL",
value: function switchURL(definitionInfo) {
this.changeDefinition(definitionInfo);
}
}, {
key: "oldChangeDefinition",
value: function oldChangeDefinition(to, from) {
var _this12 = this;
var config = this.config, player = this.player;
this.log("[oldChangeDefinition],currentTime,", player.currentTime, ",from,", from, ",to,", to);
var currentTime = player.currentTime, paused = player.paused;
if (!this._changeDefState) {
this._changeDefState = {
currentTime,
paused
};
this.log("[oldChangeDefinition],currentTime,", player.currentTime, ",pause,", paused);
}
player.config.url = to.url;
config.focusUserDefinition = true;
player.currentTime = 0;
player.pause();
this._reset();
this._isMseInit = false;
this._changeDefineCanPlay && player.off("canplay", this._changeDefineCanPlay);
this._changeDefineCanPlay = function() {
_this12.changeDefineCanPlay(currentTime, paused, from, to);
_this12._changeDefineCanPlay = null;
};
player.once("canplay", this._changeDefineCanPlay);
this.player.video.load();
this.initMp4();
}
}, {
key: "_loadStuckCheck",
value: function _loadStuckCheck() {
var _this13 = this;
var config = this.config, player = this.player;
if (!config.disableBufferBreakCheck) {
if (player.currentTime - (this._lastCurrentTime || 0) > 0.1 || player.paused) {
if (this._bufferBreakFlag === 1 || this._bufferBreakFlag === 2) {
this.log("\u89C6\u9891\u6CA1\u6709\u5361\u6B7B,\u91CD\u7F6E\u5361\u6B7B\u6807\u8BB0");
this._bufferBreakFlag = 0;
clearTimeout(this._bufferBreakTimer);
this._bufferBreakFlag = null;
}
} else {
if (!this._bufferBreakFlag) {
this._bufferBreakFlag = 1;
this.log("\u5361\u6B7B\u8BA1\u65F6\u5F00\u59CB! \u6301\u7EED".concat(config.waitingTimeOut, "\u6BEB\u79D2\u5219\u786E\u8BA4\u5361\u6B7B"));
this._bufferBreakTimer = setTimeout(function() {
if (_this13.isDestroy) {
return;
}
if (_this13._bufferBreakFlag === 1) {
_this13._bufferBreakFlag = 2;
_this13.log("\u786E\u8BA4\u5361\u6B7B!!!");
_this13._errorHandler(new Errors(_this13.player, {
errorType: "runtime",
errorTypeCode: ERROR_TYPES.runtime,
errorCode: ERROR_CODES.waitTimeout,
errorMessage: "wait_timeout",
vid: config.vid
}));
}
_this13._bufferBreakTimer = null;
}, config.waitingTimeOut);
}
}
this._lastCurrentTime = player.currentTime;
}
}
}, {
key: "isDestroy",
get: function get() {
return !this.player;
}
}, {
key: "_stopProgress",
value: function _stopProgress() {
this._hasStartProgress = false;
if (this._requestTimer) {
this._requestTimer.stop();
this._requestTimer = null;
}
if (this._bufferBreakTimer) {
clearTimeout(this._bufferBreakTimer);
this._bufferBreakTimer = null;
this._bufferBreakFlag = void 0;
}
}
}, {
key: "_startProgress",
value: function _startProgress() {
var _this14 = this;
if (this._hasStartProgress) {
return;
}
this._stopProgress();
this._requestTimer = new Timer(function() {
if (_this14._requestTimer) {
_this14._onTimeUpdate();
}
});
this._requestTimer.tickEvery(this.config.tickInSeconds);
this._hasStartProgress = true;
}
}, {
key: "log",
value: function log$1(message) {
var playerConfig = this.playerConfig;
var newMessage = playerConfig && playerConfig.vid ? "[Index]".concat(playerConfig.vid, " ").concat(message) : "[Index] ".concat(message);
for (var _len = arguments.length, optionalParams = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
optionalParams[_key - 1] = arguments[_key];
}
log.apply(void 0, [newMessage].concat(optionalParams));
}
}, {
key: "_reset",
value: function _reset() {
this._isMseInit = false;
this.endofstream = false;
this._curLoadSegmentIdx = 0;
this._removeBuffeEndTime = 0;
this._isChangeDefinition = false;
this._stopProgress();
if (this.mp4) {
this.mp4.off(MP4_EVENTS.META_READY, this._onMp4MetaReady);
this.mp4.off(MP4_EVENTS.ERROR, this._onMp4Error);
this.mp4.off(MP4_EVENTS.MOOV_REQ_PROGRESS, this._onMp4DataCallBack);
this.mp4.destroy();
this.mp4 = null;
}
if (this.mse) {
this.mse.unbindMedia();
this.mse = null;
}
this._unloadVideo();
}
}, {
key: "_unloadVideo",
value: function _unloadVideo() {
var player = this.player;
try {
this.log("unloadVideo src ".concat(player.video.src));
if (player.video && player.video.src) {
player.video.removeAttribute("src");
player.video.load();
}
} catch (error) {
this.log("unloadVideo error", error);
}
}
}, {
key: "destroy",
value: function destroy() {
var player = this.player;
player.removeHooks("replay", this._replayHook);
player.removeHooks("retry", this._retryHook);
this.detachEvents();
this._reset();
this.player.playNext = _playerPlayNext;
this.player._startInit = _playerStartInit2;
this.player.changeDefinition = _playerChangeDefinition;
this.player.switchURL = _playerSwitchUrl;
if (this._bufferBreakTimer) {
clearInterval(this._bufferBreakTimer);
}
if (this._removeBufferTimer) {
clearTimeout(this._removeBufferTimer);
this._removeBufferTimer = null;
}
if (this._waitInBufferTimer) {
clearTimeout(this._waitInBufferTimer);
this._waitInBufferTimer = null;
}
}
}], [{
key: "pluginName",
get: function get() {
return "mp4Plugin";
}
}, {
key: "defaultConfig",
get: function get() {
return {
maxBufferLength: 40,
minBufferLength: 5,
disableBufferBreakCheck: false,
waitingTimeOut: 15e3,
waitingInBufferTimeOut: 5e3,
waitJampBufferMaxCnt: 3,
tickInSeconds: 0.1,
reqOptions: null,
closeDowngrade: false,
preferMMS: false
};
}
}, {
key: "version",
get: function get() {
return "3.0.21";
}
}]);
return Mp4Plugin2;
}(BasePlugin);
export { Mp4Plugin as default };