First release
This commit is contained in:
commit
fa6c85266e
2339 changed files with 761050 additions and 0 deletions
125
node_modules/mux.js/es/aac/index.js
generated
vendored
Normal file
125
node_modules/mux.js/es/aac/index.js
generated
vendored
Normal file
|
@ -0,0 +1,125 @@
|
|||
/**
|
||||
* mux.js
|
||||
*
|
||||
* Copyright (c) Brightcove
|
||||
* Licensed Apache-2.0 https://github.com/videojs/mux.js/blob/master/LICENSE
|
||||
*
|
||||
* A stream-based aac to mp4 converter. This utility can be used to
|
||||
* deliver mp4s to a SourceBuffer on platforms that support native
|
||||
* Media Source Extensions.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var Stream = require('../utils/stream.js');
|
||||
|
||||
var aacUtils = require('./utils'); // Constants
|
||||
|
||||
|
||||
var _AacStream;
|
||||
/**
|
||||
* Splits an incoming stream of binary data into ADTS and ID3 Frames.
|
||||
*/
|
||||
|
||||
|
||||
_AacStream = function AacStream() {
|
||||
var everything = new Uint8Array(),
|
||||
timeStamp = 0;
|
||||
|
||||
_AacStream.prototype.init.call(this);
|
||||
|
||||
this.setTimestamp = function (timestamp) {
|
||||
timeStamp = timestamp;
|
||||
};
|
||||
|
||||
this.push = function (bytes) {
|
||||
var frameSize = 0,
|
||||
byteIndex = 0,
|
||||
bytesLeft,
|
||||
chunk,
|
||||
packet,
|
||||
tempLength; // If there are bytes remaining from the last segment, prepend them to the
|
||||
// bytes that were pushed in
|
||||
|
||||
if (everything.length) {
|
||||
tempLength = everything.length;
|
||||
everything = new Uint8Array(bytes.byteLength + tempLength);
|
||||
everything.set(everything.subarray(0, tempLength));
|
||||
everything.set(bytes, tempLength);
|
||||
} else {
|
||||
everything = bytes;
|
||||
}
|
||||
|
||||
while (everything.length - byteIndex >= 3) {
|
||||
if (everything[byteIndex] === 'I'.charCodeAt(0) && everything[byteIndex + 1] === 'D'.charCodeAt(0) && everything[byteIndex + 2] === '3'.charCodeAt(0)) {
|
||||
// Exit early because we don't have enough to parse
|
||||
// the ID3 tag header
|
||||
if (everything.length - byteIndex < 10) {
|
||||
break;
|
||||
} // check framesize
|
||||
|
||||
|
||||
frameSize = aacUtils.parseId3TagSize(everything, byteIndex); // Exit early if we don't have enough in the buffer
|
||||
// to emit a full packet
|
||||
// Add to byteIndex to support multiple ID3 tags in sequence
|
||||
|
||||
if (byteIndex + frameSize > everything.length) {
|
||||
break;
|
||||
}
|
||||
|
||||
chunk = {
|
||||
type: 'timed-metadata',
|
||||
data: everything.subarray(byteIndex, byteIndex + frameSize)
|
||||
};
|
||||
this.trigger('data', chunk);
|
||||
byteIndex += frameSize;
|
||||
continue;
|
||||
} else if ((everything[byteIndex] & 0xff) === 0xff && (everything[byteIndex + 1] & 0xf0) === 0xf0) {
|
||||
// Exit early because we don't have enough to parse
|
||||
// the ADTS frame header
|
||||
if (everything.length - byteIndex < 7) {
|
||||
break;
|
||||
}
|
||||
|
||||
frameSize = aacUtils.parseAdtsSize(everything, byteIndex); // Exit early if we don't have enough in the buffer
|
||||
// to emit a full packet
|
||||
|
||||
if (byteIndex + frameSize > everything.length) {
|
||||
break;
|
||||
}
|
||||
|
||||
packet = {
|
||||
type: 'audio',
|
||||
data: everything.subarray(byteIndex, byteIndex + frameSize),
|
||||
pts: timeStamp,
|
||||
dts: timeStamp
|
||||
};
|
||||
this.trigger('data', packet);
|
||||
byteIndex += frameSize;
|
||||
continue;
|
||||
}
|
||||
|
||||
byteIndex++;
|
||||
}
|
||||
|
||||
bytesLeft = everything.length - byteIndex;
|
||||
|
||||
if (bytesLeft > 0) {
|
||||
everything = everything.subarray(byteIndex);
|
||||
} else {
|
||||
everything = new Uint8Array();
|
||||
}
|
||||
};
|
||||
|
||||
this.reset = function () {
|
||||
everything = new Uint8Array();
|
||||
this.trigger('reset');
|
||||
};
|
||||
|
||||
this.endTimeline = function () {
|
||||
everything = new Uint8Array();
|
||||
this.trigger('endedtimeline');
|
||||
};
|
||||
};
|
||||
|
||||
_AacStream.prototype = new Stream();
|
||||
module.exports = _AacStream;
|
160
node_modules/mux.js/es/aac/utils.js
generated
vendored
Normal file
160
node_modules/mux.js/es/aac/utils.js
generated
vendored
Normal file
|
@ -0,0 +1,160 @@
|
|||
/**
|
||||
* mux.js
|
||||
*
|
||||
* Copyright (c) Brightcove
|
||||
* Licensed Apache-2.0 https://github.com/videojs/mux.js/blob/master/LICENSE
|
||||
*
|
||||
* Utilities to detect basic properties and metadata about Aac data.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var ADTS_SAMPLING_FREQUENCIES = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350];
|
||||
|
||||
var parseId3TagSize = function parseId3TagSize(header, byteIndex) {
|
||||
var returnSize = header[byteIndex + 6] << 21 | header[byteIndex + 7] << 14 | header[byteIndex + 8] << 7 | header[byteIndex + 9],
|
||||
flags = header[byteIndex + 5],
|
||||
footerPresent = (flags & 16) >> 4; // if we get a negative returnSize clamp it to 0
|
||||
|
||||
returnSize = returnSize >= 0 ? returnSize : 0;
|
||||
|
||||
if (footerPresent) {
|
||||
return returnSize + 20;
|
||||
}
|
||||
|
||||
return returnSize + 10;
|
||||
};
|
||||
|
||||
var getId3Offset = function getId3Offset(data, offset) {
|
||||
if (data.length - offset < 10 || data[offset] !== 'I'.charCodeAt(0) || data[offset + 1] !== 'D'.charCodeAt(0) || data[offset + 2] !== '3'.charCodeAt(0)) {
|
||||
return offset;
|
||||
}
|
||||
|
||||
offset += parseId3TagSize(data, offset);
|
||||
return getId3Offset(data, offset);
|
||||
}; // TODO: use vhs-utils
|
||||
|
||||
|
||||
var isLikelyAacData = function isLikelyAacData(data) {
|
||||
var offset = getId3Offset(data, 0);
|
||||
return data.length >= offset + 2 && (data[offset] & 0xFF) === 0xFF && (data[offset + 1] & 0xF0) === 0xF0 && // verify that the 2 layer bits are 0, aka this
|
||||
// is not mp3 data but aac data.
|
||||
(data[offset + 1] & 0x16) === 0x10;
|
||||
};
|
||||
|
||||
var parseSyncSafeInteger = function parseSyncSafeInteger(data) {
|
||||
return data[0] << 21 | data[1] << 14 | data[2] << 7 | data[3];
|
||||
}; // return a percent-encoded representation of the specified byte range
|
||||
// @see http://en.wikipedia.org/wiki/Percent-encoding
|
||||
|
||||
|
||||
var percentEncode = 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 ISO-8859-1.
|
||||
|
||||
|
||||
var parseIso88591 = function parseIso88591(bytes, start, end) {
|
||||
return unescape(percentEncode(bytes, start, end)); // jshint ignore:line
|
||||
};
|
||||
|
||||
var parseAdtsSize = function parseAdtsSize(header, byteIndex) {
|
||||
var lowThree = (header[byteIndex + 5] & 0xE0) >> 5,
|
||||
middle = header[byteIndex + 4] << 3,
|
||||
highTwo = header[byteIndex + 3] & 0x3 << 11;
|
||||
return highTwo | middle | lowThree;
|
||||
};
|
||||
|
||||
var parseType = function parseType(header, byteIndex) {
|
||||
if (header[byteIndex] === 'I'.charCodeAt(0) && header[byteIndex + 1] === 'D'.charCodeAt(0) && header[byteIndex + 2] === '3'.charCodeAt(0)) {
|
||||
return 'timed-metadata';
|
||||
} else if (header[byteIndex] & 0xff === 0xff && (header[byteIndex + 1] & 0xf0) === 0xf0) {
|
||||
return 'audio';
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
var parseSampleRate = function parseSampleRate(packet) {
|
||||
var i = 0;
|
||||
|
||||
while (i + 5 < packet.length) {
|
||||
if (packet[i] !== 0xFF || (packet[i + 1] & 0xF6) !== 0xF0) {
|
||||
// If a valid header was not found, jump one forward and attempt to
|
||||
// find a valid ADTS header starting at the next byte
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
return ADTS_SAMPLING_FREQUENCIES[(packet[i + 2] & 0x3c) >>> 2];
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
var parseAacTimestamp = function parseAacTimestamp(packet) {
|
||||
var frameStart, frameSize, frame, frameHeader; // find the start of the first frame and the end of the tag
|
||||
|
||||
frameStart = 10;
|
||||
|
||||
if (packet[5] & 0x40) {
|
||||
// advance the frame start past the extended header
|
||||
frameStart += 4; // header size field
|
||||
|
||||
frameStart += parseSyncSafeInteger(packet.subarray(10, 14));
|
||||
} // 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(packet.subarray(frameStart + 4, frameStart + 8));
|
||||
|
||||
if (frameSize < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
frameHeader = String.fromCharCode(packet[frameStart], packet[frameStart + 1], packet[frameStart + 2], packet[frameStart + 3]);
|
||||
|
||||
if (frameHeader === 'PRIV') {
|
||||
frame = packet.subarray(frameStart + 10, frameStart + frameSize + 10);
|
||||
|
||||
for (var i = 0; i < frame.byteLength; i++) {
|
||||
if (frame[i] === 0) {
|
||||
var owner = parseIso88591(frame, 0, i);
|
||||
|
||||
if (owner === 'com.apple.streaming.transportStreamTimestamp') {
|
||||
var d = frame.subarray(i + 1);
|
||||
var size = (d[3] & 0x01) << 30 | d[4] << 22 | d[5] << 14 | d[6] << 6 | d[7] >>> 2;
|
||||
size *= 4;
|
||||
size += d[7] & 0x03;
|
||||
return size;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frameStart += 10; // advance past the frame header
|
||||
|
||||
frameStart += frameSize; // advance past the frame body
|
||||
} while (frameStart < packet.byteLength);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
isLikelyAacData: isLikelyAacData,
|
||||
parseId3TagSize: parseId3TagSize,
|
||||
parseAdtsSize: parseAdtsSize,
|
||||
parseType: parseType,
|
||||
parseSampleRate: parseSampleRate,
|
||||
parseAacTimestamp: parseAacTimestamp
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue