From 514a53344507ae048f4bed3a458e3f04a729ed50 Mon Sep 17 00:00:00 2001 From: Vanilagy <1696106+Vanilagy@users.noreply.github.com> Date: Fri, 11 Jul 2025 10:07:45 +0200 Subject: [PATCH] Reduce MP3 detection false positives --- src/input-format.ts | 8 +++++--- src/mp3/mp3-misc.ts | 4 ++++ src/mp3/mp3-reader.ts | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/input-format.ts b/src/input-format.ts index d9d34ca..8ed94f8 100644 --- a/src/input-format.ts +++ b/src/input-format.ts @@ -13,6 +13,7 @@ import { IsobmffReader } from './isobmff/isobmff-reader'; import { EBMLId, EBMLReader } from './matroska/ebml'; import { MatroskaDemuxer } from './matroska/matroska-demuxer'; import { Mp3Demuxer } from './mp3/mp3-demuxer'; +import { FRAME_HEADER_SIZE } from './mp3/mp3-misc'; import { Mp3Reader } from './mp3/mp3-reader'; import { OggDemuxer } from './ogg/ogg-demuxer'; import { OggReader } from './ogg/ogg-reader'; @@ -245,9 +246,10 @@ export class Mp3InputFormat extends InputFormat { } // Fine, we found one frame header, but we're still not entirely sure this is MP3. Let's check if we can find - // another header nearby: + // another header right after it: mp3Reader.pos = firstHeader.startPos + firstHeader.totalSize; - const secondHeader = mp3Reader.readNextFrameHeader(Math.min(framesStartPos + 4096, sourceSize)); + await mp3Reader.reader.loadRange(mp3Reader.pos, mp3Reader.pos + FRAME_HEADER_SIZE); + const secondHeader = mp3Reader.readNextFrameHeader(mp3Reader.pos + FRAME_HEADER_SIZE); if (!secondHeader) { return false; } @@ -257,7 +259,7 @@ export class Mp3InputFormat extends InputFormat { return false; } - // We have found two matching MP3 frames, a strong indicator that this is an MP3 file + // We have found two matching consecutive MP3 frames, a strong indicator that this is an MP3 file return true; } diff --git a/src/mp3/mp3-misc.ts b/src/mp3/mp3-misc.ts index 687b5f6..fdd9554 100644 --- a/src/mp3/mp3-misc.ts +++ b/src/mp3/mp3-misc.ts @@ -85,6 +85,10 @@ export const readFrameHeader = (word: number, reader: { pos: number; fileSize: n reader.pos += 1; + if (firstByte !== 0xff) { + return null; + } + if ((secondByte & 0xe0) !== 0xe0) { return null; } diff --git a/src/mp3/mp3-reader.ts b/src/mp3/mp3-reader.ts index 11152ab..8425ba1 100644 --- a/src/mp3/mp3-reader.ts +++ b/src/mp3/mp3-reader.ts @@ -65,7 +65,7 @@ export class Mp3Reader { assert(this.fileSize); until ??= this.fileSize; - while (this.pos < until - FRAME_HEADER_SIZE) { + while (this.pos <= until - FRAME_HEADER_SIZE) { const word = this.readU32(); this.pos -= 4;