@jxstjh/jhvideo
Version:
HTML5 jhvideo base on MPEG2-TS Stream Player
218 lines • 7.67 kB
JavaScript
/*
* Copyright (C) 2016 Bilibili. All Rights Reserved.
*
* @author zheng qian <xqq@xqq.im>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Represents an media sample (audio / video)
var SampleInfo = /** @class */ (function () {
function SampleInfo(dts, pts, duration, originalDts, isSync) {
this.dts = dts;
this.pts = pts;
this.duration = duration;
this.originalDts = originalDts;
this.isSyncPoint = isSync;
this.fileposition = null;
}
return SampleInfo;
}());
export { SampleInfo };
// Media Segment concept is defined in Media Source Extensions spec.
// Particularly in ISO BMFF format, an Media Segment contains a moof box followed by a mdat box.
var MediaSegmentInfo = /** @class */ (function () {
function MediaSegmentInfo() {
this.beginDts = 0;
this.endDts = 0;
this.beginPts = 0;
this.endPts = 0;
this.originalBeginDts = 0;
this.originalEndDts = 0;
this.syncPoints = []; // SampleInfo[n], for video IDR frames only
this.firstSample = null; // SampleInfo
this.lastSample = null; // SampleInfo
}
MediaSegmentInfo.prototype.appendSyncPoint = function (sampleInfo) {
sampleInfo.isSyncPoint = true;
this.syncPoints.push(sampleInfo);
};
return MediaSegmentInfo;
}());
export { MediaSegmentInfo };
// Ordered list for recording video IDR frames, sorted by originalDts
var IDRSampleList = /** @class */ (function () {
function IDRSampleList() {
this._list = [];
}
IDRSampleList.prototype.clear = function () {
this._list = [];
};
IDRSampleList.prototype.appendArray = function (syncPoints) {
var list = this._list;
if (syncPoints.length === 0) {
return;
}
if (list.length > 0 && syncPoints[0].originalDts < list[list.length - 1].originalDts) {
this.clear();
}
Array.prototype.push.apply(list, syncPoints);
};
IDRSampleList.prototype.getLastSyncPointBeforeDts = function (dts) {
if (this._list.length == 0) {
return null;
}
var list = this._list;
var idx = 0;
var last = list.length - 1;
var mid = 0;
var lbound = 0;
var ubound = last;
if (dts < list[0].dts) {
idx = 0;
lbound = ubound + 1;
}
while (lbound <= ubound) {
mid = lbound + Math.floor((ubound - lbound) / 2);
if (mid === last || (dts >= list[mid].dts && dts < list[mid + 1].dts)) {
idx = mid;
break;
}
else if (list[mid].dts < dts) {
lbound = mid + 1;
}
else {
ubound = mid - 1;
}
}
return this._list[idx];
};
return IDRSampleList;
}());
export { IDRSampleList };
// Data structure for recording information of media segments in single track.
var MediaSegmentInfoList = /** @class */ (function () {
function MediaSegmentInfoList(type) {
this._type = type;
this._list = [];
this._lastAppendLocation = -1; // cached last insert location
}
Object.defineProperty(MediaSegmentInfoList.prototype, "type", {
get: function () {
return this._type;
},
enumerable: false,
configurable: true
});
Object.defineProperty(MediaSegmentInfoList.prototype, "length", {
get: function () {
return this._list.length;
},
enumerable: false,
configurable: true
});
MediaSegmentInfoList.prototype.isEmpty = function () {
return this._list.length === 0;
};
MediaSegmentInfoList.prototype.clear = function () {
this._list = [];
this._lastAppendLocation = -1;
};
MediaSegmentInfoList.prototype._searchNearestSegmentBefore = function (originalBeginDts) {
var list = this._list;
if (list.length === 0) {
return -2;
}
var last = list.length - 1;
var mid = 0;
var lbound = 0;
var ubound = last;
var idx = 0;
if (originalBeginDts < list[0].originalBeginDts) {
idx = -1;
return idx;
}
while (lbound <= ubound) {
mid = lbound + Math.floor((ubound - lbound) / 2);
if (mid === last || (originalBeginDts > list[mid].lastSample.originalDts &&
(originalBeginDts < list[mid + 1].originalBeginDts))) {
idx = mid;
break;
}
else if (list[mid].originalBeginDts < originalBeginDts) {
lbound = mid + 1;
}
else {
ubound = mid - 1;
}
}
return idx;
};
MediaSegmentInfoList.prototype._searchNearestSegmentAfter = function (originalBeginDts) {
return this._searchNearestSegmentBefore(originalBeginDts) + 1;
};
MediaSegmentInfoList.prototype.append = function (mediaSegmentInfo) {
var list = this._list;
var msi = mediaSegmentInfo;
var lastAppendIdx = this._lastAppendLocation;
var insertIdx = 0;
if (lastAppendIdx !== -1 && lastAppendIdx < list.length &&
msi.originalBeginDts >= list[lastAppendIdx].lastSample.originalDts &&
((lastAppendIdx === list.length - 1) ||
(lastAppendIdx < list.length - 1 &&
msi.originalBeginDts < list[lastAppendIdx + 1].originalBeginDts))) {
insertIdx = lastAppendIdx + 1; // use cached location idx
}
else {
if (list.length > 0) {
insertIdx = this._searchNearestSegmentBefore(msi.originalBeginDts) + 1;
}
}
this._lastAppendLocation = insertIdx;
this._list.splice(insertIdx, 0, msi);
};
MediaSegmentInfoList.prototype.getLastSegmentBefore = function (originalBeginDts) {
var idx = this._searchNearestSegmentBefore(originalBeginDts);
if (idx >= 0) {
return this._list[idx];
}
else { // -1
return null;
}
};
MediaSegmentInfoList.prototype.getLastSampleBefore = function (originalBeginDts) {
var segment = this.getLastSegmentBefore(originalBeginDts);
if (segment != null) {
return segment.lastSample;
}
else {
return null;
}
};
MediaSegmentInfoList.prototype.getLastSyncPointBefore = function (originalBeginDts) {
var segmentIdx = this._searchNearestSegmentBefore(originalBeginDts);
var syncPoints = this._list[segmentIdx].syncPoints;
while (syncPoints.length === 0 && segmentIdx > 0) {
segmentIdx--;
syncPoints = this._list[segmentIdx].syncPoints;
}
if (syncPoints.length > 0) {
return syncPoints[syncPoints.length - 1];
}
else {
return null;
}
};
return MediaSegmentInfoList;
}());
export { MediaSegmentInfoList };
//# sourceMappingURL=media-segment-info.js.map