1- use std:: io ;
1+ use std:: { io , time :: Duration } ;
22
33use symphonia:: {
44 core:: {
@@ -8,7 +8,6 @@ use symphonia::{
88 formats:: { FormatOptions , FormatReader , SeekMode , SeekTo } ,
99 io:: { MediaSource , MediaSourceStream , MediaSourceStreamOptions } ,
1010 meta:: { StandardTagKey , Value } ,
11- units:: Time ,
1211 } ,
1312 default:: {
1413 codecs:: { MpaDecoder , VorbisDecoder } ,
@@ -133,30 +132,34 @@ impl SymphoniaDecoder {
133132 }
134133
135134 fn ts_to_ms ( & self , ts : u64 ) -> u32 {
136- let time_base = self . decoder . codec_params ( ) . time_base ;
137- let seeked_to_ms = match time_base {
135+ match self . decoder . codec_params ( ) . time_base {
138136 Some ( time_base) => {
139- let time = time_base. calc_time ( ts) ;
140- ( time. seconds as f64 + time . frac ) * 1000.
137+ let time = Duration :: from ( time_base. calc_time ( ts) ) ;
138+ time. as_millis ( ) as u32
141139 }
142140 // Fallback in the unexpected case that the format has no base time set.
143- None => ts as f64 * PAGES_PER_MS ,
144- } ;
145- seeked_to_ms as u32
141+ None => ( ts as f64 * PAGES_PER_MS ) as u32 ,
142+ }
146143 }
147144}
148145
149146impl AudioDecoder for SymphoniaDecoder {
150147 fn seek ( & mut self , position_ms : u32 ) -> Result < u32 , DecoderError > {
151- let seconds = position_ms as u64 / 1000 ;
152- let frac = ( position_ms as f64 % 1000. ) / 1000. ;
153- let time = Time :: new ( seconds, frac) ;
148+ // "Saturate" the position_ms to the duration of the track if it exceeds it.
149+ let mut target = Duration :: from_millis ( position_ms. into ( ) ) ;
150+ let codec_params = self . decoder . codec_params ( ) ;
151+ if let ( Some ( time_base) , Some ( n_frames) ) = ( codec_params. time_base , codec_params. n_frames ) {
152+ let duration = Duration :: from ( time_base. calc_time ( n_frames) ) ;
153+ if target > duration {
154+ target = duration;
155+ }
156+ }
154157
155158 // `track_id: None` implies the default track ID (of the container, not of Spotify).
156159 let seeked_to_ts = self . format . seek (
157160 SeekMode :: Accurate ,
158161 SeekTo :: Time {
159- time,
162+ time : target . into ( ) ,
160163 track_id : None ,
161164 } ,
162165 ) ?;
0 commit comments