Skip to content

Commit

Permalink
fix: Fix audio properties detection (#6867)
Browse files Browse the repository at this point in the history
  • Loading branch information
avelad authored Jun 20, 2024
1 parent f46dbdc commit e204bf6
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 55 deletions.
81 changes: 33 additions & 48 deletions lib/media/segment_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ shaka.media.SegmentUtils = class {
break;
case 'ac-3':
case 'ec-3':
case 'ac-4':
case 'opus':
case 'flac':
audioCodecs.push(codecLC);
Expand Down Expand Up @@ -207,6 +208,19 @@ shaka.media.SegmentUtils = class {
/** @type {?string} */
let baseBox;

const genericAudioBox = (box) => {
const parsedAudioSampleEntryBox =
shaka.util.Mp4BoxParsers.audioSampleEntry(box.reader);
channelCount = parsedAudioSampleEntryBox.channelCount;
sampleRate = parsedAudioSampleEntryBox.sampleRate;
codecBoxParser(box);
};

const genericVideoBox = (box) => {
baseBox = box.name;
Mp4Parser.visualSampleEntry(box);
};

new Mp4Parser()
.box('moov', Mp4Parser.children)
.box('trak', Mp4Parser.children)
Expand Down Expand Up @@ -235,9 +249,10 @@ shaka.media.SegmentUtils = class {
// AUDIO
// These are the various boxes that signal a codec.
.box('mp4a', (box) => {
const parsedMP4ABox = shaka.util.Mp4BoxParsers.parseMP4A(box.reader);
channelCount = parsedMP4ABox.channelCount;
sampleRate = parsedMP4ABox.sampleRate;
const parsedAudioSampleEntryBox =
shaka.util.Mp4BoxParsers.audioSampleEntry(box.reader);
channelCount = parsedAudioSampleEntryBox.channelCount;
sampleRate = parsedAudioSampleEntryBox.sampleRate;
if (box.reader.hasMoreData()) {
Mp4Parser.children(box);
} else {
Expand All @@ -249,54 +264,24 @@ shaka.media.SegmentUtils = class {
audioCodecs.push(parsedESDSBox.codec);
hasAudio = true;
})
.box('ac-3', codecBoxParser)
.box('ec-3', codecBoxParser)
.box('opus', codecBoxParser)
.box('Opus', codecBoxParser)
.box('fLaC', codecBoxParser)
.box('ac-3', genericAudioBox)
.box('ec-3', genericAudioBox)
.box('ac-4', genericAudioBox)
.box('Opus', genericAudioBox)
.box('fLaC', genericAudioBox)

// VIDEO
// These are the various boxes that signal a codec.
.box('avc1', (box) => {
baseBox = box.name;
Mp4Parser.visualSampleEntry(box);
})
.box('avc3', (box) => {
baseBox = box.name;
Mp4Parser.visualSampleEntry(box);
})
.box('hev1', (box) => {
baseBox = box.name;
Mp4Parser.visualSampleEntry(box);
})
.box('hvc1', (box) => {
baseBox = box.name;
Mp4Parser.visualSampleEntry(box);
})
.box('dva1', (box) => {
baseBox = box.name;
Mp4Parser.visualSampleEntry(box);
})
.box('dvav', (box) => {
baseBox = box.name;
Mp4Parser.visualSampleEntry(box);
})
.box('dvh1', (box) => {
baseBox = box.name;
Mp4Parser.visualSampleEntry(box);
})
.box('dvhe', (box) => {
baseBox = box.name;
Mp4Parser.visualSampleEntry(box);
})
.box('vp09', (box) => {
baseBox = box.name;
Mp4Parser.visualSampleEntry(box);
})
.box('av01', (box) => {
baseBox = box.name;
Mp4Parser.visualSampleEntry(box);
})
.box('avc1', genericVideoBox)
.box('avc3', genericVideoBox)
.box('hev1', genericVideoBox)
.box('hvc1', genericVideoBox)
.box('dva1', genericVideoBox)
.box('dvav', genericVideoBox)
.box('dvh1', genericVideoBox)
.box('dvhe', genericVideoBox)
.box('vp09', genericVideoBox)
.box('av01', genericVideoBox)
.box('avcC', (box) => {
let codecBase = baseBox || '';
switch (baseBox) {
Expand Down
8 changes: 4 additions & 4 deletions lib/util/mp4_box_parsers.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,11 +275,11 @@ shaka.util.Mp4BoxParsers = class {
}

/**
* Parses a MP4A box.
* Parses an audio sample entry box.
* @param {!shaka.util.DataViewReader} reader
* @return {!shaka.util.ParsedMP4ABox}
* @return {!shaka.util.ParsedAudioSampleEntryBox}
*/
static parseMP4A(reader) {
static audioSampleEntry(reader) {
reader.skip(6); // Skip "reserved"
reader.skip(2); // Skip "data_reference_index"
reader.skip(8); // Skip "reserved"
Expand Down Expand Up @@ -841,7 +841,7 @@ shaka.util.ParsedTENCBox;
*
* @exportDoc
*/
shaka.util.ParsedMP4ABox;
shaka.util.ParsedAudioSampleEntryBox;

/**
* @typedef {{
Expand Down
Binary file added test/test/assets/audio-ac-4.mp4
Binary file not shown.
34 changes: 31 additions & 3 deletions test/util/mp4_box_parsers_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,28 @@ describe('Mp4BoxParsers', () => {
const videoSegmentUri = '/base/test/test/assets/sintel-video-segment.mp4';

const audioInitSegmentXheAacUri = '/base/test/test/assets/audio-xhe-aac.mp4';
const audioInitSegmentAC4Uri = '/base/test/test/assets/audio-ac-4.mp4';

/** @type {!ArrayBuffer} */
let videoInitSegment;
/** @type {!ArrayBuffer} */
let videoSegment;
/** @type {!ArrayBuffer} */
let audioInitSegmentXheAac;
/** @type {!ArrayBuffer} */
let audioInitSegmentAC4;

beforeAll(async () => {
const responses = await Promise.all([
shaka.test.Util.fetch(videoInitSegmentUri),
shaka.test.Util.fetch(videoSegmentUri),
shaka.test.Util.fetch(audioInitSegmentXheAacUri),
shaka.test.Util.fetch(audioInitSegmentAC4Uri),
]);
videoInitSegment = responses[0];
videoSegment = responses[1];
audioInitSegmentXheAac = responses[2];
audioInitSegmentAC4 = responses[3];
});

it('parses init segment', () => {
Expand Down Expand Up @@ -177,9 +182,10 @@ describe('Mp4BoxParsers', () => {
.box('stbl', Mp4Parser.children)
.fullBox('stsd', Mp4Parser.sampleDescription)
.box('mp4a', (box) => {
const parsedMP4ABox = shaka.util.Mp4BoxParsers.parseMP4A(box.reader);
channelCount = parsedMP4ABox.channelCount;
sampleRate = parsedMP4ABox.sampleRate;
const parsedAudioSampleEntryBox =
shaka.util.Mp4BoxParsers.audioSampleEntry(box.reader);
channelCount = parsedAudioSampleEntryBox.channelCount;
sampleRate = parsedAudioSampleEntryBox.sampleRate;
if (box.reader.hasMoreData()) {
Mp4Parser.children(box);
}
Expand All @@ -193,6 +199,28 @@ describe('Mp4BoxParsers', () => {
expect(codec).toBe('mp4a.40.42');
});

it('parses ac-4 box for ac-4 segment', () => {
let channelCount;
let sampleRate;

const Mp4Parser = shaka.util.Mp4Parser;
new Mp4Parser()
.box('moov', Mp4Parser.children)
.box('trak', Mp4Parser.children)
.box('mdia', Mp4Parser.children)
.box('minf', Mp4Parser.children)
.box('stbl', Mp4Parser.children)
.fullBox('stsd', Mp4Parser.sampleDescription)
.box('ac-4', (box) => {
const parsedAudioSampleEntryBox =
shaka.util.Mp4BoxParsers.audioSampleEntry(box.reader);
channelCount = parsedAudioSampleEntryBox.channelCount;
sampleRate = parsedAudioSampleEntryBox.sampleRate;
}).parse(audioInitSegmentAC4, /* partialOkay= */ false);
expect(channelCount).toBe(10);
expect(sampleRate).toBe(48000);
});

/**
*
* Explanation on the Uint8Array:
Expand Down

0 comments on commit e204bf6

Please sign in to comment.