mirror of
https://github.com/DanielnetoDotCom/YouPHPTube
synced 2025-10-05 02:39:46 +02:00
This commit is contained in:
parent
746e163d01
commit
1c7ea28b46
808 changed files with 316395 additions and 381162 deletions
307
node_modules/mux.js/dist/mux-flv.js
generated
vendored
307
node_modules/mux.js/dist/mux-flv.js
generated
vendored
|
@ -1,4 +1,4 @@
|
|||
/*! @name mux.js @version 6.0.1 @license Apache-2.0 */
|
||||
/*! @name mux.js @version 6.3.0 @license Apache-2.0 */
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
|
@ -2677,7 +2677,44 @@
|
|||
handleRollover: handleRollover
|
||||
};
|
||||
|
||||
var percentEncode = function percentEncode(bytes, start, end) {
|
||||
// IE11 doesn't support indexOf for TypedArrays.
|
||||
// Once IE11 support is dropped, this function should be removed.
|
||||
var typedArrayIndexOf$1 = function typedArrayIndexOf(typedArray, element, fromIndex) {
|
||||
if (!typedArray) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var currentIndex = fromIndex;
|
||||
|
||||
for (; currentIndex < typedArray.length; currentIndex++) {
|
||||
if (typedArray[currentIndex] === element) {
|
||||
return currentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
|
||||
var typedArray = {
|
||||
typedArrayIndexOf: typedArrayIndexOf$1
|
||||
};
|
||||
|
||||
var typedArrayIndexOf = typedArray.typedArrayIndexOf,
|
||||
// Frames that allow different types of text encoding contain a text
|
||||
// encoding description byte [ID3v2.4.0 section 4.]
|
||||
textEncodingDescriptionByte = {
|
||||
Iso88591: 0x00,
|
||||
// ISO-8859-1, terminated with \0.
|
||||
Utf16: 0x01,
|
||||
// UTF-16 encoded Unicode BOM, terminated with \0\0
|
||||
Utf16be: 0x02,
|
||||
// UTF-16BE encoded Unicode, without BOM, terminated with \0\0
|
||||
Utf8: 0x03 // UTF-8 encoded Unicode, terminated with \0
|
||||
|
||||
},
|
||||
// return a percent-encoded representation of the specified byte range
|
||||
// @see http://en.wikipedia.org/wiki/Percent-encoding
|
||||
percentEncode = function percentEncode(bytes, start, end) {
|
||||
var i,
|
||||
result = '';
|
||||
|
||||
|
@ -2700,60 +2737,202 @@
|
|||
parseSyncSafeInteger = function parseSyncSafeInteger(data) {
|
||||
return data[0] << 21 | data[1] << 14 | data[2] << 7 | data[3];
|
||||
},
|
||||
tagParsers = {
|
||||
TXXX: function TXXX(tag) {
|
||||
var i;
|
||||
frameParsers = {
|
||||
'APIC': function APIC(frame) {
|
||||
var i = 1,
|
||||
mimeTypeEndIndex,
|
||||
descriptionEndIndex,
|
||||
LINK_MIME_TYPE = '-->';
|
||||
|
||||
if (tag.data[0] !== 3) {
|
||||
if (frame.data[0] !== textEncodingDescriptionByte.Utf8) {
|
||||
// ignore frames with unrecognized character encodings
|
||||
return;
|
||||
} // parsing fields [ID3v2.4.0 section 4.14.]
|
||||
|
||||
|
||||
mimeTypeEndIndex = typedArrayIndexOf(frame.data, 0, i);
|
||||
|
||||
if (mimeTypeEndIndex < 0) {
|
||||
// malformed frame
|
||||
return;
|
||||
} // parsing Mime type field (terminated with \0)
|
||||
|
||||
|
||||
frame.mimeType = parseIso88591(frame.data, i, mimeTypeEndIndex);
|
||||
i = mimeTypeEndIndex + 1; // parsing 1-byte Picture Type field
|
||||
|
||||
frame.pictureType = frame.data[i];
|
||||
i++;
|
||||
descriptionEndIndex = typedArrayIndexOf(frame.data, 0, i);
|
||||
|
||||
if (descriptionEndIndex < 0) {
|
||||
// malformed frame
|
||||
return;
|
||||
} // parsing Description field (terminated with \0)
|
||||
|
||||
|
||||
frame.description = parseUtf8(frame.data, i, descriptionEndIndex);
|
||||
i = descriptionEndIndex + 1;
|
||||
|
||||
if (frame.mimeType === LINK_MIME_TYPE) {
|
||||
// parsing Picture Data field as URL (always represented as ISO-8859-1 [ID3v2.4.0 section 4.])
|
||||
frame.url = parseIso88591(frame.data, i, frame.data.length);
|
||||
} else {
|
||||
// parsing Picture Data field as binary data
|
||||
frame.pictureData = frame.data.subarray(i, frame.data.length);
|
||||
}
|
||||
},
|
||||
'T*': function T(frame) {
|
||||
if (frame.data[0] !== textEncodingDescriptionByte.Utf8) {
|
||||
// ignore frames with unrecognized character encodings
|
||||
return;
|
||||
} // parse text field, do not include null terminator in the frame value
|
||||
// frames that allow different types of encoding contain terminated text [ID3v2.4.0 section 4.]
|
||||
|
||||
|
||||
frame.value = parseUtf8(frame.data, 1, frame.data.length).replace(/\0*$/, ''); // text information frames supports multiple strings, stored as a terminator separated list [ID3v2.4.0 section 4.2.]
|
||||
|
||||
frame.values = frame.value.split('\0');
|
||||
},
|
||||
'TXXX': function TXXX(frame) {
|
||||
var descriptionEndIndex;
|
||||
|
||||
if (frame.data[0] !== textEncodingDescriptionByte.Utf8) {
|
||||
// ignore frames with unrecognized character encodings
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 1; i < tag.data.length; i++) {
|
||||
if (tag.data[i] === 0) {
|
||||
// parse the text fields
|
||||
tag.description = parseUtf8(tag.data, 1, i); // do not include the null terminator in the tag value
|
||||
descriptionEndIndex = typedArrayIndexOf(frame.data, 0, 1);
|
||||
|
||||
tag.value = parseUtf8(tag.data, i + 1, tag.data.length).replace(/\0*$/, '');
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (descriptionEndIndex === -1) {
|
||||
return;
|
||||
} // parse the text fields
|
||||
|
||||
tag.data = tag.value;
|
||||
|
||||
frame.description = parseUtf8(frame.data, 1, descriptionEndIndex); // do not include the null terminator in the tag value
|
||||
// frames that allow different types of encoding contain terminated text
|
||||
// [ID3v2.4.0 section 4.]
|
||||
|
||||
frame.value = parseUtf8(frame.data, descriptionEndIndex + 1, frame.data.length).replace(/\0*$/, '');
|
||||
frame.data = frame.value;
|
||||
},
|
||||
WXXX: function WXXX(tag) {
|
||||
var i;
|
||||
'W*': function W(frame) {
|
||||
// parse URL field; URL fields are always represented as ISO-8859-1 [ID3v2.4.0 section 4.]
|
||||
// if the value is followed by a string termination all the following information should be ignored [ID3v2.4.0 section 4.3]
|
||||
frame.url = parseIso88591(frame.data, 0, frame.data.length).replace(/\0.*$/, '');
|
||||
},
|
||||
'WXXX': function WXXX(frame) {
|
||||
var descriptionEndIndex;
|
||||
|
||||
if (tag.data[0] !== 3) {
|
||||
if (frame.data[0] !== textEncodingDescriptionByte.Utf8) {
|
||||
// ignore frames with unrecognized character encodings
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 1; i < tag.data.length; i++) {
|
||||
if (tag.data[i] === 0) {
|
||||
// parse the description and URL fields
|
||||
tag.description = parseUtf8(tag.data, 1, i);
|
||||
tag.url = parseUtf8(tag.data, i + 1, tag.data.length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
descriptionEndIndex = typedArrayIndexOf(frame.data, 0, 1);
|
||||
|
||||
if (descriptionEndIndex === -1) {
|
||||
return;
|
||||
} // parse the description and URL fields
|
||||
|
||||
|
||||
frame.description = parseUtf8(frame.data, 1, descriptionEndIndex); // URL fields are always represented as ISO-8859-1 [ID3v2.4.0 section 4.]
|
||||
// if the value is followed by a string termination all the following information
|
||||
// should be ignored [ID3v2.4.0 section 4.3]
|
||||
|
||||
frame.url = parseIso88591(frame.data, descriptionEndIndex + 1, frame.data.length).replace(/\0.*$/, '');
|
||||
},
|
||||
PRIV: function PRIV(tag) {
|
||||
'PRIV': function PRIV(frame) {
|
||||
var i;
|
||||
|
||||
for (i = 0; i < tag.data.length; i++) {
|
||||
if (tag.data[i] === 0) {
|
||||
for (i = 0; i < frame.data.length; i++) {
|
||||
if (frame.data[i] === 0) {
|
||||
// parse the description and URL fields
|
||||
tag.owner = parseIso88591(tag.data, 0, i);
|
||||
frame.owner = parseIso88591(frame.data, 0, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tag.privateData = tag.data.subarray(i + 1);
|
||||
tag.data = tag.privateData;
|
||||
frame.privateData = frame.data.subarray(i + 1);
|
||||
frame.data = frame.privateData;
|
||||
}
|
||||
},
|
||||
_MetadataStream;
|
||||
};
|
||||
|
||||
var parseId3Frames = function parseId3Frames(data) {
|
||||
var frameSize,
|
||||
frameHeader,
|
||||
frameStart = 10,
|
||||
tagSize = 0,
|
||||
frames = []; // If we don't have enough data for a header, 10 bytes,
|
||||
// or 'ID3' in the first 3 bytes this is not a valid ID3 tag.
|
||||
|
||||
if (data.length < 10 || data[0] !== 'I'.charCodeAt(0) || data[1] !== 'D'.charCodeAt(0) || data[2] !== '3'.charCodeAt(0)) {
|
||||
return;
|
||||
} // the frame size is transmitted as a 28-bit integer in the
|
||||
// last four bytes of the ID3 header.
|
||||
// The most significant bit of each byte is dropped and the
|
||||
// results concatenated to recover the actual value.
|
||||
|
||||
|
||||
tagSize = parseSyncSafeInteger(data.subarray(6, 10)); // ID3 reports the tag size excluding the header but it's more
|
||||
// convenient for our comparisons to include it
|
||||
|
||||
tagSize += 10; // check bit 6 of byte 5 for the extended header flag.
|
||||
|
||||
var hasExtendedHeader = data[5] & 0x40;
|
||||
|
||||
if (hasExtendedHeader) {
|
||||
// advance the frame start past the extended header
|
||||
frameStart += 4; // header size field
|
||||
|
||||
frameStart += parseSyncSafeInteger(data.subarray(10, 14));
|
||||
tagSize -= parseSyncSafeInteger(data.subarray(16, 20)); // clip any padding off the end
|
||||
} // parse one or more ID3 frames
|
||||
// http://id3.org/id3v2.3.0#ID3v2_frame_overview
|
||||
|
||||
|
||||
do {
|
||||
// determine the number of bytes in this frame
|
||||
frameSize = parseSyncSafeInteger(data.subarray(frameStart + 4, frameStart + 8));
|
||||
|
||||
if (frameSize < 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
frameHeader = String.fromCharCode(data[frameStart], data[frameStart + 1], data[frameStart + 2], data[frameStart + 3]);
|
||||
var frame = {
|
||||
id: frameHeader,
|
||||
data: data.subarray(frameStart + 10, frameStart + frameSize + 10)
|
||||
};
|
||||
frame.key = frame.id; // parse frame values
|
||||
|
||||
if (frameParsers[frame.id]) {
|
||||
// use frame specific parser
|
||||
frameParsers[frame.id](frame);
|
||||
} else if (frame.id[0] === 'T') {
|
||||
// use text frame generic parser
|
||||
frameParsers['T*'](frame);
|
||||
} else if (frame.id[0] === 'W') {
|
||||
// use URL link frame generic parser
|
||||
frameParsers['W*'](frame);
|
||||
}
|
||||
|
||||
frames.push(frame);
|
||||
frameStart += 10; // advance past the frame header
|
||||
|
||||
frameStart += frameSize; // advance past the frame body
|
||||
} while (frameStart < tagSize);
|
||||
|
||||
return frames;
|
||||
};
|
||||
|
||||
var parseId3 = {
|
||||
parseId3Frames: parseId3Frames,
|
||||
parseSyncSafeInteger: parseSyncSafeInteger,
|
||||
frameParsers: frameParsers
|
||||
};
|
||||
|
||||
var _MetadataStream;
|
||||
|
||||
_MetadataStream = function MetadataStream(options) {
|
||||
var settings = {
|
||||
|
@ -2815,7 +2994,7 @@
|
|||
// last four bytes of the ID3 header.
|
||||
// The most significant bit of each byte is dropped and the
|
||||
// results concatenated to recover the actual value.
|
||||
tagSize = parseSyncSafeInteger(chunk.data.subarray(6, 10)); // ID3 reports the tag size excluding the header but it's more
|
||||
tagSize = parseId3.parseSyncSafeInteger(chunk.data.subarray(6, 10)); // ID3 reports the tag size excluding the header but it's more
|
||||
// convenient for our comparisons to include it
|
||||
|
||||
tagSize += 10;
|
||||
|
@ -2848,23 +3027,25 @@
|
|||
// advance the frame start past the extended header
|
||||
frameStart += 4; // header size field
|
||||
|
||||
frameStart += parseSyncSafeInteger(tag.data.subarray(10, 14)); // clip any padding off the end
|
||||
frameStart += parseId3.parseSyncSafeInteger(tag.data.subarray(10, 14)); // clip any padding off the end
|
||||
|
||||
tagSize -= parseSyncSafeInteger(tag.data.subarray(16, 20));
|
||||
tagSize -= parseId3.parseSyncSafeInteger(tag.data.subarray(16, 20));
|
||||
} // parse one or more ID3 frames
|
||||
// http://id3.org/id3v2.3.0#ID3v2_frame_overview
|
||||
|
||||
|
||||
do {
|
||||
// determine the number of bytes in this frame
|
||||
frameSize = parseSyncSafeInteger(tag.data.subarray(frameStart + 4, frameStart + 8));
|
||||
frameSize = parseId3.parseSyncSafeInteger(tag.data.subarray(frameStart + 4, frameStart + 8));
|
||||
|
||||
if (frameSize < 1) {
|
||||
this.trigger('log', {
|
||||
level: 'warn',
|
||||
message: 'Malformed ID3 frame encountered. Skipping metadata parsing.'
|
||||
});
|
||||
return;
|
||||
message: 'Malformed ID3 frame encountered. Skipping remaining metadata parsing.'
|
||||
}); // If the frame is malformed, don't parse any further frames but allow previous valid parsed frames
|
||||
// to be sent along.
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
frameHeader = String.fromCharCode(tag.data[frameStart], tag.data[frameStart + 1], tag.data[frameStart + 2], tag.data[frameStart + 3]);
|
||||
|
@ -2872,29 +3053,37 @@
|
|||
id: frameHeader,
|
||||
data: tag.data.subarray(frameStart + 10, frameStart + frameSize + 10)
|
||||
};
|
||||
frame.key = frame.id;
|
||||
frame.key = frame.id; // parse frame values
|
||||
|
||||
if (tagParsers[frame.id]) {
|
||||
tagParsers[frame.id](frame); // handle the special PRIV frame used to indicate the start
|
||||
// time for raw AAC data
|
||||
if (parseId3.frameParsers[frame.id]) {
|
||||
// use frame specific parser
|
||||
parseId3.frameParsers[frame.id](frame);
|
||||
} else if (frame.id[0] === 'T') {
|
||||
// use text frame generic parser
|
||||
parseId3.frameParsers['T*'](frame);
|
||||
} else if (frame.id[0] === 'W') {
|
||||
// use URL link frame generic parser
|
||||
parseId3.frameParsers['W*'](frame);
|
||||
} // handle the special PRIV frame used to indicate the start
|
||||
// time for raw AAC data
|
||||
|
||||
if (frame.owner === 'com.apple.streaming.transportStreamTimestamp') {
|
||||
var d = frame.data,
|
||||
size = (d[3] & 0x01) << 30 | d[4] << 22 | d[5] << 14 | d[6] << 6 | d[7] >>> 2;
|
||||
size *= 4;
|
||||
size += d[7] & 0x03;
|
||||
frame.timeStamp = size; // in raw AAC, all subsequent data will be timestamped based
|
||||
// on the value of this frame
|
||||
// we couldn't have known the appropriate pts and dts before
|
||||
// parsing this ID3 tag so set those values now
|
||||
|
||||
if (tag.pts === undefined && tag.dts === undefined) {
|
||||
tag.pts = frame.timeStamp;
|
||||
tag.dts = frame.timeStamp;
|
||||
}
|
||||
if (frame.owner === 'com.apple.streaming.transportStreamTimestamp') {
|
||||
var d = frame.data,
|
||||
size = (d[3] & 0x01) << 30 | d[4] << 22 | d[5] << 14 | d[6] << 6 | d[7] >>> 2;
|
||||
size *= 4;
|
||||
size += d[7] & 0x03;
|
||||
frame.timeStamp = size; // in raw AAC, all subsequent data will be timestamped based
|
||||
// on the value of this frame
|
||||
// we couldn't have known the appropriate pts and dts before
|
||||
// parsing this ID3 tag so set those values now
|
||||
|
||||
this.trigger('timestamp', frame);
|
||||
if (tag.pts === undefined && tag.dts === undefined) {
|
||||
tag.pts = frame.timeStamp;
|
||||
tag.dts = frame.timeStamp;
|
||||
}
|
||||
|
||||
this.trigger('timestamp', frame);
|
||||
}
|
||||
|
||||
tag.frames.push(frame);
|
||||
|
|
4
node_modules/mux.js/dist/mux-flv.min.js
generated
vendored
4
node_modules/mux.js/dist/mux-flv.min.js
generated
vendored
File diff suppressed because one or more lines are too long
560
node_modules/mux.js/dist/mux-mp4.js
generated
vendored
560
node_modules/mux.js/dist/mux-mp4.js
generated
vendored
|
@ -1,4 +1,4 @@
|
|||
/*! @name mux.js @version 6.0.1 @license Apache-2.0 */
|
||||
/*! @name mux.js @version 6.3.0 @license Apache-2.0 */
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('global/window')) :
|
||||
typeof define === 'function' && define.amd ? define(['global/window'], factory) :
|
||||
|
@ -11,7 +11,7 @@
|
|||
|
||||
var MAX_UINT32$1 = Math.pow(2, 32);
|
||||
|
||||
var getUint64$2 = function getUint64(uint8) {
|
||||
var getUint64$3 = function getUint64(uint8) {
|
||||
var dv = new DataView(uint8.buffer, uint8.byteOffset, uint8.byteLength);
|
||||
var value;
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
|||
};
|
||||
|
||||
var numbers = {
|
||||
getUint64: getUint64$2,
|
||||
getUint64: getUint64$3,
|
||||
MAX_UINT32: MAX_UINT32$1
|
||||
};
|
||||
|
||||
|
@ -707,6 +707,133 @@
|
|||
|
||||
var findBox_1 = findBox;
|
||||
|
||||
/**
|
||||
* Returns the first string in the data array ending with a null char '\0'
|
||||
* @param {UInt8} data
|
||||
* @returns the string with the null char
|
||||
*/
|
||||
var uint8ToCString$1 = function uint8ToCString(data) {
|
||||
var index = 0;
|
||||
var curChar = String.fromCharCode(data[index]);
|
||||
var retString = '';
|
||||
|
||||
while (curChar !== '\0') {
|
||||
retString += curChar;
|
||||
index++;
|
||||
curChar = String.fromCharCode(data[index]);
|
||||
} // Add nullChar
|
||||
|
||||
|
||||
retString += curChar;
|
||||
return retString;
|
||||
};
|
||||
|
||||
var string = {
|
||||
uint8ToCString: uint8ToCString$1
|
||||
};
|
||||
|
||||
var uint8ToCString = string.uint8ToCString;
|
||||
var getUint64$2 = numbers.getUint64;
|
||||
/**
|
||||
* Based on: ISO/IEC 23009 Section: 5.10.3.3
|
||||
* References:
|
||||
* https://dashif-documents.azurewebsites.net/Events/master/event.html#emsg-format
|
||||
* https://aomediacodec.github.io/id3-emsg/
|
||||
*
|
||||
* Takes emsg box data as a uint8 array and returns a emsg box object
|
||||
* @param {UInt8Array} boxData data from emsg box
|
||||
* @returns A parsed emsg box object
|
||||
*/
|
||||
|
||||
var parseEmsgBox = function parseEmsgBox(boxData) {
|
||||
// version + flags
|
||||
var offset = 4;
|
||||
var version = boxData[0];
|
||||
var scheme_id_uri, value, timescale, presentation_time, presentation_time_delta, event_duration, id, message_data;
|
||||
|
||||
if (version === 0) {
|
||||
scheme_id_uri = uint8ToCString(boxData.subarray(offset));
|
||||
offset += scheme_id_uri.length;
|
||||
value = uint8ToCString(boxData.subarray(offset));
|
||||
offset += value.length;
|
||||
var dv = new DataView(boxData.buffer);
|
||||
timescale = dv.getUint32(offset);
|
||||
offset += 4;
|
||||
presentation_time_delta = dv.getUint32(offset);
|
||||
offset += 4;
|
||||
event_duration = dv.getUint32(offset);
|
||||
offset += 4;
|
||||
id = dv.getUint32(offset);
|
||||
offset += 4;
|
||||
} else if (version === 1) {
|
||||
var dv = new DataView(boxData.buffer);
|
||||
timescale = dv.getUint32(offset);
|
||||
offset += 4;
|
||||
presentation_time = getUint64$2(boxData.subarray(offset));
|
||||
offset += 8;
|
||||
event_duration = dv.getUint32(offset);
|
||||
offset += 4;
|
||||
id = dv.getUint32(offset);
|
||||
offset += 4;
|
||||
scheme_id_uri = uint8ToCString(boxData.subarray(offset));
|
||||
offset += scheme_id_uri.length;
|
||||
value = uint8ToCString(boxData.subarray(offset));
|
||||
offset += value.length;
|
||||
}
|
||||
|
||||
message_data = new Uint8Array(boxData.subarray(offset, boxData.byteLength));
|
||||
var emsgBox = {
|
||||
scheme_id_uri: scheme_id_uri,
|
||||
value: value,
|
||||
// if timescale is undefined or 0 set to 1
|
||||
timescale: timescale ? timescale : 1,
|
||||
presentation_time: presentation_time,
|
||||
presentation_time_delta: presentation_time_delta,
|
||||
event_duration: event_duration,
|
||||
id: id,
|
||||
message_data: message_data
|
||||
};
|
||||
return isValidEmsgBox(version, emsgBox) ? emsgBox : undefined;
|
||||
};
|
||||
/**
|
||||
* Scales a presentation time or time delta with an offset with a provided timescale
|
||||
* @param {number} presentationTime
|
||||
* @param {number} timescale
|
||||
* @param {number} timeDelta
|
||||
* @param {number} offset
|
||||
* @returns the scaled time as a number
|
||||
*/
|
||||
|
||||
|
||||
var scaleTime = function scaleTime(presentationTime, timescale, timeDelta, offset) {
|
||||
return presentationTime || presentationTime === 0 ? presentationTime / timescale : offset + timeDelta / timescale;
|
||||
};
|
||||
/**
|
||||
* Checks the emsg box data for validity based on the version
|
||||
* @param {number} version of the emsg box to validate
|
||||
* @param {Object} emsg the emsg data to validate
|
||||
* @returns if the box is valid as a boolean
|
||||
*/
|
||||
|
||||
|
||||
var isValidEmsgBox = function isValidEmsgBox(version, emsg) {
|
||||
var hasScheme = emsg.scheme_id_uri !== '\0';
|
||||
var isValidV0Box = version === 0 && isDefined(emsg.presentation_time_delta) && hasScheme;
|
||||
var isValidV1Box = version === 1 && isDefined(emsg.presentation_time) && hasScheme; // Only valid versions of emsg are 0 and 1
|
||||
|
||||
return !(version > 1) && isValidV0Box || isValidV1Box;
|
||||
}; // Utility function to check if an object is defined
|
||||
|
||||
|
||||
var isDefined = function isDefined(data) {
|
||||
return data !== undefined || data !== null;
|
||||
};
|
||||
|
||||
var emsg = {
|
||||
parseEmsgBox: parseEmsgBox,
|
||||
scaleTime: scaleTime
|
||||
};
|
||||
|
||||
var tfhd = function tfhd(data) {
|
||||
var view = new DataView(data.buffer, data.byteOffset, data.byteLength),
|
||||
result = {
|
||||
|
@ -896,10 +1023,266 @@
|
|||
|
||||
var parseTfdt = tfdt;
|
||||
|
||||
// IE11 doesn't support indexOf for TypedArrays.
|
||||
// Once IE11 support is dropped, this function should be removed.
|
||||
var typedArrayIndexOf$1 = function typedArrayIndexOf(typedArray, element, fromIndex) {
|
||||
if (!typedArray) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var currentIndex = fromIndex;
|
||||
|
||||
for (; currentIndex < typedArray.length; currentIndex++) {
|
||||
if (typedArray[currentIndex] === element) {
|
||||
return currentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
|
||||
var typedArray = {
|
||||
typedArrayIndexOf: typedArrayIndexOf$1
|
||||
};
|
||||
|
||||
var typedArrayIndexOf = typedArray.typedArrayIndexOf,
|
||||
// Frames that allow different types of text encoding contain a text
|
||||
// encoding description byte [ID3v2.4.0 section 4.]
|
||||
textEncodingDescriptionByte = {
|
||||
Iso88591: 0x00,
|
||||
// ISO-8859-1, terminated with \0.
|
||||
Utf16: 0x01,
|
||||
// UTF-16 encoded Unicode BOM, terminated with \0\0
|
||||
Utf16be: 0x02,
|
||||
// UTF-16BE encoded Unicode, without BOM, terminated with \0\0
|
||||
Utf8: 0x03 // UTF-8 encoded Unicode, terminated with \0
|
||||
|
||||
},
|
||||
// return a percent-encoded representation of the specified byte range
|
||||
// @see http://en.wikipedia.org/wiki/Percent-encoding
|
||||
percentEncode$1 = function percentEncode(bytes, start, end) {
|
||||
var i,
|
||||
result = '';
|
||||
|
||||
for (i = start; i < end; i++) {
|
||||
result += '%' + ('00' + bytes[i].toString(16)).slice(-2);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
// return the string representation of the specified byte range,
|
||||
// interpreted as UTf-8.
|
||||
parseUtf8 = function parseUtf8(bytes, start, end) {
|
||||
return decodeURIComponent(percentEncode$1(bytes, start, end));
|
||||
},
|
||||
// return the string representation of the specified byte range,
|
||||
// interpreted as ISO-8859-1.
|
||||
parseIso88591$1 = function parseIso88591(bytes, start, end) {
|
||||
return unescape(percentEncode$1(bytes, start, end)); // jshint ignore:line
|
||||
},
|
||||
parseSyncSafeInteger$1 = function parseSyncSafeInteger(data) {
|
||||
return data[0] << 21 | data[1] << 14 | data[2] << 7 | data[3];
|
||||
},
|
||||
frameParsers = {
|
||||
'APIC': function APIC(frame) {
|
||||
var i = 1,
|
||||
mimeTypeEndIndex,
|
||||
descriptionEndIndex,
|
||||
LINK_MIME_TYPE = '-->';
|
||||
|
||||
if (frame.data[0] !== textEncodingDescriptionByte.Utf8) {
|
||||
// ignore frames with unrecognized character encodings
|
||||
return;
|
||||
} // parsing fields [ID3v2.4.0 section 4.14.]
|
||||
|
||||
|
||||
mimeTypeEndIndex = typedArrayIndexOf(frame.data, 0, i);
|
||||
|
||||
if (mimeTypeEndIndex < 0) {
|
||||
// malformed frame
|
||||
return;
|
||||
} // parsing Mime type field (terminated with \0)
|
||||
|
||||
|
||||
frame.mimeType = parseIso88591$1(frame.data, i, mimeTypeEndIndex);
|
||||
i = mimeTypeEndIndex + 1; // parsing 1-byte Picture Type field
|
||||
|
||||
frame.pictureType = frame.data[i];
|
||||
i++;
|
||||
descriptionEndIndex = typedArrayIndexOf(frame.data, 0, i);
|
||||
|
||||
if (descriptionEndIndex < 0) {
|
||||
// malformed frame
|
||||
return;
|
||||
} // parsing Description field (terminated with \0)
|
||||
|
||||
|
||||
frame.description = parseUtf8(frame.data, i, descriptionEndIndex);
|
||||
i = descriptionEndIndex + 1;
|
||||
|
||||
if (frame.mimeType === LINK_MIME_TYPE) {
|
||||
// parsing Picture Data field as URL (always represented as ISO-8859-1 [ID3v2.4.0 section 4.])
|
||||
frame.url = parseIso88591$1(frame.data, i, frame.data.length);
|
||||
} else {
|
||||
// parsing Picture Data field as binary data
|
||||
frame.pictureData = frame.data.subarray(i, frame.data.length);
|
||||
}
|
||||
},
|
||||
'T*': function T(frame) {
|
||||
if (frame.data[0] !== textEncodingDescriptionByte.Utf8) {
|
||||
// ignore frames with unrecognized character encodings
|
||||
return;
|
||||
} // parse text field, do not include null terminator in the frame value
|
||||
// frames that allow different types of encoding contain terminated text [ID3v2.4.0 section 4.]
|
||||
|
||||
|
||||
frame.value = parseUtf8(frame.data, 1, frame.data.length).replace(/\0*$/, ''); // text information frames supports multiple strings, stored as a terminator separated list [ID3v2.4.0 section 4.2.]
|
||||
|
||||
frame.values = frame.value.split('\0');
|
||||
},
|
||||
'TXXX': function TXXX(frame) {
|
||||
var descriptionEndIndex;
|
||||
|
||||
if (frame.data[0] !== textEncodingDescriptionByte.Utf8) {
|
||||
// ignore frames with unrecognized character encodings
|
||||
return;
|
||||
}
|
||||
|
||||
descriptionEndIndex = typedArrayIndexOf(frame.data, 0, 1);
|
||||
|
||||
if (descriptionEndIndex === -1) {
|
||||
return;
|
||||
} // parse the text fields
|
||||
|
||||
|
||||
frame.description = parseUtf8(frame.data, 1, descriptionEndIndex); // do not include the null terminator in the tag value
|
||||
// frames that allow different types of encoding contain terminated text
|
||||
// [ID3v2.4.0 section 4.]
|
||||
|
||||
frame.value = parseUtf8(frame.data, descriptionEndIndex + 1, frame.data.length).replace(/\0*$/, '');
|
||||
frame.data = frame.value;
|
||||
},
|
||||
'W*': function W(frame) {
|
||||
// parse URL field; URL fields are always represented as ISO-8859-1 [ID3v2.4.0 section 4.]
|
||||
// if the value is followed by a string termination all the following information should be ignored [ID3v2.4.0 section 4.3]
|
||||
frame.url = parseIso88591$1(frame.data, 0, frame.data.length).replace(/\0.*$/, '');
|
||||
},
|
||||
'WXXX': function WXXX(frame) {
|
||||
var descriptionEndIndex;
|
||||
|
||||
if (frame.data[0] !== textEncodingDescriptionByte.Utf8) {
|
||||
// ignore frames with unrecognized character encodings
|
||||
return;
|
||||
}
|
||||
|
||||
descriptionEndIndex = typedArrayIndexOf(frame.data, 0, 1);
|
||||
|
||||
if (descriptionEndIndex === -1) {
|
||||
return;
|
||||
} // parse the description and URL fields
|
||||
|
||||
|
||||
frame.description = parseUtf8(frame.data, 1, descriptionEndIndex); // URL fields are always represented as ISO-8859-1 [ID3v2.4.0 section 4.]
|
||||
// if the value is followed by a string termination all the following information
|
||||
// should be ignored [ID3v2.4.0 section 4.3]
|
||||
|
||||
frame.url = parseIso88591$1(frame.data, descriptionEndIndex + 1, frame.data.length).replace(/\0.*$/, '');
|
||||
},
|
||||
'PRIV': function PRIV(frame) {
|
||||
var i;
|
||||
|
||||
for (i = 0; i < frame.data.length; i++) {
|
||||
if (frame.data[i] === 0) {
|
||||
// parse the description and URL fields
|
||||
frame.owner = parseIso88591$1(frame.data, 0, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
frame.privateData = frame.data.subarray(i + 1);
|
||||
frame.data = frame.privateData;
|
||||
}
|
||||
};
|
||||
|
||||
var parseId3Frames$1 = function parseId3Frames(data) {
|
||||
var frameSize,
|
||||
frameHeader,
|
||||
frameStart = 10,
|
||||
tagSize = 0,
|
||||
frames = []; // If we don't have enough data for a header, 10 bytes,
|
||||
// or 'ID3' in the first 3 bytes this is not a valid ID3 tag.
|
||||
|
||||
if (data.length < 10 || data[0] !== 'I'.charCodeAt(0) || data[1] !== 'D'.charCodeAt(0) || data[2] !== '3'.charCodeAt(0)) {
|
||||
return;
|
||||
} // the frame size is transmitted as a 28-bit integer in the
|
||||
// last four bytes of the ID3 header.
|
||||
// The most significant bit of each byte is dropped and the
|
||||
// results concatenated to recover the actual value.
|
||||
|
||||
|
||||
tagSize = parseSyncSafeInteger$1(data.subarray(6, 10)); // ID3 reports the tag size excluding the header but it's more
|
||||
// convenient for our comparisons to include it
|
||||
|
||||
tagSize += 10; // check bit 6 of byte 5 for the extended header flag.
|
||||
|
||||
var hasExtendedHeader = data[5] & 0x40;
|
||||
|
||||
if (hasExtendedHeader) {
|
||||
// advance the frame start past the extended header
|
||||
frameStart += 4; // header size field
|
||||
|
||||
frameStart += parseSyncSafeInteger$1(data.subarray(10, 14));
|
||||
tagSize -= parseSyncSafeInteger$1(data.subarray(16, 20)); // clip any padding off the end
|
||||
} // parse one or more ID3 frames
|
||||
// http://id3.org/id3v2.3.0#ID3v2_frame_overview
|
||||
|
||||
|
||||
do {
|
||||
// determine the number of bytes in this frame
|
||||
frameSize = parseSyncSafeInteger$1(data.subarray(frameStart + 4, frameStart + 8));
|
||||
|
||||
if (frameSize < 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
frameHeader = String.fromCharCode(data[frameStart], data[frameStart + 1], data[frameStart + 2], data[frameStart + 3]);
|
||||
var frame = {
|
||||
id: frameHeader,
|
||||
data: data.subarray(frameStart + 10, frameStart + frameSize + 10)
|
||||
};
|
||||
frame.key = frame.id; // parse frame values
|
||||
|
||||
if (frameParsers[frame.id]) {
|
||||
// use frame specific parser
|
||||
frameParsers[frame.id](frame);
|
||||
} else if (frame.id[0] === 'T') {
|
||||
// use text frame generic parser
|
||||
frameParsers['T*'](frame);
|
||||
} else if (frame.id[0] === 'W') {
|
||||
// use URL link frame generic parser
|
||||
frameParsers['W*'](frame);
|
||||
}
|
||||
|
||||
frames.push(frame);
|
||||
frameStart += 10; // advance past the frame header
|
||||
|
||||
frameStart += frameSize; // advance past the frame body
|
||||
} while (frameStart < tagSize);
|
||||
|
||||
return frames;
|
||||
};
|
||||
|
||||
var parseId3 = {
|
||||
parseId3Frames: parseId3Frames$1,
|
||||
parseSyncSafeInteger: parseSyncSafeInteger$1,
|
||||
frameParsers: frameParsers
|
||||
};
|
||||
|
||||
var toUnsigned = bin.toUnsigned;
|
||||
var toHexString = bin.toHexString;
|
||||
var getUint64 = numbers.getUint64;
|
||||
var timescale, startTime, compositionStartTime, getVideoTrackIds, getTracks, getTimescaleFromMediaHeader;
|
||||
var timescale, startTime, compositionStartTime, getVideoTrackIds, getTracks, getTimescaleFromMediaHeader, getEmsgID3;
|
||||
var parseId3Frames = parseId3.parseId3Frames;
|
||||
/**
|
||||
* Parses an MP4 initialization segment and extracts the timescale
|
||||
* values for any declared tracks. Timescale values indicate the
|
||||
|
@ -1218,6 +1601,34 @@
|
|||
});
|
||||
return tracks;
|
||||
};
|
||||
/**
|
||||
* Returns an array of emsg ID3 data from the provided segmentData.
|
||||
* An offset can also be provided as the Latest Arrival Time to calculate
|
||||
* the Event Start Time of v0 EMSG boxes.
|
||||
* See: https://dashif-documents.azurewebsites.net/Events/master/event.html#Inband-event-timing
|
||||
*
|
||||
* @param {Uint8Array} segmentData the segment byte array.
|
||||
* @param {number} offset the segment start time or Latest Arrival Time,
|
||||
* @return {Object[]} an array of ID3 parsed from EMSG boxes
|
||||
*/
|
||||
|
||||
|
||||
getEmsgID3 = function getEmsgID3(segmentData, offset) {
|
||||
if (offset === void 0) {
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
var emsgBoxes = findBox_1(segmentData, ['emsg']);
|
||||
return emsgBoxes.map(function (data) {
|
||||
var parsedBox = emsg.parseEmsgBox(new Uint8Array(data));
|
||||
var parsedId3Frames = parseId3Frames(parsedBox.message_data);
|
||||
return {
|
||||
cueTime: emsg.scaleTime(parsedBox.presentation_time, parsedBox.timescale, parsedBox.presentation_time_delta, offset),
|
||||
duration: emsg.scaleTime(parsedBox.event_duration, parsedBox.timescale),
|
||||
frames: parsedId3Frames
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
var probe = {
|
||||
// export mp4 inspector's findBox and parseType for backwards compatibility
|
||||
|
@ -1228,7 +1639,8 @@
|
|||
compositionStartTime: compositionStartTime,
|
||||
videoTrackIds: getVideoTrackIds,
|
||||
tracks: getTracks,
|
||||
getTimescaleFromMediaHeader: getTimescaleFromMediaHeader
|
||||
getTimescaleFromMediaHeader: getTimescaleFromMediaHeader,
|
||||
getEmsgID3: getEmsgID3
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -4197,83 +4609,7 @@
|
|||
handleRollover: handleRollover
|
||||
};
|
||||
|
||||
var percentEncode$1 = function percentEncode(bytes, start, end) {
|
||||
var i,
|
||||
result = '';
|
||||
|
||||
for (i = start; i < end; i++) {
|
||||
result += '%' + ('00' + bytes[i].toString(16)).slice(-2);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
// return the string representation of the specified byte range,
|
||||
// interpreted as UTf-8.
|
||||
parseUtf8 = function parseUtf8(bytes, start, end) {
|
||||
return decodeURIComponent(percentEncode$1(bytes, start, end));
|
||||
},
|
||||
// return the string representation of the specified byte range,
|
||||
// interpreted as ISO-8859-1.
|
||||
parseIso88591$1 = function parseIso88591(bytes, start, end) {
|
||||
return unescape(percentEncode$1(bytes, start, end)); // jshint ignore:line
|
||||
},
|
||||
parseSyncSafeInteger$1 = function parseSyncSafeInteger(data) {
|
||||
return data[0] << 21 | data[1] << 14 | data[2] << 7 | data[3];
|
||||
},
|
||||
tagParsers = {
|
||||
TXXX: function TXXX(tag) {
|
||||
var i;
|
||||
|
||||
if (tag.data[0] !== 3) {
|
||||
// ignore frames with unrecognized character encodings
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 1; i < tag.data.length; i++) {
|
||||
if (tag.data[i] === 0) {
|
||||
// parse the text fields
|
||||
tag.description = parseUtf8(tag.data, 1, i); // do not include the null terminator in the tag value
|
||||
|
||||
tag.value = parseUtf8(tag.data, i + 1, tag.data.length).replace(/\0*$/, '');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tag.data = tag.value;
|
||||
},
|
||||
WXXX: function WXXX(tag) {
|
||||
var i;
|
||||
|
||||
if (tag.data[0] !== 3) {
|
||||
// ignore frames with unrecognized character encodings
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 1; i < tag.data.length; i++) {
|
||||
if (tag.data[i] === 0) {
|
||||
// parse the description and URL fields
|
||||
tag.description = parseUtf8(tag.data, 1, i);
|
||||
tag.url = parseUtf8(tag.data, i + 1, tag.data.length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
PRIV: function PRIV(tag) {
|
||||
var i;
|
||||
|
||||
for (i = 0; i < tag.data.length; i++) {
|
||||
if (tag.data[i] === 0) {
|
||||
// parse the description and URL fields
|
||||
tag.owner = parseIso88591$1(tag.data, 0, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tag.privateData = tag.data.subarray(i + 1);
|
||||
tag.data = tag.privateData;
|
||||
}
|
||||
},
|
||||
_MetadataStream;
|
||||
var _MetadataStream;
|
||||
|
||||
_MetadataStream = function MetadataStream(options) {
|
||||
var settings = {
|
||||
|
@ -4335,7 +4671,7 @@
|
|||
// last four bytes of the ID3 header.
|
||||
// The most significant bit of each byte is dropped and the
|
||||
// results concatenated to recover the actual value.
|
||||
tagSize = parseSyncSafeInteger$1(chunk.data.subarray(6, 10)); // ID3 reports the tag size excluding the header but it's more
|
||||
tagSize = parseId3.parseSyncSafeInteger(chunk.data.subarray(6, 10)); // ID3 reports the tag size excluding the header but it's more
|
||||
// convenient for our comparisons to include it
|
||||
|
||||
tagSize += 10;
|
||||
|
@ -4368,23 +4704,25 @@
|
|||
// advance the frame start past the extended header
|
||||
frameStart += 4; // header size field
|
||||
|
||||
frameStart += parseSyncSafeInteger$1(tag.data.subarray(10, 14)); // clip any padding off the end
|
||||
frameStart += parseId3.parseSyncSafeInteger(tag.data.subarray(10, 14)); // clip any padding off the end
|
||||
|
||||
tagSize -= parseSyncSafeInteger$1(tag.data.subarray(16, 20));
|
||||
tagSize -= parseId3.parseSyncSafeInteger(tag.data.subarray(16, 20));
|
||||
} // parse one or more ID3 frames
|
||||
// http://id3.org/id3v2.3.0#ID3v2_frame_overview
|
||||
|
||||
|
||||
do {
|
||||
// determine the number of bytes in this frame
|
||||
frameSize = parseSyncSafeInteger$1(tag.data.subarray(frameStart + 4, frameStart + 8));
|
||||
frameSize = parseId3.parseSyncSafeInteger(tag.data.subarray(frameStart + 4, frameStart + 8));
|
||||
|
||||
if (frameSize < 1) {
|
||||
this.trigger('log', {
|
||||
level: 'warn',
|
||||
message: 'Malformed ID3 frame encountered. Skipping metadata parsing.'
|
||||
});
|
||||
return;
|
||||
message: 'Malformed ID3 frame encountered. Skipping remaining metadata parsing.'
|
||||
}); // If the frame is malformed, don't parse any further frames but allow previous valid parsed frames
|
||||
// to be sent along.
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
frameHeader = String.fromCharCode(tag.data[frameStart], tag.data[frameStart + 1], tag.data[frameStart + 2], tag.data[frameStart + 3]);
|
||||
|
@ -4392,29 +4730,37 @@
|
|||
id: frameHeader,
|
||||
data: tag.data.subarray(frameStart + 10, frameStart + frameSize + 10)
|
||||
};
|
||||
frame.key = frame.id;
|
||||
frame.key = frame.id; // parse frame values
|
||||
|
||||
if (tagParsers[frame.id]) {
|
||||
tagParsers[frame.id](frame); // handle the special PRIV frame used to indicate the start
|
||||
// time for raw AAC data
|
||||
if (parseId3.frameParsers[frame.id]) {
|
||||
// use frame specific parser
|
||||
parseId3.frameParsers[frame.id](frame);
|
||||
} else if (frame.id[0] === 'T') {
|
||||
// use text frame generic parser
|
||||
parseId3.frameParsers['T*'](frame);
|
||||
} else if (frame.id[0] === 'W') {
|
||||
// use URL link frame generic parser
|
||||
parseId3.frameParsers['W*'](frame);
|
||||
} // handle the special PRIV frame used to indicate the start
|
||||
// time for raw AAC data
|
||||
|
||||
if (frame.owner === 'com.apple.streaming.transportStreamTimestamp') {
|
||||
var d = frame.data,
|
||||
size = (d[3] & 0x01) << 30 | d[4] << 22 | d[5] << 14 | d[6] << 6 | d[7] >>> 2;
|
||||
size *= 4;
|
||||
size += d[7] & 0x03;
|
||||
frame.timeStamp = size; // in raw AAC, all subsequent data will be timestamped based
|
||||
// on the value of this frame
|
||||
// we couldn't have known the appropriate pts and dts before
|
||||
// parsing this ID3 tag so set those values now
|
||||
|
||||
if (tag.pts === undefined && tag.dts === undefined) {
|
||||
tag.pts = frame.timeStamp;
|
||||
tag.dts = frame.timeStamp;
|
||||
}
|
||||
if (frame.owner === 'com.apple.streaming.transportStreamTimestamp') {
|
||||
var d = frame.data,
|
||||
size = (d[3] & 0x01) << 30 | d[4] << 22 | d[5] << 14 | d[6] << 6 | d[7] >>> 2;
|
||||
size *= 4;
|
||||
size += d[7] & 0x03;
|
||||
frame.timeStamp = size; // in raw AAC, all subsequent data will be timestamped based
|
||||
// on the value of this frame
|
||||
// we couldn't have known the appropriate pts and dts before
|
||||
// parsing this ID3 tag so set those values now
|
||||
|
||||
this.trigger('timestamp', frame);
|
||||
if (tag.pts === undefined && tag.dts === undefined) {
|
||||
tag.pts = frame.timeStamp;
|
||||
tag.dts = frame.timeStamp;
|
||||
}
|
||||
|
||||
this.trigger('timestamp', frame);
|
||||
}
|
||||
|
||||
tag.frames.push(frame);
|
||||
|
|
4
node_modules/mux.js/dist/mux-mp4.min.js
generated
vendored
4
node_modules/mux.js/dist/mux-mp4.min.js
generated
vendored
File diff suppressed because one or more lines are too long
560
node_modules/mux.js/dist/mux.js
generated
vendored
560
node_modules/mux.js/dist/mux.js
generated
vendored
|
@ -1,4 +1,4 @@
|
|||
/*! @name mux.js @version 6.0.1 @license Apache-2.0 */
|
||||
/*! @name mux.js @version 6.3.0 @license Apache-2.0 */
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('global/window')) :
|
||||
typeof define === 'function' && define.amd ? define(['global/window'], factory) :
|
||||
|
@ -1085,7 +1085,7 @@
|
|||
|
||||
var MAX_UINT32$1 = Math.pow(2, 32);
|
||||
|
||||
var getUint64$4 = function getUint64(uint8) {
|
||||
var getUint64$5 = function getUint64(uint8) {
|
||||
var dv = new DataView(uint8.buffer, uint8.byteOffset, uint8.byteLength);
|
||||
var value;
|
||||
|
||||
|
@ -1103,7 +1103,7 @@
|
|||
};
|
||||
|
||||
var numbers = {
|
||||
getUint64: getUint64$4,
|
||||
getUint64: getUint64$5,
|
||||
MAX_UINT32: MAX_UINT32$1
|
||||
};
|
||||
|
||||
|
@ -1781,6 +1781,133 @@
|
|||
|
||||
var findBox_1 = findBox;
|
||||
|
||||
/**
|
||||
* Returns the first string in the data array ending with a null char '\0'
|
||||
* @param {UInt8} data
|
||||
* @returns the string with the null char
|
||||
*/
|
||||
var uint8ToCString$1 = function uint8ToCString(data) {
|
||||
var index = 0;
|
||||
var curChar = String.fromCharCode(data[index]);
|
||||
var retString = '';
|
||||
|
||||
while (curChar !== '\0') {
|
||||
retString += curChar;
|
||||
index++;
|
||||
curChar = String.fromCharCode(data[index]);
|
||||
} // Add nullChar
|
||||
|
||||
|
||||
retString += curChar;
|
||||
return retString;
|
||||
};
|
||||
|
||||
var string = {
|
||||
uint8ToCString: uint8ToCString$1
|
||||
};
|
||||
|
||||
var uint8ToCString = string.uint8ToCString;
|
||||
var getUint64$4 = numbers.getUint64;
|
||||
/**
|
||||
* Based on: ISO/IEC 23009 Section: 5.10.3.3
|
||||
* References:
|
||||
* https://dashif-documents.azurewebsites.net/Events/master/event.html#emsg-format
|
||||
* https://aomediacodec.github.io/id3-emsg/
|
||||
*
|
||||
* Takes emsg box data as a uint8 array and returns a emsg box object
|
||||
* @param {UInt8Array} boxData data from emsg box
|
||||
* @returns A parsed emsg box object
|
||||
*/
|
||||
|
||||
var parseEmsgBox = function parseEmsgBox(boxData) {
|
||||
// version + flags
|
||||
var offset = 4;
|
||||
var version = boxData[0];
|
||||
var scheme_id_uri, value, timescale, presentation_time, presentation_time_delta, event_duration, id, message_data;
|
||||
|
||||
if (version === 0) {
|
||||
scheme_id_uri = uint8ToCString(boxData.subarray(offset));
|
||||
offset += scheme_id_uri.length;
|
||||
value = uint8ToCString(boxData.subarray(offset));
|
||||
offset += value.length;
|
||||
var dv = new DataView(boxData.buffer);
|
||||
timescale = dv.getUint32(offset);
|
||||
offset += 4;
|
||||
presentation_time_delta = dv.getUint32(offset);
|
||||
offset += 4;
|
||||
event_duration = dv.getUint32(offset);
|
||||
offset += 4;
|
||||
id = dv.getUint32(offset);
|
||||
offset += 4;
|
||||
} else if (version === 1) {
|
||||
var dv = new DataView(boxData.buffer);
|
||||
timescale = dv.getUint32(offset);
|
||||
offset += 4;
|
||||
presentation_time = getUint64$4(boxData.subarray(offset));
|
||||
offset += 8;
|
||||
event_duration = dv.getUint32(offset);
|
||||
offset += 4;
|
||||
id = dv.getUint32(offset);
|
||||
offset += 4;
|
||||
scheme_id_uri = uint8ToCString(boxData.subarray(offset));
|
||||
offset += scheme_id_uri.length;
|
||||
value = uint8ToCString(boxData.subarray(offset));
|
||||
offset += value.length;
|
||||
}
|
||||
|
||||
message_data = new Uint8Array(boxData.subarray(offset, boxData.byteLength));
|
||||
var emsgBox = {
|
||||
scheme_id_uri: scheme_id_uri,
|
||||
value: value,
|
||||
// if timescale is undefined or 0 set to 1
|
||||
timescale: timescale ? timescale : 1,
|
||||
presentation_time: presentation_time,
|
||||
presentation_time_delta: presentation_time_delta,
|
||||
event_duration: event_duration,
|
||||
id: id,
|
||||
message_data: message_data
|
||||
};
|
||||
return isValidEmsgBox(version, emsgBox) ? emsgBox : undefined;
|
||||
};
|
||||
/**
|
||||
* Scales a presentation time or time delta with an offset with a provided timescale
|
||||
* @param {number} presentationTime
|
||||
* @param {number} timescale
|
||||
* @param {number} timeDelta
|
||||
* @param {number} offset
|
||||
* @returns the scaled time as a number
|
||||
*/
|
||||
|
||||
|
||||
var scaleTime = function scaleTime(presentationTime, timescale, timeDelta, offset) {
|
||||
return presentationTime || presentationTime === 0 ? presentationTime / timescale : offset + timeDelta / timescale;
|
||||
};
|
||||
/**
|
||||
* Checks the emsg box data for validity based on the version
|
||||
* @param {number} version of the emsg box to validate
|
||||
* @param {Object} emsg the emsg data to validate
|
||||
* @returns if the box is valid as a boolean
|
||||
*/
|
||||
|
||||
|
||||
var isValidEmsgBox = function isValidEmsgBox(version, emsg) {
|
||||
var hasScheme = emsg.scheme_id_uri !== '\0';
|
||||
var isValidV0Box = version === 0 && isDefined(emsg.presentation_time_delta) && hasScheme;
|
||||
var isValidV1Box = version === 1 && isDefined(emsg.presentation_time) && hasScheme; // Only valid versions of emsg are 0 and 1
|
||||
|
||||
return !(version > 1) && isValidV0Box || isValidV1Box;
|
||||
}; // Utility function to check if an object is defined
|
||||
|
||||
|
||||
var isDefined = function isDefined(data) {
|
||||
return data !== undefined || data !== null;
|
||||
};
|
||||
|
||||
var emsg = {
|
||||
parseEmsgBox: parseEmsgBox,
|
||||
scaleTime: scaleTime
|
||||
};
|
||||
|
||||
var tfhd = function tfhd(data) {
|
||||
var view = new DataView(data.buffer, data.byteOffset, data.byteLength),
|
||||
result = {
|
||||
|
@ -1970,10 +2097,266 @@
|
|||
|
||||
var parseTfdt = tfdt;
|
||||
|
||||
// IE11 doesn't support indexOf for TypedArrays.
|
||||
// Once IE11 support is dropped, this function should be removed.
|
||||
var typedArrayIndexOf$1 = function typedArrayIndexOf(typedArray, element, fromIndex) {
|
||||
if (!typedArray) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var currentIndex = fromIndex;
|
||||
|
||||
for (; currentIndex < typedArray.length; currentIndex++) {
|
||||
if (typedArray[currentIndex] === element) {
|
||||
return currentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
|
||||
var typedArray = {
|
||||
typedArrayIndexOf: typedArrayIndexOf$1
|
||||
};
|
||||
|
||||
var typedArrayIndexOf = typedArray.typedArrayIndexOf,
|
||||
// Frames that allow different types of text encoding contain a text
|
||||
// encoding description byte [ID3v2.4.0 section 4.]
|
||||
textEncodingDescriptionByte = {
|
||||
Iso88591: 0x00,
|
||||
// ISO-8859-1, terminated with \0.
|
||||
Utf16: 0x01,
|
||||
// UTF-16 encoded Unicode BOM, terminated with \0\0
|
||||
Utf16be: 0x02,
|
||||
// UTF-16BE encoded Unicode, without BOM, terminated with \0\0
|
||||
Utf8: 0x03 // UTF-8 encoded Unicode, terminated with \0
|
||||
|
||||
},
|
||||
// return a percent-encoded representation of the specified byte range
|
||||
// @see http://en.wikipedia.org/wiki/Percent-encoding
|
||||
percentEncode$1 = function percentEncode(bytes, start, end) {
|
||||
var i,
|
||||
result = '';
|
||||
|
||||
for (i = start; i < end; i++) {
|
||||
result += '%' + ('00' + bytes[i].toString(16)).slice(-2);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
// return the string representation of the specified byte range,
|
||||
// interpreted as UTf-8.
|
||||
parseUtf8 = function parseUtf8(bytes, start, end) {
|
||||
return decodeURIComponent(percentEncode$1(bytes, start, end));
|
||||
},
|
||||
// return the string representation of the specified byte range,
|
||||
// interpreted as ISO-8859-1.
|
||||
parseIso88591$1 = function parseIso88591(bytes, start, end) {
|
||||
return unescape(percentEncode$1(bytes, start, end)); // jshint ignore:line
|
||||
},
|
||||
parseSyncSafeInteger$1 = function parseSyncSafeInteger(data) {
|
||||
return data[0] << 21 | data[1] << 14 | data[2] << 7 | data[3];
|
||||
},
|
||||
frameParsers = {
|
||||
'APIC': function APIC(frame) {
|
||||
var i = 1,
|
||||
mimeTypeEndIndex,
|
||||
descriptionEndIndex,
|
||||
LINK_MIME_TYPE = '-->';
|
||||
|
||||
if (frame.data[0] !== textEncodingDescriptionByte.Utf8) {
|
||||
// ignore frames with unrecognized character encodings
|
||||
return;
|
||||
} // parsing fields [ID3v2.4.0 section 4.14.]
|
||||
|
||||
|
||||
mimeTypeEndIndex = typedArrayIndexOf(frame.data, 0, i);
|
||||
|
||||
if (mimeTypeEndIndex < 0) {
|
||||
// malformed frame
|
||||
return;
|
||||
} // parsing Mime type field (terminated with \0)
|
||||
|
||||
|
||||
frame.mimeType = parseIso88591$1(frame.data, i, mimeTypeEndIndex);
|
||||
i = mimeTypeEndIndex + 1; // parsing 1-byte Picture Type field
|
||||
|
||||
frame.pictureType = frame.data[i];
|
||||
i++;
|
||||
descriptionEndIndex = typedArrayIndexOf(frame.data, 0, i);
|
||||
|
||||
if (descriptionEndIndex < 0) {
|
||||
// malformed frame
|
||||
return;
|
||||
} // parsing Description field (terminated with \0)
|
||||
|
||||
|
||||
frame.description = parseUtf8(frame.data, i, descriptionEndIndex);
|
||||
i = descriptionEndIndex + 1;
|
||||
|
||||
if (frame.mimeType === LINK_MIME_TYPE) {
|
||||
// parsing Picture Data field as URL (always represented as ISO-8859-1 [ID3v2.4.0 section 4.])
|
||||
frame.url = parseIso88591$1(frame.data, i, frame.data.length);
|
||||
} else {
|
||||
// parsing Picture Data field as binary data
|
||||
frame.pictureData = frame.data.subarray(i, frame.data.length);
|
||||
}
|
||||
},
|
||||
'T*': function T(frame) {
|
||||
if (frame.data[0] !== textEncodingDescriptionByte.Utf8) {
|
||||
// ignore frames with unrecognized character encodings
|
||||
return;
|
||||
} // parse text field, do not include null terminator in the frame value
|
||||
// frames that allow different types of encoding contain terminated text [ID3v2.4.0 section 4.]
|
||||
|
||||
|
||||
frame.value = parseUtf8(frame.data, 1, frame.data.length).replace(/\0*$/, ''); // text information frames supports multiple strings, stored as a terminator separated list [ID3v2.4.0 section 4.2.]
|
||||
|
||||
frame.values = frame.value.split('\0');
|
||||
},
|
||||
'TXXX': function TXXX(frame) {
|
||||
var descriptionEndIndex;
|
||||
|
||||
if (frame.data[0] !== textEncodingDescriptionByte.Utf8) {
|
||||
// ignore frames with unrecognized character encodings
|
||||
return;
|
||||
}
|
||||
|
||||
descriptionEndIndex = typedArrayIndexOf(frame.data, 0, 1);
|
||||
|
||||
if (descriptionEndIndex === -1) {
|
||||
return;
|
||||
} // parse the text fields
|
||||
|
||||
|
||||
frame.description = parseUtf8(frame.data, 1, descriptionEndIndex); // do not include the null terminator in the tag value
|
||||
// frames that allow different types of encoding contain terminated text
|
||||
// [ID3v2.4.0 section 4.]
|
||||
|
||||
frame.value = parseUtf8(frame.data, descriptionEndIndex + 1, frame.data.length).replace(/\0*$/, '');
|
||||
frame.data = frame.value;
|
||||
},
|
||||
'W*': function W(frame) {
|
||||
// parse URL field; URL fields are always represented as ISO-8859-1 [ID3v2.4.0 section 4.]
|
||||
// if the value is followed by a string termination all the following information should be ignored [ID3v2.4.0 section 4.3]
|
||||
frame.url = parseIso88591$1(frame.data, 0, frame.data.length).replace(/\0.*$/, '');
|
||||
},
|
||||
'WXXX': function WXXX(frame) {
|
||||
var descriptionEndIndex;
|
||||
|
||||
if (frame.data[0] !== textEncodingDescriptionByte.Utf8) {
|
||||
// ignore frames with unrecognized character encodings
|
||||
return;
|
||||
}
|
||||
|
||||
descriptionEndIndex = typedArrayIndexOf(frame.data, 0, 1);
|
||||
|
||||
if (descriptionEndIndex === -1) {
|
||||
return;
|
||||
} // parse the description and URL fields
|
||||
|
||||
|
||||
frame.description = parseUtf8(frame.data, 1, descriptionEndIndex); // URL fields are always represented as ISO-8859-1 [ID3v2.4.0 section 4.]
|
||||
// if the value is followed by a string termination all the following information
|
||||
// should be ignored [ID3v2.4.0 section 4.3]
|
||||
|
||||
frame.url = parseIso88591$1(frame.data, descriptionEndIndex + 1, frame.data.length).replace(/\0.*$/, '');
|
||||
},
|
||||
'PRIV': function PRIV(frame) {
|
||||
var i;
|
||||
|
||||
for (i = 0; i < frame.data.length; i++) {
|
||||
if (frame.data[i] === 0) {
|
||||
// parse the description and URL fields
|
||||
frame.owner = parseIso88591$1(frame.data, 0, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
frame.privateData = frame.data.subarray(i + 1);
|
||||
frame.data = frame.privateData;
|
||||
}
|
||||
};
|
||||
|
||||
var parseId3Frames$1 = function parseId3Frames(data) {
|
||||
var frameSize,
|
||||
frameHeader,
|
||||
frameStart = 10,
|
||||
tagSize = 0,
|
||||
frames = []; // If we don't have enough data for a header, 10 bytes,
|
||||
// or 'ID3' in the first 3 bytes this is not a valid ID3 tag.
|
||||
|
||||
if (data.length < 10 || data[0] !== 'I'.charCodeAt(0) || data[1] !== 'D'.charCodeAt(0) || data[2] !== '3'.charCodeAt(0)) {
|
||||
return;
|
||||
} // the frame size is transmitted as a 28-bit integer in the
|
||||
// last four bytes of the ID3 header.
|
||||
// The most significant bit of each byte is dropped and the
|
||||
// results concatenated to recover the actual value.
|
||||
|
||||
|
||||
tagSize = parseSyncSafeInteger$1(data.subarray(6, 10)); // ID3 reports the tag size excluding the header but it's more
|
||||
// convenient for our comparisons to include it
|
||||
|
||||
tagSize += 10; // check bit 6 of byte 5 for the extended header flag.
|
||||
|
||||
var hasExtendedHeader = data[5] & 0x40;
|
||||
|
||||
if (hasExtendedHeader) {
|
||||
// advance the frame start past the extended header
|
||||
frameStart += 4; // header size field
|
||||
|
||||
frameStart += parseSyncSafeInteger$1(data.subarray(10, 14));
|
||||
tagSize -= parseSyncSafeInteger$1(data.subarray(16, 20)); // clip any padding off the end
|
||||
} // parse one or more ID3 frames
|
||||
// http://id3.org/id3v2.3.0#ID3v2_frame_overview
|
||||
|
||||
|
||||
do {
|
||||
// determine the number of bytes in this frame
|
||||
frameSize = parseSyncSafeInteger$1(data.subarray(frameStart + 4, frameStart + 8));
|
||||
|
||||
if (frameSize < 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
frameHeader = String.fromCharCode(data[frameStart], data[frameStart + 1], data[frameStart + 2], data[frameStart + 3]);
|
||||
var frame = {
|
||||
id: frameHeader,
|
||||
data: data.subarray(frameStart + 10, frameStart + frameSize + 10)
|
||||
};
|
||||
frame.key = frame.id; // parse frame values
|
||||
|
||||
if (frameParsers[frame.id]) {
|
||||
// use frame specific parser
|
||||
frameParsers[frame.id](frame);
|
||||
} else if (frame.id[0] === 'T') {
|
||||
// use text frame generic parser
|
||||
frameParsers['T*'](frame);
|
||||
} else if (frame.id[0] === 'W') {
|
||||
// use URL link frame generic parser
|
||||
frameParsers['W*'](frame);
|
||||
}
|
||||
|
||||
frames.push(frame);
|
||||
frameStart += 10; // advance past the frame header
|
||||
|
||||
frameStart += frameSize; // advance past the frame body
|
||||
} while (frameStart < tagSize);
|
||||
|
||||
return frames;
|
||||
};
|
||||
|
||||
var parseId3 = {
|
||||
parseId3Frames: parseId3Frames$1,
|
||||
parseSyncSafeInteger: parseSyncSafeInteger$1,
|
||||
frameParsers: frameParsers
|
||||
};
|
||||
|
||||
var toUnsigned = bin.toUnsigned;
|
||||
var toHexString = bin.toHexString;
|
||||
var getUint64$2 = numbers.getUint64;
|
||||
var timescale, startTime, compositionStartTime, getVideoTrackIds, getTracks, getTimescaleFromMediaHeader;
|
||||
var timescale, startTime, compositionStartTime, getVideoTrackIds, getTracks, getTimescaleFromMediaHeader, getEmsgID3;
|
||||
var parseId3Frames = parseId3.parseId3Frames;
|
||||
/**
|
||||
* Parses an MP4 initialization segment and extracts the timescale
|
||||
* values for any declared tracks. Timescale values indicate the
|
||||
|
@ -2292,6 +2675,34 @@
|
|||
});
|
||||
return tracks;
|
||||
};
|
||||
/**
|
||||
* Returns an array of emsg ID3 data from the provided segmentData.
|
||||
* An offset can also be provided as the Latest Arrival Time to calculate
|
||||
* the Event Start Time of v0 EMSG boxes.
|
||||
* See: https://dashif-documents.azurewebsites.net/Events/master/event.html#Inband-event-timing
|
||||
*
|
||||
* @param {Uint8Array} segmentData the segment byte array.
|
||||
* @param {number} offset the segment start time or Latest Arrival Time,
|
||||
* @return {Object[]} an array of ID3 parsed from EMSG boxes
|
||||
*/
|
||||
|
||||
|
||||
getEmsgID3 = function getEmsgID3(segmentData, offset) {
|
||||
if (offset === void 0) {
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
var emsgBoxes = findBox_1(segmentData, ['emsg']);
|
||||
return emsgBoxes.map(function (data) {
|
||||
var parsedBox = emsg.parseEmsgBox(new Uint8Array(data));
|
||||
var parsedId3Frames = parseId3Frames(parsedBox.message_data);
|
||||
return {
|
||||
cueTime: emsg.scaleTime(parsedBox.presentation_time, parsedBox.timescale, parsedBox.presentation_time_delta, offset),
|
||||
duration: emsg.scaleTime(parsedBox.event_duration, parsedBox.timescale),
|
||||
frames: parsedId3Frames
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
var probe$2 = {
|
||||
// export mp4 inspector's findBox and parseType for backwards compatibility
|
||||
|
@ -2302,7 +2713,8 @@
|
|||
compositionStartTime: compositionStartTime,
|
||||
videoTrackIds: getVideoTrackIds,
|
||||
tracks: getTracks,
|
||||
getTimescaleFromMediaHeader: getTimescaleFromMediaHeader
|
||||
getTimescaleFromMediaHeader: getTimescaleFromMediaHeader,
|
||||
getEmsgID3: getEmsgID3
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -5058,83 +5470,7 @@
|
|||
handleRollover: handleRollover$1
|
||||
};
|
||||
|
||||
var percentEncode$1 = function percentEncode(bytes, start, end) {
|
||||
var i,
|
||||
result = '';
|
||||
|
||||
for (i = start; i < end; i++) {
|
||||
result += '%' + ('00' + bytes[i].toString(16)).slice(-2);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
// return the string representation of the specified byte range,
|
||||
// interpreted as UTf-8.
|
||||
parseUtf8 = function parseUtf8(bytes, start, end) {
|
||||
return decodeURIComponent(percentEncode$1(bytes, start, end));
|
||||
},
|
||||
// return the string representation of the specified byte range,
|
||||
// interpreted as ISO-8859-1.
|
||||
parseIso88591$1 = function parseIso88591(bytes, start, end) {
|
||||
return unescape(percentEncode$1(bytes, start, end)); // jshint ignore:line
|
||||
},
|
||||
parseSyncSafeInteger$1 = function parseSyncSafeInteger(data) {
|
||||
return data[0] << 21 | data[1] << 14 | data[2] << 7 | data[3];
|
||||
},
|
||||
tagParsers = {
|
||||
TXXX: function TXXX(tag) {
|
||||
var i;
|
||||
|
||||
if (tag.data[0] !== 3) {
|
||||
// ignore frames with unrecognized character encodings
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 1; i < tag.data.length; i++) {
|
||||
if (tag.data[i] === 0) {
|
||||
// parse the text fields
|
||||
tag.description = parseUtf8(tag.data, 1, i); // do not include the null terminator in the tag value
|
||||
|
||||
tag.value = parseUtf8(tag.data, i + 1, tag.data.length).replace(/\0*$/, '');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tag.data = tag.value;
|
||||
},
|
||||
WXXX: function WXXX(tag) {
|
||||
var i;
|
||||
|
||||
if (tag.data[0] !== 3) {
|
||||
// ignore frames with unrecognized character encodings
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 1; i < tag.data.length; i++) {
|
||||
if (tag.data[i] === 0) {
|
||||
// parse the description and URL fields
|
||||
tag.description = parseUtf8(tag.data, 1, i);
|
||||
tag.url = parseUtf8(tag.data, i + 1, tag.data.length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
PRIV: function PRIV(tag) {
|
||||
var i;
|
||||
|
||||
for (i = 0; i < tag.data.length; i++) {
|
||||
if (tag.data[i] === 0) {
|
||||
// parse the description and URL fields
|
||||
tag.owner = parseIso88591$1(tag.data, 0, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tag.privateData = tag.data.subarray(i + 1);
|
||||
tag.data = tag.privateData;
|
||||
}
|
||||
},
|
||||
_MetadataStream;
|
||||
var _MetadataStream;
|
||||
|
||||
_MetadataStream = function MetadataStream(options) {
|
||||
var settings = {
|
||||
|
@ -5196,7 +5532,7 @@
|
|||
// last four bytes of the ID3 header.
|
||||
// The most significant bit of each byte is dropped and the
|
||||
// results concatenated to recover the actual value.
|
||||
tagSize = parseSyncSafeInteger$1(chunk.data.subarray(6, 10)); // ID3 reports the tag size excluding the header but it's more
|
||||
tagSize = parseId3.parseSyncSafeInteger(chunk.data.subarray(6, 10)); // ID3 reports the tag size excluding the header but it's more
|
||||
// convenient for our comparisons to include it
|
||||
|
||||
tagSize += 10;
|
||||
|
@ -5229,23 +5565,25 @@
|
|||
// advance the frame start past the extended header
|
||||
frameStart += 4; // header size field
|
||||
|
||||
frameStart += parseSyncSafeInteger$1(tag.data.subarray(10, 14)); // clip any padding off the end
|
||||
frameStart += parseId3.parseSyncSafeInteger(tag.data.subarray(10, 14)); // clip any padding off the end
|
||||
|
||||
tagSize -= parseSyncSafeInteger$1(tag.data.subarray(16, 20));
|
||||
tagSize -= parseId3.parseSyncSafeInteger(tag.data.subarray(16, 20));
|
||||
} // parse one or more ID3 frames
|
||||
// http://id3.org/id3v2.3.0#ID3v2_frame_overview
|
||||
|
||||
|
||||
do {
|
||||
// determine the number of bytes in this frame
|
||||
frameSize = parseSyncSafeInteger$1(tag.data.subarray(frameStart + 4, frameStart + 8));
|
||||
frameSize = parseId3.parseSyncSafeInteger(tag.data.subarray(frameStart + 4, frameStart + 8));
|
||||
|
||||
if (frameSize < 1) {
|
||||
this.trigger('log', {
|
||||
level: 'warn',
|
||||
message: 'Malformed ID3 frame encountered. Skipping metadata parsing.'
|
||||
});
|
||||
return;
|
||||
message: 'Malformed ID3 frame encountered. Skipping remaining metadata parsing.'
|
||||
}); // If the frame is malformed, don't parse any further frames but allow previous valid parsed frames
|
||||
// to be sent along.
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
frameHeader = String.fromCharCode(tag.data[frameStart], tag.data[frameStart + 1], tag.data[frameStart + 2], tag.data[frameStart + 3]);
|
||||
|
@ -5253,29 +5591,37 @@
|
|||
id: frameHeader,
|
||||
data: tag.data.subarray(frameStart + 10, frameStart + frameSize + 10)
|
||||
};
|
||||
frame.key = frame.id;
|
||||
frame.key = frame.id; // parse frame values
|
||||
|
||||
if (tagParsers[frame.id]) {
|
||||
tagParsers[frame.id](frame); // handle the special PRIV frame used to indicate the start
|
||||
// time for raw AAC data
|
||||
if (parseId3.frameParsers[frame.id]) {
|
||||
// use frame specific parser
|
||||
parseId3.frameParsers[frame.id](frame);
|
||||
} else if (frame.id[0] === 'T') {
|
||||
// use text frame generic parser
|
||||
parseId3.frameParsers['T*'](frame);
|
||||
} else if (frame.id[0] === 'W') {
|
||||
// use URL link frame generic parser
|
||||
parseId3.frameParsers['W*'](frame);
|
||||
} // handle the special PRIV frame used to indicate the start
|
||||
// time for raw AAC data
|
||||
|
||||
if (frame.owner === 'com.apple.streaming.transportStreamTimestamp') {
|
||||
var d = frame.data,
|
||||
size = (d[3] & 0x01) << 30 | d[4] << 22 | d[5] << 14 | d[6] << 6 | d[7] >>> 2;
|
||||
size *= 4;
|
||||
size += d[7] & 0x03;
|
||||
frame.timeStamp = size; // in raw AAC, all subsequent data will be timestamped based
|
||||
// on the value of this frame
|
||||
// we couldn't have known the appropriate pts and dts before
|
||||
// parsing this ID3 tag so set those values now
|
||||
|
||||
if (tag.pts === undefined && tag.dts === undefined) {
|
||||
tag.pts = frame.timeStamp;
|
||||
tag.dts = frame.timeStamp;
|
||||
}
|
||||
if (frame.owner === 'com.apple.streaming.transportStreamTimestamp') {
|
||||
var d = frame.data,
|
||||
size = (d[3] & 0x01) << 30 | d[4] << 22 | d[5] << 14 | d[6] << 6 | d[7] >>> 2;
|
||||
size *= 4;
|
||||
size += d[7] & 0x03;
|
||||
frame.timeStamp = size; // in raw AAC, all subsequent data will be timestamped based
|
||||
// on the value of this frame
|
||||
// we couldn't have known the appropriate pts and dts before
|
||||
// parsing this ID3 tag so set those values now
|
||||
|
||||
this.trigger('timestamp', frame);
|
||||
if (tag.pts === undefined && tag.dts === undefined) {
|
||||
tag.pts = frame.timeStamp;
|
||||
tag.dts = frame.timeStamp;
|
||||
}
|
||||
|
||||
this.trigger('timestamp', frame);
|
||||
}
|
||||
|
||||
tag.frames.push(frame);
|
||||
|
|
4
node_modules/mux.js/dist/mux.min.js
generated
vendored
4
node_modules/mux.js/dist/mux.min.js
generated
vendored
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue