diff --git a/dev/convert.html b/dev/convert.html index a14d831..f85cc61 100644 --- a/dev/convert.html +++ b/dev/convert.html @@ -25,7 +25,7 @@ chunked: true, chunkSize: 2**20 }); - const outputFormat = new Mediabunny.FlacOutputFormat(); + const outputFormat = new Mediabunny.Mp4OutputFormat(); const p = document.createElement('p'); p.textContent = 'Capturing...'; @@ -96,6 +96,7 @@ input, output, audio: { + discard: true, //forceTranscode: true, //sampleFormat: 's16', }, @@ -124,7 +125,7 @@ }, */ video: { - discard: true, + //discard: true, }, tags: {} ?? { title: 'Bigggy', @@ -144,6 +145,7 @@ } }, trim: { + end: 10, //start: startTime, //end: startTime + 2, }, diff --git a/src/codec.ts b/src/codec.ts index 0c868b1..e763a98 100644 --- a/src/codec.ts +++ b/src/codec.ts @@ -784,6 +784,37 @@ export const validateVideoChunkMetadata = (metadata: EncodedVideoChunkMetadata | 'Video chunk metadata decoder configuration must specify a valid codedHeight (positive integer).', ); } + if ( + metadata.decoderConfig.displayAspectWidth !== undefined + && ( + !Number.isInteger(metadata.decoderConfig.displayAspectWidth) + || metadata.decoderConfig.displayAspectWidth <= 0 + ) + ) { + throw new TypeError( + 'Video chunk metadata decoder configuration displayAspectWidth, when defined, must be a positive integer.', + ); + } + if ( + metadata.decoderConfig.displayAspectHeight !== undefined + && ( + !Number.isInteger(metadata.decoderConfig.displayAspectHeight) + || metadata.decoderConfig.displayAspectHeight <= 0 + ) + ) { + throw new TypeError( + 'Video chunk metadata decoder configuration displayAspectHeight, when defined, must be a positive integer.', + ); + } + if ( + (metadata.decoderConfig.displayAspectWidth !== undefined) + !== (metadata.decoderConfig.displayAspectHeight !== undefined) + ) { + throw new TypeError( + 'Video chunk metadata decoder configuration must specify both displayAspectWidth and displayAspectHeight,' + + ' or neither.', + ); + } if (metadata.decoderConfig.description !== undefined) { if (!isAllowSharedBufferSource(metadata.decoderConfig.description)) { throw new TypeError( diff --git a/src/isobmff/isobmff-demuxer.ts b/src/isobmff/isobmff-demuxer.ts index 4d215a1..7e468f6 100644 --- a/src/isobmff/isobmff-demuxer.ts +++ b/src/isobmff/isobmff-demuxer.ts @@ -1475,10 +1475,13 @@ export class IsobmffDemuxer extends Demuxer { const num = readU32Be(slice); const den = readU32Be(slice); - if (num > den) { - track.info.squarePixelWidth = Math.round(track.info.width * num / den); - } else { - track.info.squarePixelHeight = Math.round(track.info.height * den / num); + // https://github.com/Vanilagy/mediabunny/issues/362 + if (num > 0 && den > 0) { + if (num > den) { + track.info.squarePixelWidth = Math.round(track.info.width * num / den); + } else { + track.info.squarePixelHeight = Math.round(track.info.height * den / num); + } } }; break; diff --git a/src/matroska/matroska-demuxer.ts b/src/matroska/matroska-demuxer.ts index a88f077..87ebece 100644 --- a/src/matroska/matroska-demuxer.ts +++ b/src/matroska/matroska-demuxer.ts @@ -1051,14 +1051,16 @@ export class MatroskaDemuxer extends Demuxer { const num = this.currentTrack.info.displayWidth * this.currentTrack.info.height; const den = this.currentTrack.info.displayHeight * this.currentTrack.info.width; - if (num > den) { - this.currentTrack.info.squarePixelWidth = Math.round( - this.currentTrack.info.width * num / den, - ); - } else { - this.currentTrack.info.squarePixelHeight = Math.round( - this.currentTrack.info.height * den / num, - ); + if (num > 0 && den > 0) { + if (num > den) { + this.currentTrack.info.squarePixelWidth = Math.round( + this.currentTrack.info.width * num / den, + ); + } else { + this.currentTrack.info.squarePixelHeight = Math.round( + this.currentTrack.info.height * den / num, + ); + } } } diff --git a/src/misc.ts b/src/misc.ts index ee90e1c..129c58c 100644 --- a/src/misc.ts +++ b/src/misc.ts @@ -938,6 +938,8 @@ export type Rational = { }; export const simplifyRational = (rational: Rational): Rational => { + assert(Number.isInteger(rational.num)); + assert(Number.isInteger(rational.den)); assert(rational.den !== 0); let a = Math.abs(rational.num); diff --git a/src/mpeg-ts/mpeg-ts-demuxer.ts b/src/mpeg-ts/mpeg-ts-demuxer.ts index 652c796..80b09e5 100644 --- a/src/mpeg-ts/mpeg-ts-demuxer.ts +++ b/src/mpeg-ts/mpeg-ts-demuxer.ts @@ -474,18 +474,22 @@ export class MpegTsDemuxer extends Demuxer { elementaryStream.info.width = spsInfo.displayWidth; elementaryStream.info.height = spsInfo.displayHeight; - if (spsInfo.pixelAspectRatio.num > spsInfo.pixelAspectRatio.den) { - elementaryStream.info.squarePixelWidth = Math.round( - elementaryStream.info.width - * spsInfo.pixelAspectRatio.num / spsInfo.pixelAspectRatio.den, - ); - elementaryStream.info.squarePixelHeight = elementaryStream.info.height; - } else { - elementaryStream.info.squarePixelWidth = elementaryStream.info.width; - elementaryStream.info.squarePixelHeight = Math.round( - elementaryStream.info.height - * spsInfo.pixelAspectRatio.den / spsInfo.pixelAspectRatio.num, - ); + + const num = spsInfo.pixelAspectRatio.num; + const den = spsInfo.pixelAspectRatio.den; + + if (num > 0 && den > 0) { + if (num > den) { + elementaryStream.info.squarePixelWidth = Math.round( + elementaryStream.info.width * num / den, + ); + elementaryStream.info.squarePixelHeight = elementaryStream.info.height; + } else { + elementaryStream.info.squarePixelWidth = elementaryStream.info.width; + elementaryStream.info.squarePixelHeight = Math.round( + elementaryStream.info.height * den / num, + ); + } } elementaryStream.info.colorSpace = {