App-MHFS
view release on metacpan or search on metacpan
share/public_html/static/hls.js view on Meta::CPAN
var front = offset;
var length = 0;
while (ID3.isHeader(data, offset)) {
// ID3 header is 10 bytes
length += 10;
var size = ID3._readSize(data, offset + 6);
length += size;
if (ID3.isFooter(data, offset + 10)) {
// ID3 footer is 10 bytes
length += 10;
}
offset += length;
}
if (length > 0) {
return data.subarray(front, front + length);
}
return undefined;
};
ID3._readSize = function _readSize(data, offset) {
var size = 0;
size = (data[offset] & 0x7f) << 21;
size |= (data[offset + 1] & 0x7f) << 14;
size |= (data[offset + 2] & 0x7f) << 7;
size |= data[offset + 3] & 0x7f;
return size;
};
/**
* Searches for the Elementary Stream timestamp found in the ID3 data chunk
* @param {Uint8Array} data - Block of data containing one or more ID3 tags
* @return {number} - The timestamp
*/
ID3.getTimeStamp = function getTimeStamp(data) {
var frames = ID3.getID3Frames(data);
for (var i = 0; i < frames.length; i++) {
var frame = frames[i];
if (ID3.isTimeStampFrame(frame)) {
return ID3._readTimeStamp(frame);
}
}
return undefined;
};
/**
* Returns true if the ID3 frame is an Elementary Stream timestamp frame
* @param {ID3 frame} frame
*/
ID3.isTimeStampFrame = function isTimeStampFrame(frame) {
return frame && frame.key === 'PRIV' && frame.info === 'com.apple.streaming.transportStreamTimestamp';
};
ID3._getFrameData = function _getFrameData(data) {
/*
Frame ID $xx xx xx xx (four characters)
Size $xx xx xx xx
Flags $xx xx
*/
var type = String.fromCharCode(data[0], data[1], data[2], data[3]);
var size = ID3._readSize(data, 4);
// skip frame id, size, and flags
var offset = 10;
return { type: type, size: size, data: data.subarray(offset, offset + size) };
};
/**
* Returns an array of ID3 frames found in all the ID3 tags in the id3Data
* @param {Uint8Array} id3Data - The ID3 data containing one or more ID3 tags
* @return {ID3 frame[]} - Array of ID3 frame objects
*/
ID3.getID3Frames = function getID3Frames(id3Data) {
var offset = 0;
var frames = [];
while (ID3.isHeader(id3Data, offset)) {
var size = ID3._readSize(id3Data, offset + 6);
// skip past ID3 header
offset += 10;
var end = offset + size;
// loop through frames in the ID3 tag
while (offset + 8 < end) {
var frameData = ID3._getFrameData(id3Data.subarray(offset));
var frame = ID3._decodeFrame(frameData);
if (frame) {
frames.push(frame);
}
// skip frame header and frame data
offset += frameData.size + 10;
}
if (ID3.isFooter(id3Data, offset)) {
offset += 10;
}
}
return frames;
};
ID3._decodeFrame = function _decodeFrame(frame) {
if (frame.type === 'PRIV') {
return ID3._decodePrivFrame(frame);
} else if (frame.type[0] === 'T') {
return ID3._decodeTextFrame(frame);
} else if (frame.type[0] === 'W') {
return ID3._decodeURLFrame(frame);
share/public_html/static/hls.js view on Meta::CPAN
frag = new loader_fragment();
}
} else if (result[4]) {
// X-BYTERANGE
frag.rawByteRange = (' ' + result[4]).slice(1);
if (prevFrag) {
var lastByteRangeEndOffset = prevFrag.byteRangeEndOffset;
if (lastByteRangeEndOffset) {
frag.lastByteRangeEndOffset = lastByteRangeEndOffset;
}
}
} else if (result[5]) {
// PROGRAM-DATE-TIME
// avoid sliced strings https://github.com/video-dev/hls.js/issues/939
frag.rawProgramDateTime = (' ' + result[5]).slice(1);
frag.tagList.push(['PROGRAM-DATE-TIME', frag.rawProgramDateTime]);
if (level.programDateTime === undefined) {
level.programDateTime = new Date(new Date(Date.parse(result[5])) - 1000 * totalduration);
}
} else {
result = result[0].match(LEVEL_PLAYLIST_REGEX_SLOW);
for (i = 1; i < result.length; i++) {
if (result[i] !== undefined) {
break;
}
}
// avoid sliced strings https://github.com/video-dev/hls.js/issues/939
var value1 = (' ' + result[i + 1]).slice(1);
var value2 = (' ' + result[i + 2]).slice(1);
switch (result[i]) {
case '#':
frag.tagList.push(value2 ? [value1, value2] : [value1]);
break;
case 'PLAYLIST-TYPE':
level.type = value1.toUpperCase();
break;
case 'MEDIA-SEQUENCE':
currentSN = level.startSN = parseInt(value1);
break;
case 'TARGETDURATION':
level.targetduration = parseFloat(value1);
break;
case 'VERSION':
level.version = parseInt(value1);
break;
case 'EXTM3U':
break;
case 'ENDLIST':
level.live = false;
break;
case 'DIS':
cc++;
frag.tagList.push(['DIS']);
break;
case 'DISCONTINUITY-SEQ':
cc = parseInt(value1);
break;
case 'KEY':
// https://tools.ietf.org/html/draft-pantos-http-live-streaming-08#section-3.4.4
var decryptparams = value1;
var keyAttrs = new attr_list(decryptparams);
var decryptmethod = keyAttrs.enumeratedString('METHOD'),
decrypturi = keyAttrs.URI,
decryptiv = keyAttrs.hexadecimalInteger('IV');
if (decryptmethod) {
levelkey = new level_key();
if (decrypturi && ['AES-128', 'SAMPLE-AES', 'SAMPLE-AES-CENC'].indexOf(decryptmethod) >= 0) {
levelkey.method = decryptmethod;
// URI to get the key
levelkey.baseuri = baseurl;
levelkey.reluri = decrypturi;
levelkey.key = null;
// Initialization Vector (IV)
levelkey.iv = decryptiv;
}
}
break;
case 'START':
var startParams = value1;
var startAttrs = new attr_list(startParams);
var startTimeOffset = startAttrs.decimalFloatingPoint('TIME-OFFSET');
// TIME-OFFSET can be 0
if (!isNaN(startTimeOffset)) {
level.startTimeOffset = startTimeOffset;
}
break;
case 'MAP':
var mapAttrs = new attr_list(value1);
frag.relurl = mapAttrs.URI;
frag.rawByteRange = mapAttrs.BYTERANGE;
frag.baseurl = baseurl;
frag.level = id;
frag.type = type;
frag.sn = 'initSegment';
level.initSegment = frag;
frag = new loader_fragment();
break;
default:
logger["b" /* logger */].warn('line parsed but not handled: ' + result);
break;
}
}
}
frag = prevFrag;
// logger.log('found ' + level.fragments.length + ' fragments');
if (frag && !frag.relurl) {
level.fragments.pop();
totalduration -= frag.duration;
}
level.totalduration = totalduration;
level.averagetargetduration = totalduration / level.fragments.length;
level.endSN = currentSN - 1;
level.startCC = level.fragments[0] ? level.fragments[0].cc : 0;
level.endCC = cc;
if (!level.initSegment && level.fragments.length) {
// this is a bit lurky but HLS really has no other way to tell us
// if the fragments are TS or MP4, except if we download them :/
( run in 1.576 second using v1.01-cache-2.11-cpan-140bd7fdf52 )