fix(lib): count the ID3 tag once and honour CRC frames when probing an MP3

The tag's length was subtracted twice from the audio length when the
tag fit in the first read, and not at all when it did not, so durations
came out short or long by the tag; a frame with the protection bit
clear carries a two-byte CRC before its side info, which put the Xing
block two bytes off; and a Xing block without a frame count threw the
whole file's attributes away instead of falling back to the frame
header. Each has a test now.
This commit is contained in:
Michel de Graaf
2026-09-08 01:44:19 +02:00
parent a58aedf479
commit 5a20d69056
2 changed files with 135 additions and 61 deletions
+6 -7
View File
@@ -253,13 +253,12 @@ mod tests {
.join(format!("soulseek-shares-audio-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&root);
std::fs::create_dir_all(&root).unwrap();
// 100 frames of MPEG-1 Layer III at 128 kbps, 44.1 kHz.
let mut mp3 = Vec::new();
for _ in 0..100 {
mp3.extend_from_slice(&[0xFF, 0xFB, 0x90, 0x00]);
mp3.resize(mp3.len() + 413, 0);
}
std::fs::write(root.join("track.mp3"), &mp3).unwrap();
// 100 frames at 128 kbps is 2.6 seconds.
std::fs::write(
root.join("track.mp3"),
super::audio::tests::cbr_mp3(100),
)
.unwrap();
std::fs::write(root.join("cover.jpg"), b"jpeg").unwrap();
let shares = Shares::scan(&root).unwrap();