fix: detect mp3 with multiple id3 tag

This commit is contained in:
鲁树人 2024-12-15 01:12:33 +09:00
parent 051805a019
commit 8b9348b4fc
3 changed files with 25 additions and 6 deletions

Binary file not shown.

View File

@ -140,4 +140,11 @@ mod tests {
let result = detect_audio_type(mp3_data).expect("failed to parse mp3");
assert_eq!(result, AudioType::MP3);
}
#[test]
fn test_mp3_multiple_id3() {
let mp3_data = include_bytes!("__fixtures__/mp3_with_id3v2_x3.bin");
let result = detect_audio_type(mp3_data).expect("failed to parse mp3");
assert_eq!(result, AudioType::MP3);
}
}

View File

@ -26,10 +26,12 @@ fn parse_id3_sync_safe_int(buffer: &[u8]) -> i32 {
const MIN_ID3_HEADER_LEN: usize = 10;
fn get_id3_header_size(buffer: &[u8], offset: usize) -> Result<usize, AudioError> {
if buffer.len() < MIN_ID3_HEADER_LEN {
if buffer.len() < offset + MIN_ID3_HEADER_LEN {
Err(AudioError::NeedMoreHeader(offset + MIN_ID3_HEADER_LEN))?;
}
let buffer = &buffer[offset..];
// TAG: ID3v1, 128 bytes
if buffer.starts_with(b"TAG") {
return Ok(128);
@ -66,10 +68,20 @@ fn get_ape_v2_size(buffer: &[u8], offset: usize) -> Result<usize, AudioError> {
}
pub fn get_header_metadata_size(buffer: &[u8], offset: usize) -> Result<usize, AudioError> {
let len = get_id3_header_size(buffer, offset)?;
if len != 0 {
Ok(len)
} else {
get_ape_v2_size(buffer, offset)
let mut offset = offset;
// Workaround: Some files have multiple ID3v2 tags, max 5 times.
for _ in 0..5 {
let len = match get_id3_header_size(buffer, offset)? {
0 => get_ape_v2_size(buffer, offset)?,
len => len,
};
if len == 0 {
break;
}
offset += len;
}
Ok(offset)
}