From 28eda5cfd22cbde50c1b6a7219c36d89ff44b084 Mon Sep 17 00:00:00 2001 From: "huyun.00" Date: Wed, 12 Jun 2024 11:26:24 +0800 Subject: [PATCH] fix opus player issue in chrome --- src/demux/flv-demuxer.js | 54 ++++++++++++++++---------------------- src/remux/mp4-generator.js | 14 +++++++++- 2 files changed, 35 insertions(+), 33 deletions(-) diff --git a/src/demux/flv-demuxer.js b/src/demux/flv-demuxer.js index a954c9e..bdcd66e 100644 --- a/src/demux/flv-demuxer.js +++ b/src/demux/flv-demuxer.js @@ -492,25 +492,9 @@ class FLVDemuxer { let soundSpec = v.getUint8(0); let soundFormat = soundSpec >>> 4; - if (soundFormat === 9) { // Enhanced FLV - if (dataSize <= 5) { - Log.w(this.TAG, 'Flv: Invalid audio packet, missing AudioFourCC in Ehnanced FLV payload!'); - return; - } - let packetType = soundSpec & 0x0F; - let fourcc = String.fromCharCode(... (new Uint8Array(arrayBuffer, dataOffset, dataSize)).slice(1, 5)); - - if (fourcc === 'Opus') { - this._parseOpusAudioPacket(arrayBuffer, dataOffset + 5, dataSize - 5, tagTimestamp, packetType); - } else { - this._onError(DemuxErrors.CODEC_UNSUPPORTED, 'Flv: Unsupported audio codec: ' + fourcc); - } - - return; - } // Legacy FLV - if (soundFormat !== 2 && soundFormat !== 10) { // MP3 or AAC + if (soundFormat !== 2 && soundFormat !== 10 && soundFormat != 13) { // MP3 or AAC this._onError(DemuxErrors.CODEC_UNSUPPORTED, 'Flv: Unsupported audio codec idx: ' + soundFormat); return; } @@ -606,6 +590,20 @@ class FLVDemuxer { } else { Log.e(this.TAG, `Flv: Unsupported AAC data type ${aacData.packetType}`); } + } else if (soundFormat == 13) { + let result = {}; + result.packetType = v.getUint8(1); + + if (result.packetType == 0) { + this._parseOpusSequenceHeader(arrayBuffer, dataOffset + 2, dataSize - 2); + } else if (result.packetType == 1) { + this._parseOpusAudioData(arrayBuffer, dataOffset + 2, dataSize - 2 , tagTimestamp); + } else if (result.packetType == 2) { + // TODO: parse Opus metadata + } else { + this._onError(DemuxErrors.FORMAT_ERROR, `Flv: Invalid OPUS packet type ${packetType}`); + return; + } } else if (soundFormat === 2) { // MP3 if (!meta.codec) { // We need metadata for mp3 audio track, extract info from frame header @@ -850,19 +848,6 @@ class FLVDemuxer { return result; } - _parseOpusAudioPacket(arrayBuffer, dataOffset, dataSize, tagTimestamp, packetType) { - if (packetType === 0) { // OpusSequenceHeader - this._parseOpusSequenceHeader(arrayBuffer, dataOffset, dataSize); - } else if (packetType === 1) { // OpusCodedData - this._parseOpusAudioData(arrayBuffer, dataOffset, dataSize, tagTimestamp); - } else if (packetType === 2) { - // empty, Opus end of sequence - } else { - this._onError(DemuxErrors.FORMAT_ERROR, `Flv: Invalid video packet type ${packetType}`); - return; - } - } - _parseOpusSequenceHeader(arrayBuffer, dataOffset, dataSize) { if (dataSize <= 16) { Log.w(this.TAG, 'Flv: Invalid OpusSequenceHeader, lack of data!'); @@ -888,8 +873,14 @@ class FLVDemuxer { // Identification Header let v = new DataView(arrayBuffer, dataOffset, dataSize); let channelCount = v.getUint8(8 + 1); // Opus Header + 1 + let cs = `${channelCount}`; + Log.v(this.TAG, 'channel count: ' + cs); let samplingFrequence = v.getUint32(8 + 4, true); // Opus Header + 4 + let ss = `${samplingFrequence}`; + Log.v(this.TAG, 'sampling count: ' + ss); let config = new Uint8Array(arrayBuffer, dataOffset + 8, dataSize - 8); + Log.v(this.TAG, 'opus config length: ' + config.byteLength); + Log.v(this.TAG, 'opus config data: ' + config.toString()); config[0] = 0; let misc = { @@ -950,7 +941,6 @@ class FLVDemuxer { let data = new Uint8Array(arrayBuffer, dataOffset, dataSize); let dts = this._timestampBase + tagTimestamp; let opusSample = {unit: data, length: data.byteLength, dts: dts, pts: dts}; - track.samples.push(opusSample); track.length += data.length; } @@ -1652,4 +1642,4 @@ class FLVDemuxer { } } -export default FLVDemuxer; \ No newline at end of file +export default FLVDemuxer; diff --git a/src/remux/mp4-generator.js b/src/remux/mp4-generator.js index 927426c..820a8ac 100644 --- a/src/remux/mp4-generator.js +++ b/src/remux/mp4-generator.js @@ -16,6 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import Log from '../utils/logger.js'; // MP4 boxes generator for ISO BMFF (ISO Base Media File Format, defined in ISO/IEC 14496-12) class MP4 { @@ -453,7 +454,7 @@ class MP4 { static Opus(meta) { let channelCount = meta.channelCount; let sampleRate = meta.audioSampleRate; - + Log.v('MP4Generator', 'Opus channel count: ' + channelCount + ', sample rate: ' + sampleRate); let data = new Uint8Array([ 0x00, 0x00, 0x00, 0x00, // reserved(4) 0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2) @@ -466,6 +467,15 @@ class MP4 { (sampleRate) & 0xFF, 0x00, 0x00 ]); + Log.v('MP4Generator', 'Opus box data: ' + data.toString()); + + if (meta.config) { + meta.config[4] = (sampleRate >>> 24) & 0xFF + meta.config[5] = (sampleRate >>> 16) & 0xFF + meta.config[6] = (sampleRate >>> 8) & 0xFF + meta.config[7] = (sampleRate ) & 0xFF + Log.v('MP4Generator', 'Opus default config meta: ' + meta.config.toString()); + } return MP4.box(MP4.types.Opus, data, MP4.dOps(meta)); } @@ -543,6 +553,8 @@ class MP4 { 0x00, 0x00, // Global Gain : 2 ... mapping ]); + + Log.v('MP4Generator', 'Opus generate meta: ' + data.toString()); return MP4.box(MP4.types.dOps, data); }