mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-10-02 21:33:52 +02:00
Fix WAV files with embedded ID3 metadata returning empty tags (#110)
* Read ID3v2 tags from WAV file * remove js import Co-authored-by: David P. <[email protected]> * revert slicing in wave-demuxer.ts and add id3.ts for further sharing * Add `writeId3Tag` to the `WavOutputFormat` constructor options * add more context in private and public APIs that it's non-standard * compare actual values in the test with real file * remove unnecesarry double slice requesting * trim test audio file (i tried my best to preserve ID3, including artwork) * Couple of code cleanups * const -> using * Fix linting errors --------- Co-authored-by: David P. <[email protected]>
This commit is contained in:
co-authored by
David P.
parent
cab8319051
commit
6aee4e6a6a
@@ -15,6 +15,7 @@ import { MetadataTags } from '../tags';
|
||||
import { assert, UNDETERMINED_LANGUAGE } from '../misc';
|
||||
import { EncodedPacket, PLACEHOLDER_DATA } from '../packet';
|
||||
import { readAscii, readBytes, Reader, readU16, readU32, readU64 } from '../reader';
|
||||
import { parseId3V2Tag, readId3V2Header } from '../id3';
|
||||
|
||||
export enum WaveFormat {
|
||||
PCM = 0x0001,
|
||||
@@ -107,6 +108,8 @@ export class WaveDemuxer extends Demuxer {
|
||||
totalFileSize = Math.min(riffChunkSize + 8, this.reader.fileSize ?? Infinity);
|
||||
} else if (chunkId === 'LIST') {
|
||||
await this.parseListChunk(startPos, chunkSize, littleEndian);
|
||||
} else if (chunkId === 'ID3 ' || chunkId === 'id3 ') {
|
||||
await this.parseId3Chunk(startPos, chunkSize);
|
||||
}
|
||||
|
||||
currentPos = startPos + chunkSize + (chunkSize & 1); // Handle padding
|
||||
@@ -271,6 +274,21 @@ export class WaveDemuxer extends Demuxer {
|
||||
}
|
||||
}
|
||||
|
||||
private async parseId3Chunk(startPos: number, size: number) {
|
||||
// Parse ID3 tag embedded in WAV file (non-default, but used a lot in practice anyway)
|
||||
let slice = this.reader.requestSlice(startPos, size);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (!slice) return; // File too short
|
||||
|
||||
const id3V2Header = readId3V2Header(slice);
|
||||
if (id3V2Header) {
|
||||
// Extract the content portion (skip the 10-byte header)
|
||||
const contentSlice = slice.slice(startPos + 10, id3V2Header.size);
|
||||
|
||||
parseId3V2Tag(contentSlice, id3V2Header, this.metadataTags);
|
||||
}
|
||||
}
|
||||
|
||||
getCodec(): AudioCodec | null {
|
||||
assert(this.audioInfo);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user