@@ -116,6 +116,8 @@ impl AudioMixerBuilder {
116116 _filter_graph : filter_graph,
117117 _amix : amix,
118118 _aformat : aformat,
119+ start_timestamp : None ,
120+ timestamps : Timestamps :: now ( ) ,
119121 } )
120122 }
121123}
@@ -131,6 +133,8 @@ pub struct AudioMixer {
131133 _filter_graph : ffmpeg:: filter:: Graph ,
132134 _amix : ffmpeg:: filter:: Context ,
133135 _aformat : ffmpeg:: filter:: Context ,
136+ timestamps : Timestamps ,
137+ start_timestamp : Option < Timestamp > ,
134138}
135139
136140impl AudioMixer {
@@ -141,15 +145,15 @@ impl AudioMixer {
141145 ) ;
142146 pub const BUFFER_TIMEOUT : Duration = Duration :: from_millis ( 10 ) ;
143147
144- fn buffer_sources ( & mut self , start : Timestamps ) {
148+ fn buffer_sources ( & mut self ) {
145149 for source in & mut self . sources {
146150 let rate = source. info . rate ( ) ;
147151
148152 while let Ok ( ( frame, timestamp) ) = source. rx . try_recv ( ) {
149153 // if gap between incoming and last, insert silence
150154 if let Some ( ( buffer_last_timestamp, buffer_last_duration) ) = source. buffer_last {
151- let timestamp_elapsed = timestamp. duration_since ( start ) ;
152- let buffer_last_elapsed = buffer_last_timestamp. duration_since ( start ) ;
155+ let timestamp_elapsed = timestamp. duration_since ( self . timestamps ) ;
156+ let buffer_last_elapsed = buffer_last_timestamp. duration_since ( self . timestamps ) ;
153157
154158 if timestamp_elapsed > buffer_last_elapsed {
155159 let elapsed_since_last_frame = timestamp_elapsed - buffer_last_elapsed;
@@ -158,9 +162,9 @@ impl AudioMixer {
158162 && buffer_last_duration - elapsed_since_last_frame
159163 >= Duration :: from_millis ( 1 )
160164 {
161- let gap = ( buffer_last_timestamp. duration_since ( start )
165+ let gap = ( buffer_last_timestamp. duration_since ( self . timestamps )
162166 + buffer_last_duration)
163- - timestamp. duration_since ( start ) ;
167+ - timestamp. duration_since ( self . timestamps ) ;
164168
165169 debug ! ( "Gap between last buffer frame, inserting {gap:?} of silence" ) ;
166170
@@ -183,7 +187,7 @@ impl AudioMixer {
183187 }
184188 }
185189 } else {
186- let gap = timestamp. duration_since ( start ) ;
190+ let gap = timestamp. duration_since ( self . timestamps ) ;
187191
188192 if !gap. is_zero ( ) {
189193 debug ! ( "Gap from beginning of stream, inserting {gap:?} of silence" ) ;
@@ -210,8 +214,9 @@ impl AudioMixer {
210214
211215 frame. set_rate ( rate as u32 ) ;
212216
213- let timestamp =
214- Timestamp :: Instant ( start. instant ( ) + chunk_duration * i as u32 ) ;
217+ let timestamp = Timestamp :: Instant (
218+ self . timestamps . instant ( ) + chunk_duration * i as u32 ,
219+ ) ;
215220 source. buffer_last = Some ( ( timestamp, chunk_duration) ) ;
216221 source. buffer . push_back ( ( frame, timestamp) ) ;
217222 }
@@ -233,14 +238,15 @@ impl AudioMixer {
233238 let duration =
234239 Duration :: from_secs_f64 ( leftover_chunk_size as f64 / rate as f64 ) ;
235240 let timestamp = Timestamp :: Instant (
236- start. instant ( ) + chunk_duration * chunks. floor ( ) as u32 + duration,
241+ self . timestamps . instant ( )
242+ + chunk_duration * chunks. floor ( ) as u32
243+ + duration,
237244 ) ;
238245 source. buffer_last = Some ( ( timestamp, duration) ) ;
239246 source. buffer . push_back ( ( frame, timestamp) ) ;
240247 }
241248 }
242249
243- // dbg!(frame.samples());
244250 source. buffer_last = Some ( (
245251 timestamp,
246252 Duration :: from_secs_f64 ( frame. samples ( ) as f64 / frame. rate ( ) as f64 ) ,
@@ -251,7 +257,23 @@ impl AudioMixer {
251257 }
252258
253259 fn tick ( & mut self , start : Timestamps , now : Instant ) -> Result < ( ) , ( ) > {
254- self . buffer_sources ( start) ;
260+ self . buffer_sources ( ) ;
261+
262+ if self . start_timestamp . is_none ( ) {
263+ self . start_timestamp = self
264+ . sources
265+ . iter ( )
266+ . filter_map ( |s| s. buffer . get ( 0 ) )
267+ . min_by ( |a, b| {
268+ a. 1 . duration_since ( self . timestamps )
269+ . cmp ( & b. 1 . duration_since ( self . timestamps ) )
270+ } )
271+ . map ( |v| v. 1 ) ;
272+ }
273+
274+ let Some ( start_timestamp) = self . start_timestamp else {
275+ return Ok ( ( ) ) ;
276+ } ;
255277
256278 for ( i, source) in self . sources . iter_mut ( ) . enumerate ( ) {
257279 for buffer in source. buffer . drain ( ..) {
@@ -262,12 +284,10 @@ impl AudioMixer {
262284 let mut filtered = ffmpeg:: frame:: Audio :: empty ( ) ;
263285 while self . abuffersink . sink ( ) . frame ( & mut filtered) . is_ok ( ) {
264286 let elapsed = Duration :: from_secs_f64 ( self . samples_out as f64 / filtered. rate ( ) as f64 ) ;
265- let timestamp = start. instant ( ) + elapsed;
287+ let timestamp = start. instant ( ) + start_timestamp . duration_since ( start ) + elapsed;
266288
267289 self . samples_out += filtered. samples ( ) ;
268290
269- // dbg!(filtered.samples(), timestamp);
270-
271291 if self
272292 . output
273293 . send ( ( filtered, Timestamp :: Instant ( timestamp) ) )
0 commit comments