From ff585584f6c3f0ac1cf80a7c17d76e48ae6d4d98 Mon Sep 17 00:00:00 2001 From: n1073645 Date: Wed, 18 Mar 2020 12:51:47 +0000 Subject: [PATCH 1/4] MP3 Extractor --- src/core/lib/FileSignatures.mjs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/core/lib/FileSignatures.mjs b/src/core/lib/FileSignatures.mjs index 7ec0af21..f6f2c80f 100644 --- a/src/core/lib/FileSignatures.mjs +++ b/src/core/lib/FileSignatures.mjs @@ -780,7 +780,7 @@ export const FILE_SIGNATURES = { 1: 0xfb } ], - extractor: null + extractor: extractMP3 }, { name: "MPEG-4 Part 14 audio", @@ -3067,6 +3067,30 @@ export function extractWAV(bytes, offset) { } +/** + * MP3 extractor. + * + * @param {Uint8Array} bytes + * @param {Number} offset + * @returns {Uint8Array} + */ +export function extractMP3(bytes, offset) { + const stream = new Stream(bytes.slice(offset)); + + if (stream.readInt(1) === 0xff) { + console.log("gggg"); + } else if (stream.getBytes(3) === [0x49, 0x44, 0x33]) { + stream.moveTo(6); + const tagSize = (stream.readInt(1)<<23) | (stream.readInt(1)<<15) | (stream.readInt(1)<<7) | stream.readInt(1); + stream.moveForwardsBy(tagSize); + + if (stream.getBytes(4) !== [0xff, 0xfb, 0x30, 0xc4]) + console.log("always bad"); + + } +} + + /** * FLV extractor. * From b69e4567c07f837cdf9370ff1cfc748575202726 Mon Sep 17 00:00:00 2001 From: n1073645 Date: Thu, 19 Mar 2020 16:10:22 +0000 Subject: [PATCH 2/4] MP3extractor --- src/core/lib/FileSignatures.mjs | 38 ++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/core/lib/FileSignatures.mjs b/src/core/lib/FileSignatures.mjs index f6f2c80f..ddd61799 100644 --- a/src/core/lib/FileSignatures.mjs +++ b/src/core/lib/FileSignatures.mjs @@ -3077,17 +3077,39 @@ export function extractWAV(bytes, offset) { export function extractMP3(bytes, offset) { const stream = new Stream(bytes.slice(offset)); - if (stream.readInt(1) === 0xff) { - console.log("gggg"); - } else if (stream.getBytes(3) === [0x49, 0x44, 0x33]) { + const bitRateIndexes = ["free", 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, "bad"]; + + const samplingRateFrequencyIndex = [44100, 48000, 32000, "reserved"]; + + if ((stream.getBytes(3).toString() === [0x49, 0x44, 0x33].toString())) { stream.moveTo(6); - const tagSize = (stream.readInt(1)<<23) | (stream.readInt(1)<<15) | (stream.readInt(1)<<7) | stream.readInt(1); + const tagSize = (stream.readInt(1) << 21) | (stream.readInt(1) << 14) | (stream.readInt(1) << 7) | stream.readInt(1); stream.moveForwardsBy(tagSize); - - if (stream.getBytes(4) !== [0xff, 0xfb, 0x30, 0xc4]) - console.log("always bad"); - + } else { + stream.moveTo(0); } + while (stream.hasMore()) { + if (stream.getBytes(2).toString() !== [0xff, 0xfb].toString()) { + stream.moveBackwardsBy(2); + break; + } + const flags = stream.readInt(1); + const bitRate = bitRateIndexes[flags >> 4]; + const sampleRate = samplingRateFrequencyIndex[(flags & 0x0f) >> 2]; + const padding = (flags & 0x02) >> 1; + if (bitRate === "free" || bitRate === "bad" || sampleRate === "reserved") { + stream.moveBackwardsBy(1); + break; + } + const frameSize = Math.floor(((144 * bitRate) / sampleRate) + padding); + if ((stream.position + frameSize) > stream.length) { + stream.moveTo(stream.length); + break; + } else { + stream.moveForwardsBy(frameSize - 3); + } + } + return stream.carve(); } From 090bf3f8ec30039531a05bf7e6ad6449d963c125 Mon Sep 17 00:00:00 2001 From: n1073645 Date: Mon, 23 Mar 2020 10:10:47 +0000 Subject: [PATCH 3/4] MP3 Extractor added --- src/core/lib/FileSignatures.mjs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/core/lib/FileSignatures.mjs b/src/core/lib/FileSignatures.mjs index ddd61799..3e21aca9 100644 --- a/src/core/lib/FileSignatures.mjs +++ b/src/core/lib/FileSignatures.mjs @@ -3077,10 +3077,12 @@ export function extractWAV(bytes, offset) { export function extractMP3(bytes, offset) { const stream = new Stream(bytes.slice(offset)); + // Constants for flag byte. const bitRateIndexes = ["free", 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, "bad"]; const samplingRateFrequencyIndex = [44100, 48000, 32000, "reserved"]; + // ID3 tag, move over it. if ((stream.getBytes(3).toString() === [0x49, 0x44, 0x33].toString())) { stream.moveTo(6); const tagSize = (stream.readInt(1) << 21) | (stream.readInt(1) << 14) | (stream.readInt(1) << 7) | stream.readInt(1); @@ -3088,20 +3090,45 @@ export function extractMP3(bytes, offset) { } else { stream.moveTo(0); } + + // Loop over all the frame headers in the file. while (stream.hasMore()) { + + // If it has an old TAG frame at the end of it, fixed size, 128 bytes. + if (stream.getBytes(3) === [0x54, 0x41, 0x47].toString()) { + stream.moveForwardsBy(125); + break; + } + + // If not start of frame. if (stream.getBytes(2).toString() !== [0xff, 0xfb].toString()) { stream.moveBackwardsBy(2); break; } + + // Read flag byte. const flags = stream.readInt(1); + + // Extract frame bitrate from flag byte. const bitRate = bitRateIndexes[flags >> 4]; + + // Extract frame samplerate from flag byte. const sampleRate = samplingRateFrequencyIndex[(flags & 0x0f) >> 2]; + + // Padding if the frame size is not a multiple of the bitrate. const padding = (flags & 0x02) >> 1; + + // Things that are either not standard or undocumented. if (bitRate === "free" || bitRate === "bad" || sampleRate === "reserved") { stream.moveBackwardsBy(1); break; } + + // Formula: FrameLength = (144 * BitRate / SampleRate ) + Padding const frameSize = Math.floor(((144 * bitRate) / sampleRate) + padding); + + // If the next move goes past the end of the bytestream then extract the entire bytestream. + // We assume complete frames in the above formula because there is no field that suggests otherwise. if ((stream.position + frameSize) > stream.length) { stream.moveTo(stream.length); break; From 7c672c5ee915b87f19eb60cbd689ae666aa3caed Mon Sep 17 00:00:00 2001 From: n1073645 Date: Mon, 23 Mar 2020 10:11:24 +0000 Subject: [PATCH 4/4] MP3 Extractor added --- src/core/lib/FileSignatures.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/FileSignatures.mjs b/src/core/lib/FileSignatures.mjs index 3e21aca9..4d127075 100644 --- a/src/core/lib/FileSignatures.mjs +++ b/src/core/lib/FileSignatures.mjs @@ -3109,10 +3109,10 @@ export function extractMP3(bytes, offset) { // Read flag byte. const flags = stream.readInt(1); - // Extract frame bitrate from flag byte. + // Extract frame bit rate from flag byte. const bitRate = bitRateIndexes[flags >> 4]; - // Extract frame samplerate from flag byte. + // Extract frame sample rate from flag byte. const sampleRate = samplingRateFrequencyIndex[(flags & 0x0f) >> 2]; // Padding if the frame size is not a multiple of the bitrate.