From 35c4d384cf1a07af0e3a2ef1cd2febf63a1859f2 Mon Sep 17 00:00:00 2001 From: Vanilagy <1696106+Vanilagy@users.noreply.github.com> Date: Sun, 2 Feb 2025 17:21:57 +0100 Subject: [PATCH] Mime type & MP3 improvements --- src/isobmff/isobmff-demuxer.ts | 8 +++++++- src/matroska/matroska-demuxer.ts | 8 +++++++- src/mp3/mp3-misc.ts | 11 ++++++++--- src/mp3/mp3-writer.ts | 4 ++-- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/isobmff/isobmff-demuxer.ts b/src/isobmff/isobmff-demuxer.ts index 7bcb0aa..cd3f054 100644 --- a/src/isobmff/isobmff-demuxer.ts +++ b/src/isobmff/isobmff-demuxer.ts @@ -210,7 +210,13 @@ export class IsobmffDemuxer extends Demuxer { override async getMimeType() { await this.readMetadata(); - let string = this.isQuickTime ? 'video/quicktime' : 'video/mp4'; + const base = this.tracks.some(x => x.info?.type === 'video') + ? 'video/' + : this.tracks.some(x => x.info?.type === 'audio') + ? 'audio/' + : 'application/'; + + let string = base + (this.isQuickTime ? 'quicktime' : 'mp4'); if (this.tracks.length > 0) { const codecMimeTypes = await Promise.all(this.tracks.map(x => x.inputTrack!.getCodecMimeType())); diff --git a/src/matroska/matroska-demuxer.ts b/src/matroska/matroska-demuxer.ts index 58863cd..7c9c1df 100644 --- a/src/matroska/matroska-demuxer.ts +++ b/src/matroska/matroska-demuxer.ts @@ -177,7 +177,13 @@ export class MatroskaDemuxer extends Demuxer { override async getMimeType() { await this.readMetadata(); - let string = this.isWebM ? 'video/webm' : 'video/x-matroska'; + const base = this.segments.some(segment => segment.tracks.some(x => x.info?.type === 'video')) + ? 'video/' + : this.segments.some(segment => segment.tracks.some(x => x.info?.type === 'audio')) + ? 'audio/' + : 'application/'; + + let string = base + (this.isWebM ? 'webm' : 'x-matroska'); const tracks = await this.getTracks(); if (tracks.length > 0) { diff --git a/src/mp3/mp3-misc.ts b/src/mp3/mp3-misc.ts index ba58b7a..79f1056 100644 --- a/src/mp3/mp3-misc.ts +++ b/src/mp3/mp3-misc.ts @@ -46,8 +46,13 @@ export type FrameHeader = { emphasis: number; }; -export const computeMp3FrameSize = (bitrate: number, sampleRate: number, padding: number) => { - return Math.floor((144 * bitrate / sampleRate) + padding); +export const computeMp3FrameSize = (layer: number, bitrate: number, sampleRate: number, padding: number) => { + if (layer === 3) { + // Layer 1 + return Math.floor((12 * bitrate / sampleRate + padding) * 4); + } else { + return Math.floor((144 * bitrate / sampleRate) + padding); + } }; export const getXingOffset = (mpegVersionId: number, channel: number) => { @@ -102,7 +107,7 @@ export const readFrameHeader = (word: number, reader: { pos: number; fileSize: n return null; } - const frameLength = computeMp3FrameSize(bitrate, sampleRate, padding); + const frameLength = computeMp3FrameSize(layer, bitrate, sampleRate, padding); if (reader.fileSize !== null && reader.fileSize - startPos < frameLength) { // The frame doesn't fit into the rest of the file diff --git a/src/mp3/mp3-writer.ts b/src/mp3/mp3-writer.ts index f5a603c..849ab91 100644 --- a/src/mp3/mp3-writer.ts +++ b/src/mp3/mp3-writer.ts @@ -56,7 +56,7 @@ export class Mp3Writer { // Let's find the lowest bitrate for which the frame size is sufficiently large to fit all the data const bitrateIndex = bitrates.findIndex((kbr) => { - return computeMp3FrameSize(1000 * kbr, sampleRate, padding) >= neededBytes; + return computeMp3FrameSize(data.layer, 1000 * kbr, sampleRate, padding) >= neededBytes; }); if (bitrateIndex === -1) { throw new Error('No suitable bitrate found.'); @@ -98,7 +98,7 @@ export class Mp3Writer { this.writeU32(data.fileSize ?? 0); this.writer.write(data.toc ?? new Uint8Array(100)); - const frameSize = computeMp3FrameSize(1000 * bitrates[bitrateIndex]!, sampleRate, padding); + const frameSize = computeMp3FrameSize(data.layer, 1000 * bitrates[bitrateIndex]!, sampleRate, padding); this.writer.seek(startPos + frameSize); } }