Skip to content

Commit

Permalink
Fix size in 'stst' box and handle sample description entry
Browse files Browse the repository at this point in the history
  • Loading branch information
Borewit committed Jan 24, 2025
1 parent a29bcc2 commit ca306bf
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 14 deletions.
10 changes: 5 additions & 5 deletions lib/mp4/AtomToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ const stsdHeader: IGetToken<IAtomStsdHeader> = {
export interface ISampleDescription {
dataFormat: string;
dataReferenceIndex: number;
description: Uint8Array;
description: Uint8Array | undefined;
}

export interface IAtomStsd {
Expand All @@ -499,19 +499,19 @@ export interface IAtomStsd {

/**
* Atom: Sample Description Atom ('stsd')
* Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25691
* Ref: https://developer.apple.com/documentation/quicktime-file-format/sample_description_atom
*/
class SampleDescriptionTable implements IGetToken<ISampleDescription> {

public constructor(public len: number) {
}

public get(buf: Uint8Array, off: number): ISampleDescription {

const descrLen = this.len - 12;
return {
dataFormat: FourCcToken.get(buf, off),
dataReferenceIndex: Token.UINT16_BE.get(buf, off + 10),
description: new Token.Uint8ArrayType(this.len - 12).get(buf, off + 12)
description: descrLen > 0 ? new Token.Uint8ArrayType(descrLen).get(buf, off + 12) : undefined
};
}
}
Expand All @@ -535,7 +535,7 @@ export class StsdAtom implements IGetToken<IAtomStsd> {
for (let n = 0; n < header.numberOfEntries; ++n) {
const size = Token.UINT32_BE.get(buf, off); // Sample description size
off += Token.UINT32_BE.len;
table.push(new SampleDescriptionTable(size).get(buf, off));
table.push(new SampleDescriptionTable(size - Token.UINT32_BE.len).get(buf, off));
off += size;
}

Expand Down
20 changes: 11 additions & 9 deletions lib/mp4/MP4Parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { BasicParser } from '../common/BasicParser.js';
import { Genres } from '../id3v1/ID3v1Parser.js';
import { Atom } from './Atom.js';
import * as AtomToken from './AtomToken.js';
import { Mp4ContentError } from './AtomToken.js';
import { type AnyTagValue, type IChapter, type ITrackInfo, TrackType } from '../type.js';

import type { IGetToken } from '@tokenizer/token';
import { uint8ArrayToHex, uint8ArrayToString } from 'uint8array-extras';
import { Mp4ContentError } from './AtomToken.js';

const debug = initDebug('music-metadata:parser:MP4');
const tagFormat = 'iTunes';
Expand Down Expand Up @@ -545,14 +545,16 @@ export class MP4Parser extends BasicParser {
};

let offset = 0;
const version = AtomToken.SoundSampleDescriptionVersion.get(sampleDescription.description, offset);
offset += AtomToken.SoundSampleDescriptionVersion.len;

if (version.version === 0 || version.version === 1) {
// Sound Sample Description (Version 0)
ssd.description = AtomToken.SoundSampleDescriptionV0.get(sampleDescription.description, offset);
} else {
debug(`Warning: sound-sample-description ${version} not implemented`);
if (sampleDescription.description) {
const version = AtomToken.SoundSampleDescriptionVersion.get(sampleDescription.description, offset);
offset += AtomToken.SoundSampleDescriptionVersion.len;

if (version.version === 0 || version.version === 1) {
// Sound Sample Description (Version 0)
ssd.description = AtomToken.SoundSampleDescriptionV0.get(sampleDescription.description, offset);
} else {
debug(`Warning: sound-sample-description ${version} not implemented`);
}
}
return ssd;
}
Expand Down
Binary file added test/samples/mp4/frag_bunny.mp4
Binary file not shown.
10 changes: 10 additions & 0 deletions test/test-file-mp4.ts
Original file line number Diff line number Diff line change
Expand Up @@ -473,4 +473,14 @@ describe('Parse MPEG-4 files with iTunes metadata', () => {
assert.equal(mm.ratingToStars(common.rating[0].rating), 4, 'Vorbis tag rating conversion');
});

it('\'stsd\' atom: Handle empty sample entry description', async () => {

const filePath = path.join(mp4Samples, 'frag_bunny.mp4');
const {format, common} = await mm.parseFile(filePath);

assert.strictEqual(format.container, 'mp42/avc1/iso5', 'format.container');
assert.strictEqual(format.codec, 'MPEG-4/AAC', 'format.codec');
assert.strictEqual(common.title, undefined, 'common.title');
});

});

0 comments on commit ca306bf

Please sign in to comment.