@jxstjh/jhvideo
Version:
HTML5 jhvideo base on MPEG2-TS Stream Player
159 lines • 6.6 kB
JavaScript
import Log from "../utils/logger";
import { MPEG4SamplingFrequencies } from "./mpeg4-audio";
var AACFrame = /** @class */ (function () {
function AACFrame() {
}
return AACFrame;
}());
export { AACFrame };
var AACADTSParser = /** @class */ (function () {
function AACADTSParser(data) {
this.TAG = "AACADTSParser";
this.data_ = data;
this.current_syncword_offset_ = this.findNextSyncwordOffset(0);
if (this.eof_flag_) {
Log.e(this.TAG, "Could not found ADTS syncword until payload end");
}
}
AACADTSParser.prototype.findNextSyncwordOffset = function (syncword_offset) {
var i = syncword_offset;
var data = this.data_;
while (true) {
if (i + 7 >= data.byteLength) {
this.eof_flag_ = true;
return data.byteLength;
}
// search 12-bit 0xFFF syncword
var syncword = ((data[i + 0] << 8) | data[i + 1]) >>> 4;
if (syncword === 0xFFF) {
return i;
}
else {
i++;
}
}
};
AACADTSParser.prototype.readNextAACFrame = function () {
var data = this.data_;
var aac_frame = null;
while (aac_frame == null) {
if (this.eof_flag_) {
break;
}
var syncword_offset = this.current_syncword_offset_;
var offset = syncword_offset;
// adts_fixed_header()
// syncword 0xFFF: 12-bit
var ID = (data[offset + 1] & 0x08) >>> 3;
var layer = (data[offset + 1] & 0x06) >>> 1;
var protection_absent = data[offset + 1] & 0x01;
var profile = (data[offset + 2] & 0xC0) >>> 6;
var sampling_frequency_index = (data[offset + 2] & 0x3C) >>> 2;
var channel_configuration = ((data[offset + 2] & 0x01) << 2)
| ((data[offset + 3] & 0xC0) >>> 6);
// adts_variable_header()
var aac_frame_length = ((data[offset + 3] & 0x03) << 11)
| (data[offset + 4] << 3)
| ((data[offset + 5] & 0xE0) >>> 5);
var number_of_raw_data_blocks_in_frame = data[offset + 6] & 0x03;
if (offset + aac_frame_length > this.data_.byteLength) {
// data not enough for extracting last sample
this.eof_flag_ = true;
this.has_last_incomplete_data = true;
break;
}
var adts_header_length = (protection_absent === 1) ? 7 : 9;
var adts_frame_payload_length = aac_frame_length - adts_header_length;
offset += adts_header_length;
var next_syncword_offset = this.findNextSyncwordOffset(offset + adts_frame_payload_length);
this.current_syncword_offset_ = next_syncword_offset;
if ((ID !== 0 && ID !== 1) || layer !== 0) {
// invalid adts frame ?
continue;
}
var frame_data = data.subarray(offset, offset + adts_frame_payload_length);
aac_frame = new AACFrame();
aac_frame.audio_object_type = (profile + 1);
aac_frame.sampling_freq_index = sampling_frequency_index;
aac_frame.sampling_frequency = MPEG4SamplingFrequencies[sampling_frequency_index];
aac_frame.channel_config = channel_configuration;
aac_frame.data = frame_data;
}
return aac_frame;
};
AACADTSParser.prototype.hasIncompleteData = function () {
return this.has_last_incomplete_data;
};
AACADTSParser.prototype.getIncompleteData = function () {
if (!this.has_last_incomplete_data) {
return null;
}
return this.data_.subarray(this.current_syncword_offset_);
};
return AACADTSParser;
}());
export { AACADTSParser };
var AudioSpecificConfig = /** @class */ (function () {
function AudioSpecificConfig(frame) {
var config = null;
var original_audio_object_type = frame.audio_object_type;
var audio_object_type = frame.audio_object_type;
var sampling_index = frame.sampling_freq_index;
var channel_config = frame.channel_config;
var extension_sampling_index = 0;
var userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf('firefox') !== -1) {
// firefox: use SBR (HE-AAC) if freq less than 24kHz
if (sampling_index >= 6) {
audio_object_type = 5;
config = new Array(4);
extension_sampling_index = sampling_index - 3;
}
else { // use LC-AAC
audio_object_type = 2;
config = new Array(2);
extension_sampling_index = sampling_index;
}
}
else if (userAgent.indexOf('android') !== -1) {
// android: always use LC-AAC
audio_object_type = 2;
config = new Array(2);
extension_sampling_index = sampling_index;
}
else {
// for other browsers, e.g. chrome...
// Always use HE-AAC to make it easier to switch aac codec profile
audio_object_type = 5;
extension_sampling_index = sampling_index;
config = new Array(4);
if (sampling_index >= 6) {
extension_sampling_index = sampling_index - 3;
}
else if (channel_config === 1) { // Mono channel
audio_object_type = 2;
config = new Array(2);
extension_sampling_index = sampling_index;
}
}
config[0] = audio_object_type << 3;
config[0] |= (sampling_index & 0x0F) >>> 1;
config[1] = (sampling_index & 0x0F) << 7;
config[1] |= (channel_config & 0x0F) << 3;
if (audio_object_type === 5) {
config[1] |= ((extension_sampling_index & 0x0F) >>> 1);
config[2] = (extension_sampling_index & 0x01) << 7;
// extended audio object type: force to 2 (LC-AAC)
config[2] |= (2 << 2);
config[3] = 0;
}
this.config = config;
this.sampling_rate = MPEG4SamplingFrequencies[sampling_index];
this.channel_count = channel_config;
this.codec_mimetype = 'mp4a.40.' + audio_object_type;
this.original_codec_mimetype = 'mp4a.40.' + original_audio_object_type;
}
return AudioSpecificConfig;
}());
export { AudioSpecificConfig };
//# sourceMappingURL=aac.js.map