Skip to content

Commit

Permalink
Several fixes and adjustments
Browse files Browse the repository at this point in the history
- Predict audio decoder config description only when the codec is AAC
- Validate Opus description before using it
- Validate `target` in the options
  • Loading branch information
Vanilagy committed Sep 19, 2024
1 parent d7aae0f commit fc587af
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 73 deletions.
11 changes: 7 additions & 4 deletions build/mp4-muxer.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 38 additions & 22 deletions build/mp4-muxer.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions build/mp4-muxer.min.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions build/mp4-muxer.min.mjs

Large diffs are not rendered by default.

60 changes: 38 additions & 22 deletions build/mp4-muxer.mjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mp4-muxer",
"version": "5.1.2",
"version": "5.1.3",
"description": "MP4 multiplexer in pure TypeScript with support for WebCodecs API, video & audio.",
"main": "./build/mp4-muxer.js",
"module": "./build/mp4-muxer.mjs",
Expand Down
10 changes: 8 additions & 2 deletions src/box.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,9 +452,15 @@ export const dOps = (track: AudioTrack) => {

// Read preskip and from codec private data from the encoder
// https://www.rfc-editor.org/rfc/rfc7845#section-5
const description = track.info.decoderConfig.description;
const description = track.info.decoderConfig?.description;
if (description) {
const view = new DataView(ArrayBuffer.isView(description) ? description.buffer : description);
if (description.byteLength < 18) {
throw new TypeError('Invalid decoder description provided for Opus; must be at least 18 bytes long.');
}

const view = ArrayBuffer.isView(description)
? new DataView(description.buffer, description.byteOffset, description.byteLength)
: new DataView(description);
preskip = view.getUint16(10, true);
gain = view.getInt16(14, true);
}
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { Muxer } from './muxer';
export * from './target';
export { ArrayBufferTarget, StreamTarget, FileSystemWritableFileStreamTarget } from './target';
34 changes: 21 additions & 13 deletions src/muxer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ export class Muxer<T extends Target> {
throw new TypeError('The muxer requires an options object to be passed to its constructor.');
}

if (!(options.target instanceof Target)) {
throw new TypeError('The target must be provided and an instance of Target.');
}

if (options.video) {
if (!SUPPORTED_VIDEO_CODECS.includes(options.video.codec)) {
throw new TypeError(`Unsupported video codec: ${options.video.codec}`);
Expand Down Expand Up @@ -322,26 +326,14 @@ export class Muxer<T extends Target> {
}

if (this.#options.audio) {
// For the case that we don't get any further decoder details, we can still make a pretty educated guess:
let guessedCodecPrivate = this.#generateMpeg4AudioSpecificConfig(
2, // Object type for AAC-LC, since it's the most common
this.#options.audio.sampleRate,
this.#options.audio.numberOfChannels
);

this.#audioTrack = {
id: this.#options.video ? 2 : 1,
info: {
type: 'audio',
codec: this.#options.audio.codec,
numberOfChannels: this.#options.audio.numberOfChannels,
sampleRate: this.#options.audio.sampleRate,
decoderConfig: {
codec: this.#options.audio.codec,
description: guessedCodecPrivate,
numberOfChannels: this.#options.audio.numberOfChannels,
sampleRate: this.#options.audio.sampleRate
}
decoderConfig: null
},
timescale: this.#options.audio.sampleRate,
samples: [],
Expand All @@ -355,6 +347,22 @@ export class Muxer<T extends Target> {
lastSample: null,
compactlyCodedChunkTable: []
};

if (this.#options.audio.codec === 'aac') {
// For the case that we don't get any further decoder details, we can still make an educated guess:
let guessedCodecPrivate = this.#generateMpeg4AudioSpecificConfig(
2, // Object type for AAC-LC, since it's the most common
this.#options.audio.sampleRate,
this.#options.audio.numberOfChannels
);

this.#audioTrack.info.decoderConfig = {
codec: this.#options.audio.codec,
description: guessedCodecPrivate,
numberOfChannels: this.#options.audio.numberOfChannels,
sampleRate: this.#options.audio.sampleRate
};
}
}
}

Expand Down
Loading

0 comments on commit fc587af

Please sign in to comment.