diff --git a/assets/music-zero-ms.mp3 b/assets/music-zero-ms.mp3 new file mode 100644 index 00000000..c650485b Binary files /dev/null and b/assets/music-zero-ms.mp3 differ diff --git a/src/decoder/symphonia.rs b/src/decoder/symphonia.rs index eb2198ea..9511fe5f 100644 --- a/src/decoder/symphonia.rs +++ b/src/decoder/symphonia.rs @@ -301,10 +301,13 @@ fn skip_back_a_tiny_bit( }: Time, ) -> Time { frac -= 0.0001; + + // Frac must be between 0.0 and 1.0 for Symphonia if frac < 0.0 { seconds = seconds.saturating_sub(1); - frac = 1.0 - frac; + frac += 1.0; } + Time { seconds, frac } } diff --git a/tests/seek.rs b/tests/seek.rs index 59738ded..a5488b20 100644 --- a/tests/seek.rs +++ b/tests/seek.rs @@ -161,6 +161,18 @@ fn seek_does_not_break_channel_order( } } +#[rstest] +fn seek_beyond_end_saturates_fixed_length_mp3() { + let asset = Path::new("assets/music-zero-ms.mp3"); + let file = std::fs::File::open(asset).unwrap(); + let mut decoder = rodio::Decoder::new(BufReader::new(file)).unwrap(); + + let res = decoder.try_seek(Duration::from_millis(195000)); + + assert!(res.is_ok(), "err: {res:?}"); + assert!(time_remaining(decoder) < Duration::from_secs(1)); +} + fn second_channel_beep_range(source: &mut R) -> std::ops::Range where R: Iterator,