mirror of
https://github.com/RustAudio/rodio
synced 2024-11-10 06:04:16 +00:00
fixes seek in m4a files, fixes seeking having 1 second granularity
This commit is contained in:
parent
3f4b530a42
commit
82bfa417ff
2 changed files with 43 additions and 32 deletions
|
@ -155,36 +155,47 @@ impl Source for SymphoniaDecoder {
|
|||
.total_duration()
|
||||
.is_some_and(|dur| dur.saturating_sub(pos).as_millis() < 1);
|
||||
|
||||
if seek_beyond_end {
|
||||
self.format.seek(
|
||||
SeekMode::Accurate,
|
||||
SeekTo::Time {
|
||||
time: self.total_duration.unwrap(),
|
||||
track_id: None,
|
||||
},
|
||||
)?;
|
||||
let time = if seek_beyond_end {
|
||||
let time = self.total_duration.expect("if guarentees this is Some");
|
||||
adjust_down_a_bit(time) // some decoders can only seek to just before the end
|
||||
} else {
|
||||
let frac = if pos.subsec_nanos() == 0 {
|
||||
0f64
|
||||
} else {
|
||||
1f64 / pos.subsec_nanos() as f64
|
||||
let res = pos.subsec_nanos() as f64 / 1_000_000_000.0;
|
||||
res
|
||||
};
|
||||
self.format.seek(
|
||||
SeekMode::Accurate,
|
||||
SeekTo::Time {
|
||||
time: Time {
|
||||
seconds: pos.as_secs(),
|
||||
frac,
|
||||
},
|
||||
track_id: None,
|
||||
},
|
||||
)?;
|
||||
}
|
||||
Time {
|
||||
seconds: pos.as_secs(),
|
||||
frac,
|
||||
}
|
||||
};
|
||||
|
||||
self.format.seek(
|
||||
SeekMode::Accurate,
|
||||
SeekTo::Time {
|
||||
time,
|
||||
track_id: None,
|
||||
},
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn adjust_down_a_bit(
|
||||
Time {
|
||||
mut seconds,
|
||||
mut frac,
|
||||
}: Time,
|
||||
) -> Time {
|
||||
frac -= 0.0001;
|
||||
if frac < 0.0 {
|
||||
seconds = seconds.saturating_sub(1);
|
||||
frac = 1.0 - frac;
|
||||
}
|
||||
Time { seconds, frac }
|
||||
}
|
||||
|
||||
impl Iterator for SymphoniaDecoder {
|
||||
type Item = i16;
|
||||
|
||||
|
|
|
@ -36,37 +36,37 @@ fn sink_and_decoder(format: &str) -> (Sink, Decoder<impl Read + Seek>) {
|
|||
// --features symphonia-flac --features symphonia-isomp4 --features minimp3
|
||||
fn format_decoder_info() -> &'static [(&'static str, bool, &'static str)] {
|
||||
&[
|
||||
#[cfg(feature = "minimp3")]
|
||||
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
|
||||
("mp3", false, "minimp3"),
|
||||
#[cfg(feature = "symphonia-mp3")]
|
||||
("mp3", true, "symphonia"),
|
||||
#[cfg(feature = "hound")]
|
||||
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
|
||||
("wav", true, "hound"),
|
||||
#[cfg(feature = "symphonia-wav")]
|
||||
("wav", true, "symphonia"),
|
||||
#[cfg(feature = "lewton")]
|
||||
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
|
||||
("ogg", true, "lewton"),
|
||||
// note: disabled, symphonia returns error unsupported format
|
||||
// note: disabled, broken decoder see issue: #516
|
||||
// #[cfg(feature = "symphonia-vorbis")]
|
||||
// ("ogg", true, "symphonia"),
|
||||
#[cfg(feature = "claxon")]
|
||||
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
|
||||
("flac", false, "claxon"),
|
||||
#[cfg(feature = "symphonia-flac")]
|
||||
("flac", true, "symphonia"),
|
||||
// note: disabled, symphonia returns error unsupported format
|
||||
// #[cfg(feature = "symphonia-isomp4")]
|
||||
// ("m4a", true, "symphonia"),
|
||||
#[cfg(feature = "symphonia-isomp4")]
|
||||
("m4a", true, "symphonia"),
|
||||
]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn seek_returns_err_if_unsupported() {
|
||||
for (format, supported, decoder) in format_decoder_info().iter().cloned() {
|
||||
println!("trying: {format},\t\tby: {decoder},\t\tshould support seek: {supported}");
|
||||
for (format, supported, decoder_name) in format_decoder_info().iter().cloned() {
|
||||
println!("trying: {format},\t\tby: {decoder_name},\t\tshould support seek: {supported}");
|
||||
let (sink, decoder) = sink_and_decoder(format);
|
||||
sink.append(decoder);
|
||||
let res = sink.try_seek(Duration::from_secs(2));
|
||||
assert_eq!(res.is_ok(), supported);
|
||||
let res = sink.try_seek(Duration::from_millis(2500));
|
||||
assert_eq!(res.is_ok(), supported, "decoder: {decoder_name}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ fn seek_beyond_end_saturates() {
|
|||
|
||||
println!("seeking beyond end for: {format}\t decoded by: {decoder_name}");
|
||||
let res = sink.try_seek(Duration::from_secs(999));
|
||||
assert!(res.is_ok());
|
||||
assert!(dbg!(res).is_ok());
|
||||
|
||||
let now = Instant::now();
|
||||
sink.sleep_until_end();
|
||||
|
|
Loading…
Reference in a new issue