xgplayer-mp4
Version:
xgplayer plugin for mp4 transform to fmp4
903 lines (902 loc) • 37.7 kB
JavaScript
import { inherits as _inherits, createSuper as _createSuper, classCallCheck as _classCallCheck, defineProperty as _defineProperty, assertThisInitialized as _assertThisInitialized, objectSpread2 as _objectSpread2, createClass as _createClass, asyncToGenerator as _asyncToGenerator, regeneratorRuntime as _regeneratorRuntime } from "./_virtual/_rollupPluginBabelHelpers.js";
import EventEmitter from "eventemitter3";
import Concat from "concat-typed-array";
import { FMP4Demuxer, MP4Demuxer, FMP4Remuxer } from "xgplayer-transmuxer";
import { ParserError, ERROR_TYPES, ERROR_CODES, NetWorkError } from "./error.js";
import util from "./util/index.js";
import MP4Loader from "xgplayer-mp4-loader";
import { checkOpenLog, log } from "./util/logger.js";
import TransmuxerWorkerControl from "./worker/index.js";
var MP4_EVENTS = {
ERROR: "error",
META_READY: "metaReady",
MOOV_REQ_PROGRESS: "moov_request_Progress",
UPDATE_LOAD_IDX: "update_load_fragmentIdx"
};
var MP4 = /* @__PURE__ */ function(_EventEmitter) {
_inherits(MP42, _EventEmitter);
var _super = _createSuper(MP42);
function MP42(url, _options) {
var _this;
_classCallCheck(this, MP42);
_this = _super.call(this);
_defineProperty(_assertThisInitialized(_this), "onprogressDataArrive", /* @__PURE__ */ function() {
var _ref = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee(data, state, options) {
var curSegRange;
return _regeneratorRuntime().wrap(function _callee$(_context) {
while (1)
switch (_context.prev = _context.next) {
case 0:
if (data && data.byteLength > 0) {
curSegRange = _this.timeRange[options.index].range;
if (curSegRange && options.range[1] >= curSegRange[1] && !state) {
state = true;
}
_this.log("[mp4.loadFragment onprogressDataArrive ] receive data, >>> index,", options.index, ",range,", JSON.stringify(options.range), ", dataLen,", data.byteLength);
_this._mux(data, options.range[0], options.index, state);
}
if (state) {
_this.timeRange[options.index].downloaded = true;
_this.bufferLoadedPos = -1;
_this.log("[FragLoadDowned],fragmentIdx,", options.index, ",rangeEnd,", options.range[1]);
}
case 2:
case "end":
return _context.stop();
}
}, _callee);
}));
return function(_x, _x2, _x3) {
return _ref.apply(this, arguments);
};
}());
_this.url = url;
_this.options = MP42.getDefaultConfig();
Object.keys(_options).map(function(key) {
_options[key] !== void 0 && _options[key] !== null && (_this.options[key] = _options[key]);
});
_this.timeRange = [];
_this.CHUNK_SIZE = _this.options.chunkSize;
_this.bufferLoaded = new Uint8Array(0);
_this.bufferLoadedPos = 0;
_this.meta = null;
_this.videoTrak = null;
_this.audioTrak = null;
_this.canDownload = true;
_this._loadSuccessCallBack = null;
_this._isPending = false;
_this._metaLoading = false;
_this.MP4Loader = new MP4Loader(_objectSpread2(_objectSpread2({
segmentDuration: _this.options.segmentDuration,
url,
vid: _options.vid,
retry: _this.options.retryCount,
retryDelay: _this.options.retryDelay,
timeout: _this.options.timeout
}, _options.reqOptions), {}, {
preferMMS: _this.options.preferMMS,
openLog: checkOpenLog()
}));
_this.fMP4Demuxer = null;
_this.MP4Demuxer = null;
_this.FMP4Remuxer = null;
_this._needInitSegment = true;
_this._switchBitRate = false;
_this.enableWorker = _this.options.enableWorker;
if (_this.enableWorker && typeof Worker !== "undefined") {
try {
_this.workerSequence = 0;
_this.transmuxerWorkerControl = new TransmuxerWorkerControl({
id: _this.workerSequence,
codecType: _options.codecType,
supportHevc: _this.options.supportHevc,
openLog: checkOpenLog()
});
_this.transmuxerWorkerControl.on("transmux", function(muxRes) {
var res = muxRes.args;
_this.log("[transmuxerworker end] ,range, ", JSON.stringify(res.range), ",dataLen,", res.buffer.byteLength, res.context);
_this._loadSuccessCallBack && _this._loadSuccessCallBack(res);
});
} catch (error) {
_this.log("Error in worker:", error);
_this.enableWorker = false;
_this.transmuxerWorkerControl = null;
}
}
if (!_this.enableWorker) {
_this.MP4Demuxer = null;
_this.FMP4Remuxer = null;
}
_this.seekTime = -1;
_this.changeBitRateTime = -1;
return _this;
}
_createClass(MP42, [{
key: "changeBitRate",
value: function() {
var _changeBitRate = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee2(bitRateInfo) {
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
while (1)
switch (_context2.prev = _context2.next) {
case 0:
this.url = bitRateInfo.url;
_context2.next = 3;
return this.MP4Loader.changeUrl(this.url, this.options.vid + Date.now(), this.CHUNK_SIZE);
case 3:
this._switchBitRate = true;
this.log("[switchBitrate] changeUrl, bitRate,", this.url);
case 5:
case "end":
return _context2.stop();
}
}, _callee2, this);
}));
function changeBitRate(_x4) {
return _changeBitRate.apply(this, arguments);
}
return changeBitRate;
}()
}, {
key: "log",
value: function log$1(message) {
var options = this.options;
var newMessage = options && options.vid ? "[MP4] ".concat(options.vid, " ").concat(message) : "[MP4] ".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: "errorHandler",
value: function() {
var _errorHandler = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee3(error, state) {
var response, message, vid, _error;
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
while (1)
switch (_context3.prev = _context3.next) {
case 0:
response = error.response, message = error.message;
vid = this.options ? this.options.vid : "";
_error = null;
this._isPending = true;
if (response) {
_error = new NetWorkError("network", response.status, {
httpText: response.httpText,
message,
url: response.url
});
this.emit(MP4_EVENTS.ERROR, _error);
} else {
console.log("[MP4] [".concat(vid, "] errorHandler,"), error);
_error = error;
this.emit(MP4_EVENTS.ERROR, _error);
}
case 6:
case "end":
return _context3.stop();
}
}, _callee3, this);
}));
function errorHandler(_x5, _x6) {
return _errorHandler.apply(this, arguments);
}
return errorHandler;
}()
}, {
key: "init",
value: function() {
var _init = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee4() {
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
while (1)
switch (_context4.prev = _context4.next) {
case 0:
if (!this.url) {
_context4.next = 3;
break;
}
_context4.next = 3;
return this.MP4Loader.changeUrl(this.url, this.options.vid + Date.now(), this.CHUNK_SIZE);
case 3:
_context4.next = 5;
return this.getMetaInfo();
case 5:
case "end":
return _context4.stop();
}
}, _callee4, this);
}));
function init() {
return _init.apply(this, arguments);
}
return init;
}()
}, {
key: "getTimeRange",
value: function getTimeRange() {
var range = [];
var timeRange = null;
for (var i = 0; this.videoTrak && i < this.videoTrak.length; i++) {
timeRange = {
startTime: this.videoTrak[i].startTime,
endTime: this.videoTrak[i].endTime,
downloaded: false,
isLoading: false
};
range.push(timeRange);
}
if (this.audioTrak && this.audioTrak.length > range.length) {
for (var j = range.length; j < this.audioTrak.length; j++) {
timeRange = {
startTime: Math.max(this.audioTrak[j].startTime, timeRange ? timeRange.endTime : 0),
endTime: Math.max(this.audioTrak[j].endTime, timeRange ? timeRange.endTime : 0),
downloaded: false,
isLoading: false
};
range.push(timeRange);
}
}
return range;
}
}, {
key: "getMetaInfo",
value: function() {
var _getMetaInfo = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee6() {
var _this2 = this;
var isEmitMetaEvent, startPos, onProgressHandle, _args6 = arguments;
return _regeneratorRuntime().wrap(function _callee6$(_context6) {
while (1)
switch (_context6.prev = _context6.next) {
case 0:
isEmitMetaEvent = _args6.length > 0 && _args6[0] !== void 0 ? _args6[0] : true;
_context6.prev = 1;
this._metaLoading = true;
this.log("getMetaInfo start");
this.bufferLoaded = new Uint8Array(0);
startPos = 0;
onProgressHandle = /* @__PURE__ */ function() {
var _ref2 = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee5(data, state, options) {
var metaInfo;
return _regeneratorRuntime().wrap(function _callee5$(_context5) {
while (1)
switch (_context5.prev = _context5.next) {
case 0:
_this2.log("getMetaInfo onProgressHandle, dataLen,", data ? data.byteLength : -1, ", state,", state, ",range,", JSON.stringify(options.range));
if (data) {
if (options.range[0] === startPos) {
_this2.bufferLoaded = Concat(Uint8Array, _this2.bufferLoaded, new Uint8Array(data));
startPos += data.byteLength;
}
}
if (options.meta && !_this2.meta) {
metaInfo = options.meta;
_this2.videoTrak = metaInfo.videoSegments;
_this2.audioTrak = metaInfo.audioSegments;
_this2.timeRange = _this2.getTimeRange();
_this2.meta = _objectSpread2(_objectSpread2({}, metaInfo.meta), {}, {
ext: {
videoTrak: _this2.videoTrak,
audioTrak: _this2.audioTrak
}
});
metaInfo.bufferLoaded = _this2.bufferLoaded;
_this2.log("meta reach");
if (isEmitMetaEvent) {
_this2.emit(MP4_EVENTS.META_READY, _this2.meta);
}
}
if (_this2.meta && state) {
_this2.log("[getMetaInfo req end]");
_this2._metaLoading = false;
}
if (_this2.meta && (data || state)) {
_this2.log("emit moov_req_progress");
_this2.emit(MP4_EVENTS.MOOV_REQ_PROGRESS);
}
case 5:
case "end":
return _context5.stop();
}
}, _callee5);
}));
return function onProgressHandle2(_x7, _x8, _x9) {
return _ref2.apply(this, arguments);
};
}();
_context6.next = 9;
return this.MP4Loader.loadMetaProcess(this.MP4Loader.cache, [0, this.CHUNK_SIZE], onProgressHandle);
case 9:
_context6.next = 15;
break;
case 11:
_context6.prev = 11;
_context6.t0 = _context6["catch"](1);
console.error("[MP4] trigger errorHandler getMetaInfo", _context6.t0 === null || _context6.t0 === void 0 ? void 0 : _context6.t0.message);
this.loadError(_context6.t0, "getMetaInfo");
case 15:
case "end":
return _context6.stop();
}
}, _callee6, this, [[1, 11]]);
}));
function getMetaInfo() {
return _getMetaInfo.apply(this, arguments);
}
return getMetaInfo;
}()
}, {
key: "getFragmentIdx",
value: function getFragmentIdx(time) {
var video;
var audio;
if (!this.videoTrak.length) {
audio = this.audioTrak.find(function(x) {
return x.startTime <= time && x.endTime > time;
});
return audio ? audio.index : 0;
} else {
video = this.videoTrak.find(function(x) {
return x.startTime <= time && x.endTime > time;
});
audio = this.audioTrak.find(function(x) {
return x.startTime <= time && x.endTime > time;
});
if (video && audio) {
return Math.min(video.index, audio.index);
} else if (video || audio) {
return video ? video.index : audio.index;
} else {
var last = Number.MAX_VALUE;
if (this.videoTrak && this.videoTrak.length > 0) {
last = this.videoTrak.length - 1;
}
if (this.audioTrak && this.audioTrak.length > 0) {
last = Math.min(this.audioTrak.length - 1, last);
}
return last;
}
}
}
}, {
key: "_checkHasMeta",
value: function() {
var _checkHasMeta2 = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee7() {
var metaInfo;
return _regeneratorRuntime().wrap(function _callee7$(_context7) {
while (1)
switch (_context7.prev = _context7.next) {
case 0:
this.log(" loadMeta start");
this._metaLoading = true;
_context7.next = 4;
return this.MP4Loader.loadMeta(this.MP4Loader.cache, Math.round(this.CHUNK_SIZE / 2));
case 4:
metaInfo = _context7.sent;
this._metaLoading = false;
this.videoTrak = metaInfo.videoSegments;
this.audioTrak = metaInfo.audioSegments;
this.meta = _objectSpread2(_objectSpread2({}, metaInfo.meta), {}, {
ext: {
videoTrak: this.videoTrak,
audioTrak: this.audioTrak
}
});
this.timeRange = this.getTimeRange();
this.bufferLoaded = new Uint8Array(0);
metaInfo.bufferLoaded = this.bufferLoaded;
return _context7.abrupt("return", true);
case 13:
case "end":
return _context7.stop();
}
}, _callee7, this);
}));
function _checkHasMeta() {
return _checkHasMeta2.apply(this, arguments);
}
return _checkHasMeta;
}()
}, {
key: "resetFragmentLoadState",
value: function resetFragmentLoadState(fragIndex) {
for (var i = 0; i < this.timeRange.length; i++) {
if (i < fragIndex) {
this.timeRange[i].downloaded = true;
this.timeRange[i].isLoading = true;
} else {
this.timeRange[i].downloaded = false;
this.timeRange[i].isLoading = false;
}
}
}
}, {
key: "getFragRange",
value: function getFragRange(fragIndex) {
var _videoSeg, _audioSeg, _videoSeg2, _audioSeg2;
var videoSeg = null;
if (this.videoTrak) {
videoSeg = fragIndex < this.videoTrak.length ? this.videoTrak[fragIndex] : this.videoTrak[this.videoTrak.length - 1];
}
var audioSeg = null;
if (this.audioTrak) {
audioSeg = fragIndex < this.audioTrak.length ? this.audioTrak[fragIndex] : this.audioTrak[this.audioTrak.length - 1];
}
var videodiff = 0, audiodiff = 0;
if (this.videoTrak && fragIndex >= this.videoTrak.length - 1) {
videodiff = -1;
}
if (this.audioTrak && fragIndex >= this.audioTrak.length - 1) {
audiodiff = -1;
}
var range = [Math.min(((_videoSeg = videoSeg) === null || _videoSeg === void 0 ? void 0 : _videoSeg.range[0]) || Infinity, ((_audioSeg = audioSeg) === null || _audioSeg === void 0 ? void 0 : _audioSeg.range[0]) || Infinity), Math.max(((_videoSeg2 = videoSeg) === null || _videoSeg2 === void 0 ? void 0 : _videoSeg2.range[1]) + videodiff || 0, ((_audioSeg2 = audioSeg) === null || _audioSeg2 === void 0 ? void 0 : _audioSeg2.range[1]) + audiodiff || 0)];
if (fragIndex < this.timeRange.length) {
this.timeRange[fragIndex].range = range;
}
return range;
}
}, {
key: "load",
value: function() {
var _load = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee8(fragIndex, successCallback) {
var metaReady, range, subRange;
return _regeneratorRuntime().wrap(function _callee8$(_context8) {
while (1)
switch (_context8.prev = _context8.next) {
case 0:
this._loadSuccessCallBack = successCallback;
if (!(this._switchBitRate && !this._metaLoading)) {
_context8.next = 12;
break;
}
this.log("[switchBitrate], switch bitRate start load, time,", fragIndex >= this.videoTrak.length ? this.audioTrak[fragIndex].startTime : this.videoTrak[fragIndex].startTime, ", fragIndex,", fragIndex);
_context8.next = 5;
return this._checkHasMeta();
case 5:
metaReady = _context8.sent;
if (this.changeBitRateTime > 0) {
if (this.timeRange[fragIndex].startTime <= this.changeBitRateTime && this.changeBitRateTime < this.timeRange[fragIndex].endTime) {
this.log("[switchBitrate], not need update load fragIndex", fragIndex, ",stTime,", this.changeBitRateTime);
} else {
fragIndex = this.getFragmentIdx(this.changeBitRateTime);
this.log("[switchBitrate], need update load fragIndex", fragIndex, ",stTime,", this.changeBitRateTime, ",newBitrateTimeRange,", this.timeRange[fragIndex].startTime, "-", this.timeRange[fragIndex].endTime);
this.emit(MP4_EVENTS.UPDATE_LOAD_IDX, fragIndex);
}
this.seekTime = this.changeBitRateTime;
this.changeBitRateTime = -1;
}
this.resetFragmentLoadState(fragIndex);
this.log("[switchBitrate], reset timerange state,", fragIndex);
this._needInitSegment = true;
this.resetTansmuxer();
if (metaReady) {
this._switchBitRate = false;
}
case 12:
if (!(this._switchBitRate && this._metaLoading)) {
_context8.next = 14;
break;
}
return _context8.abrupt("return");
case 14:
range = this.getFragRange(fragIndex);
this.log("loadFragment,", fragIndex, ",range,", JSON.stringify(range));
if (this.seekTime > 0) {
subRange = this.getSubRange(fragIndex, this.seekTime, range);
this.loadFragment(fragIndex, subRange);
this.seekTime = -1;
} else {
this.loadFragment(fragIndex, range);
}
case 17:
case "end":
return _context8.stop();
}
}, _callee8, this);
}));
function load(_x10, _x11) {
return _load.apply(this, arguments);
}
return load;
}()
}, {
key: "getSubRange",
value: function getSubRange(fragIndex, time, range) {
var videoStartRange = range[0];
var audioStartRange = range[0];
var i = 1;
var find = false;
this.log(">>>>>getSubRange time,", time, JSON.stringify(range));
if (this.videoTrak) {
var videoSeg = fragIndex < this.videoTrak.length ? this.videoTrak[fragIndex] : this.videoTrak[this.videoTrak.length - 1];
if (videoSeg.frames.length === 0) {
this.log(">>>>>getSubRange video, no frames");
return range;
}
var keyFrameList = videoSeg.frames.filter(getKeyFrameList);
var videoTimescale = this.meta.videoTimescale;
var startTime = keyFrameList[0].startTime / videoTimescale;
this.log(">>>>>getSubRange video, startTime,", videoSeg.startTime, ",endTime,", videoSeg.endTime);
for (var j = 0; j < keyFrameList.length; j++) {
this.log(">>>>>getSubRange video keyFrameList, startTime,", keyFrameList[j].startTime / videoTimescale, ",range,", keyFrameList[j].offset);
}
for (; i < keyFrameList.length; i++) {
var endTime = keyFrameList[i].startTime / videoTimescale;
if (startTime <= time && time < endTime && range[0] < keyFrameList[i - 1].offset) {
videoStartRange = keyFrameList[i - 1].offset;
find = true;
this.log(">>>>>getSubRange video end, startTime,", startTime, ",endTime,", endTime, ",startRange,", videoStartRange, ", keyFrameIndex,", i - 1);
break;
}
startTime = endTime;
}
if (!find && startTime <= time && time < videoSeg.endTime + 0.8) {
videoStartRange = keyFrameList[i - 1].offset;
this.log(">>>>>getSubRange video last, startTime,", startTime, ",endTime,", videoSeg.endTime, ",startRange,", videoStartRange);
}
}
i = 1;
if (this.audioTrak) {
var audioSeg = fragIndex < this.audioTrak.length ? this.audioTrak[fragIndex] : this.audioTrak[this.audioTrak.length - 1];
if (audioSeg.frames.length === 0) {
this.log(">>>>>getSubRange video, no frames");
return range;
}
var frameList = audioSeg.frames;
var audioTimescale = this.meta.audioTimescale;
i = Math.floor((time * audioTimescale - frameList[0].startTime) / audioSeg.frames[0].duration);
i = Math.min(frameList.length - 1, i);
var starttime = i > 0 ? frameList[i - 1].startTime / audioTimescale : frameList[0].startTime / audioTimescale;
for (; i >= 0 && i < frameList.length; ) {
if (i > 0 && starttime > time) {
i -= 1;
starttime = frameList[i].startTime / audioTimescale;
continue;
}
var endtime = (frameList[i].startTime + frameList[i].duration) / audioTimescale;
if (starttime <= time && time < endtime && range[0] < frameList[i].offset) {
audioStartRange = frameList[i].offset;
find = true;
this.log(">>>>>getSubRange audio end, startTime,", starttime, ",endTime,", endtime, ",startRange,", audioStartRange, ", index,", i);
break;
}
starttime = endtime;
i++;
}
}
var finalRange = [Math.min(audioStartRange, videoStartRange), range[1]];
this.log(">>>>>getSubRange finalRange ", JSON.stringify(finalRange), ",oldRange,", JSON.stringify(range));
return finalRange;
}
}, {
key: "_mux",
value: function _mux(buffer, start, fragIndex, state) {
var videoIndexRange = this.getSamplesRange(fragIndex, "video");
var audioIndexRange = this.getSamplesRange(fragIndex, "audio");
var range = [start, start + buffer.byteLength];
if (this.transmuxerWorkerControl && !this.meta.isFragmentMP4) {
var context = {
range,
state,
fragIndex
};
this.log("[transmuxerworker start] ,range, ", JSON.stringify(range), ",dataLen,", buffer.byteLength, context);
this.transmuxerWorkerControl.transmux(this.workerSequence, buffer, start, videoIndexRange, audioIndexRange, this.meta.moov, this.useEME, this.kidValue, context);
} else {
try {
var demuxRet;
if (this.meta.isFragmentMP4) {
if (!this.fMP4Demuxer) {
this.fMP4Demuxer = new FMP4Demuxer();
}
demuxRet = this.fMP4Demuxer.demuxPart(buffer, start, this.meta.moov);
} else {
if (!this.MP4Demuxer) {
this.MP4Demuxer = new MP4Demuxer(this.videoTrak, this.audioTrak, null, {
openLog: checkOpenLog()
});
}
demuxRet = this.MP4Demuxer.demuxPart(buffer, start, videoIndexRange, audioIndexRange, this.meta.moov, this.useEME, this.kidValue);
}
if (!this.FMP4Remuxer && (!this.checkCodecH265() || this.options.supportHevc)) {
this.FMP4Remuxer = new FMP4Remuxer(demuxRet.videoTrack, demuxRet.audioTrack, {
openLog: checkOpenLog()
});
}
var res;
this.log("[mux], videoTimeRange,", demuxRet.videoTrack ? [demuxRet.videoTrack.startPts, demuxRet.videoTrack.endPts] : null, ",audioTimeRange,", demuxRet.audioTrack ? [demuxRet.audioTrack.startPts, demuxRet.audioTrack.endPts] : null);
var startPts = Math.min(demuxRet.videoTrack.startPts, demuxRet.audioTrack.startPts);
var endPts = Math.max(demuxRet.videoTrack.endPts, demuxRet.audioTrack.endPts);
var timeRange = [startPts, endPts];
if (this.FMP4Remuxer) {
var remuxRes = this.FMP4Remuxer.remux(this._needInitSegment, {
initMerge: true,
range
});
remuxRes.initSegment && (this._needInitSegment = false);
var data = util.concatData(remuxRes.audioSegment, remuxRes.videoSegment);
res = {
buffer: data,
range,
state,
context: {
range,
fragIndex,
timeRange
},
initSeg: remuxRes.initSegment
};
} else {
res = {
videoTrack: demuxRet.videoTrack,
audioTrack: demuxRet.audioTrack,
buffer: null,
range,
state,
context: {
range,
fragIndex,
timeRange
}
};
}
this._loadSuccessCallBack && this._loadSuccessCallBack(res);
} catch (e) {
console.error("mux err:", e);
var err = new ParserError(ERROR_TYPES.remux, ERROR_CODES.muxError, {
msg: JSON.stringify(e)
});
this.errorHandler(err, "mux", {
fragIndex,
range: [start, start + buffer.byteLength]
});
}
}
}
}, {
key: "getSamplesRange",
value: function getSamplesRange(fragmentIdx, type) {
var range = [];
switch (type) {
case "video":
if (this.videoTrak && fragmentIdx < this.videoTrak.length) {
var frames = this.videoTrak[fragmentIdx].frames;
if (!frames.length)
break;
range.push(frames[0].index);
range.push(frames[frames.length - 1].index);
}
break;
case "audio":
if (this.audioTrak && fragmentIdx < this.audioTrak.length) {
var _frames = this.audioTrak[fragmentIdx].frames;
if (!_frames.length)
break;
range.push(_frames[0].index);
range.push(_frames[_frames.length - 1].index);
}
break;
default:
console.warn("[getSamplesRange] type ", type, " is invalid");
break;
}
return range;
}
}, {
key: "loadFragment",
value: function() {
var _loadFragment = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee9(fragIndex, range) {
var start, buffer, _start, _buffer;
return _regeneratorRuntime().wrap(function _callee9$(_context9) {
while (1)
switch (_context9.prev = _context9.next) {
case 0:
if (!(this._isPending || range.length > 0 && range[0] === 0 && range[1] === 0 || this.timeRange[fragIndex].isLoading)) {
_context9.next = 2;
break;
}
return _context9.abrupt("return");
case 2:
this.log("[MP4.loadFragment] ,fragIndex,", fragIndex, ",range ", range, ",len ,", range[1] - range[0], ", bufferLoaded_Len,", this.bufferLoaded.byteLength);
if (!(range.length >= 2 && range[1] && range[1] > 0 && range[1] <= this.bufferLoaded.byteLength)) {
_context9.next = 13;
break;
}
this.timeRange[fragIndex].isLoading = true;
start = Math.max(range[0], this.bufferLoadedPos);
buffer = new Uint8Array(this.bufferLoaded.slice(start, range[1]));
this.log("[mp4.loadFragment] has all data: ", start, range[1]);
this.timeRange[fragIndex].downloaded = true;
this.bufferLoadedPos = -1;
this._mux(buffer, start, fragIndex, true);
_context9.next = 34;
break;
case 13:
if (!(range.length >= 2 && range[0] && range[0] <= this.bufferLoaded.byteLength)) {
_context9.next = 29;
break;
}
if (this.timeRange[fragIndex].isLoading) {
_context9.next = 27;
break;
}
_start = Math.max(range[0], this.bufferLoadedPos);
_buffer = new Uint8Array(this.bufferLoaded.slice(_start, range[1]));
if (!(_buffer.byteLength > 0)) {
_context9.next = 22;
break;
}
this.bufferLoadedPos = _start + _buffer.byteLength;
this.log("[mp4.loadFragment] has part data: ", _start, _start + _buffer.byteLength);
this._mux(_buffer, _start, fragIndex, range[1] <= this.bufferLoadedPos);
return _context9.abrupt("return");
case 22:
if (!(!this._metaLoading && !this.timeRange[fragIndex].isLoading)) {
_context9.next = 27;
break;
}
this.log("[mp4.loadFragment] ready to load part data >>> ", this.bufferLoaded.byteLength, range[1]);
this.timeRange[fragIndex].isLoading = true;
_context9.next = 27;
return this.startLoad([this.bufferLoaded.byteLength, range[1]], fragIndex);
case 27:
_context9.next = 34;
break;
case 29:
if (!((!this._metaLoading || range[0] >= this.CHUNK_SIZE) && !this.timeRange[fragIndex].isLoading)) {
_context9.next = 34;
break;
}
this.timeRange[fragIndex].isLoading = true;
this.log("[mp4.loadFragment],ready to load all data ,segmentIdx, ", fragIndex, ",range >>> ", JSON.stringify(range));
_context9.next = 34;
return this.startLoad(range, fragIndex);
case 34:
case "end":
return _context9.stop();
}
}, _callee9, this);
}));
function loadFragment(_x12, _x13) {
return _loadFragment.apply(this, arguments);
}
return loadFragment;
}()
}, {
key: "startLoad",
value: function() {
var _startLoad = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee10(range, fragIndex) {
return _regeneratorRuntime().wrap(function _callee10$(_context10) {
while (1)
switch (_context10.prev = _context10.next) {
case 0:
_context10.prev = 0;
_context10.next = 3;
return this.MP4Loader.loadData(range, this.MP4Loader.cache, {
index: fragIndex,
onProgress: this.onprogressDataArrive,
onProcessMinLen: this.options.onProcessMinLen
});
case 3:
_context10.next = 9;
break;
case 5:
_context10.prev = 5;
_context10.t0 = _context10["catch"](0);
console.error("[MP4] trigger errorHandler getMetaInfo", _context10.t0 === null || _context10.t0 === void 0 ? void 0 : _context10.t0.message);
this.loadError(_context10.t0, "loadFragment", {
range,
fragIndex
});
case 9:
case "end":
return _context10.stop();
}
}, _callee10, this, [[0, 5]]);
}));
function startLoad(_x14, _x15) {
return _startLoad.apply(this, arguments);
}
return startLoad;
}()
}, {
key: "loadError",
value: function loadError(e, loadState, context) {
var _e$response;
!e.response && (e.response = {});
if (e.isTimeout) {
e.response.status = "timeout";
} else if (!(e !== null && e !== void 0 && (_e$response = e.response) !== null && _e$response !== void 0 && _e$response.status)) {
e.response.status = "networkError";
}
this.errorHandler(e, loadState, context);
}
}, {
key: "cancelLoading",
value: function() {
var _cancelLoading = _asyncToGenerator(/* @__PURE__ */ _regeneratorRuntime().mark(function _callee11() {
return _regeneratorRuntime().wrap(function _callee11$(_context11) {
while (1)
switch (_context11.prev = _context11.next) {
case 0:
_context11.next = 2;
return this.MP4Loader;
case 2:
_context11.t0 = _context11.sent;
if (!_context11.t0) {
_context11.next = 5;
break;
}
this.MP4Loader.cancel();
case 5:
case "end":
return _context11.stop();
}
}, _callee11, this);
}));
function cancelLoading() {
return _cancelLoading.apply(this, arguments);
}
return cancelLoading;
}()
}, {
key: "update",
value: function update(url) {
this.url = url;
}
}, {
key: "checkCodecH265",
value: function checkCodecH265() {
var isHvc = this.meta && (this.meta.videoCodec.indexOf("hvc1") > -1 || this.meta.videoCodec.indexOf("hev1") > -1);
return isHvc;
}
}, {
key: "destroy",
value: function destroy() {
if (this.hasDestroyed) {
return;
}
this.resetTansmuxer();
this.transmuxerWorkerControl && this.transmuxerWorkerControl.destroy();
this._isPending = false;
this._metaLoading = false;
this.bufferLoadedPos = 0;
this.bufferLoaded = new Uint8Array(0);
if (this.MP4Loader) {
this.MP4Loader.cancel();
this.MP4Loader.destroy();
}
this.hasDestroyed = true;
}
}, {
key: "resetTansmuxer",
value: function resetTansmuxer() {
this.MP4Demuxer && this.MP4Demuxer.reset();
this.MP4Demuxer = null;
this.FMP4Remuxer && this.FMP4Remuxer.reset();
this.FMP4Remuxer = null;
this.transmuxerWorkerControl && this.transmuxerWorkerControl.reset();
}
}], [{
key: "getDefaultConfig",
value: function getDefaultConfig() {
return {
segmentDuration: 5,
onProcessMinLen: 1024,
chunkSize: 8e5,
retryCount: 3,
retryDelay: 1e3,
timeout: 3e3,
enableWorker: false,
playerId: "",
vid: "",
ext: {},
preferMMS: false
};
}
}]);
return MP42;
}(EventEmitter);
function getKeyFrameList(frame) {
if (frame.keyframe)
return frame;
}
export { MP4_EVENTS, MP4 as default };