diff --git a/lib/media/segment_utils.js b/lib/media/segment_utils.js index 3ddab02dc0..a7c75ee347 100644 --- a/lib/media/segment_utils.js +++ b/lib/media/segment_utils.js @@ -349,7 +349,7 @@ shaka.media.SegmentUtils = class { // This signals an encrypted sample, which we can go inside of to // find the codec used. // Note: If encrypted, you can only have audio or video, not both. - .box('enca', Mp4Parser.visualSampleEntry) + .box('enca', Mp4Parser.audioSampleEntry) .box('encv', Mp4Parser.visualSampleEntry) .box('sinf', Mp4Parser.children) .box('frma', (box) => { diff --git a/lib/util/mp4_parser.js b/lib/util/mp4_parser.js index b21221de3b..e2a6639704 100644 --- a/lib/util/mp4_parser.js +++ b/lib/util/mp4_parser.js @@ -271,6 +271,63 @@ shaka.util.Mp4Parser = class { } + /** + * A callback that tells the Mp4 parser to treat the body of a box as a audio + * sample entry. A audio sample entry has some fixed-sized fields + * describing the audio codec parameters, followed by an arbitrary number of + * appended children. Each child is a box. + * + * @param {!shaka.extern.ParsedBox} box + * @export + */ + static audioSampleEntry(box) { + // The "reader" starts at the payload, so we need to add the header to the + // start position. The header size varies. + const headerSize = shaka.util.Mp4Parser.headerSize(box); + + // 6 bytes reserved + // 2 bytes data reference index + box.reader.skip(8); + // 2 bytes version + const version = box.reader.readUint16(); + // 2 bytes revision (0, could be ignored) + // 4 bytes reserved + box.reader.skip(6); + + if (version == 2) { + // 16 bytes hard-coded values with no comments + // 8 bytes sample rate + // 4 bytes channel count + // 4 bytes hard-coded values with no comments + // 4 bytes bits per sample + // 4 bytes lpcm flags + // 4 bytes sample size + // 4 bytes samples per packet + box.reader.skip(48); + } else { + // 2 bytes channel count + // 2 bytes bits per sample + // 2 bytes compression ID + // 2 bytes packet size + // 2 bytes sample rate + // 2 byte reserved + box.reader.skip(12); + } + + if (version == 1) { + // 4 bytes samples per packet + // 4 bytes bytes per packet + // 4 bytes bytes per frame + // 4 bytes bytes per sample + box.reader.skip(16); + } + + while (box.reader.hasMoreData() && !box.parser.done_) { + box.parser.parseNext(box.start + headerSize, box.reader, box.partialOkay); + } + } + + /** * Create a callback that tells the Mp4 parser to treat the body of a box as a * binary blob and to parse the body's contents using the provided callback.