Skip to content

Commit a74beb9

Browse files
committed
fix: 🐛 (mp4) retrieve audio sample rate from esds #1830
1 parent f43799f commit a74beb9

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

packages/xgplayer-mp4-loader/src/utils.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,18 @@ function getSegments (segDuration, timescale, stts, stsc, stsz, stco, stss, ctts
327327
return segments
328328
}
329329

330+
export function getAudioSampleRate (audioSampleEntry) {
331+
let sampleRate = 0
332+
if (audioSampleEntry.type === 'mp4a') {
333+
if (audioSampleEntry.sampleRate > 0) {
334+
sampleRate = audioSampleEntry.sampleRate
335+
} else {
336+
sampleRate = audioSampleEntry.esds.sampleRate
337+
}
338+
}
339+
return sampleRate || 0
340+
}
341+
330342
export function moovToMeta (moov, isFragmentMP4) {
331343
let videoCodec = ''
332344
let audioCodec = ''
@@ -364,7 +376,7 @@ export function moovToMeta (moov, isFragmentMP4) {
364376
e1 = audioTrack.mdia?.minf?.stbl?.stsd.entries[0]
365377
if (e1) {
366378
audioChannelCount = e1.channelCount
367-
audioSampleRate = e1.sampleRate
379+
audioSampleRate = getAudioSampleRate(e1)
368380
audioCodec = e1.esds?.codec
369381
audioTimescale = audioTrack.mdia?.mdhd?.timescale
370382
if (e1.type === 'enca') {

packages/xgplayer-transmuxer/src/mp4/mp4-parser.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,13 +606,28 @@ export class MP4Parser {
606606
ret.codec += (data[start].toString(16) + '.').padStart(3, '0')
607607
data = data.subarray(start + 13)
608608
} else if (tag === 5) {
609+
// AudioSpecificConfig
609610
const config = ret.config = data.subarray(start, start + size)
611+
612+
// ObjectType
610613
let objectType = (config[0] & 0xF8) >> 3
611614
if (objectType === 31 && config.length >= 2) {
612615
objectType = 32 + ((config[0] & 0x7) << 3) + ((config[1] & 0xE0) >> 5)
613616
}
614617
ret.objectType = objectType
615618
ret.codec += objectType.toString(16)
619+
620+
// SamplingFrequencyIndex
621+
if (/^mp4a/ig.test(ret.codec) && config.length >= 2) {
622+
const samplingFrequencyIndex = (config[0] & 0x07) << 1 | ((config[1] & 0x80) >> 7)
623+
ret.samplingFrequencyIndex = samplingFrequencyIndex
624+
625+
// Map sampling frequency index to actual frequency
626+
if (samplingFrequencyIndex < AAC.FREQ.length) {
627+
ret.sampleRate = AAC.FREQ[samplingFrequencyIndex]
628+
}
629+
}
630+
616631
if (ret.codec[ret.codec.length - 1] === '.') {
617632
ret.codec = ret.codec.substring(0, ret.codec.length - 1)
618633
}
@@ -920,7 +935,7 @@ export class MP4Parser {
920935
a.duration = aTrack.mdia.mdhd.duration || (a.mvhdDurtion / a.mvhdTimecale * a.timescale)
921936
const e1 = aTrack.mdia.minf.stbl.stsd.entries[0]
922937
a.sampleSize = e1.sampleSize
923-
a.sampleRate = e1.sampleRate
938+
a.sampleRate = getAudioSampleRate(e1)
924939
a.channelCount = e1.channelCount
925940
a.present = true
926941

@@ -1087,6 +1102,18 @@ export class MP4Parser {
10871102
}
10881103
}
10891104

1105+
export function getAudioSampleRate (audioSampleEntry) {
1106+
let sampleRate = 0
1107+
if (audioSampleEntry.type === 'mp4a') {
1108+
if (audioSampleEntry.sampleRate > 0) {
1109+
sampleRate = audioSampleEntry.sampleRate
1110+
} else {
1111+
sampleRate = audioSampleEntry.esds.sampleRate
1112+
}
1113+
}
1114+
return sampleRate || 0
1115+
}
1116+
10901117
function getSamples (stts, stsc, stsz, stco, ctts, stss) {
10911118
const samples = []
10921119
const cttsEntries = ctts?.entries

0 commit comments

Comments
 (0)