Callback on source end example
Would have helped with: https://github.com/RustAudio/rodio/pull/600 (see last few messages there)
Hi! Just came here to ask about something I assume might be similar. I am looking for a way to assign some Fn to call when the current Source has reached its end. For pausable / seekable sources, just "sleep until end" isn't enough, as it's useful to have the thread responsive to controls.
My current approach is getting get_pos and comparing to total_duration on a constant loop, but I assume there's a better way. Would love to be able to do something like source.on_end(|| println!("Sink ended")); or sink.on_current_source_ended(/* closure */); that can be assigned once on source creation.
Is there a way to do this already, or is it a planned feature?
OK seems like this works:
let actual_source = /* your actual source */;
sink.append(actual_source);
let callback_source = EmptyCallback::<f32>::new(Box::new(|| println!("actual source has ended!")));
sink.append(callback_source);
It's quite a strange approach to me, since statistics like number of sources added to the sink's queue, are then "wrong", let's say I added 10 actual audio sources, but getting sound_count would return 20.
It's possible to live with that and manage the queue separately somewhere of course. But wondering about the reasons you chose to go for this API specifically. Seems more "direct" to have the Sink itself notify of it progressing through its sources, in the "my current source changed (ended, skipped, etc), here's next source if any".
there is, we really need an example of that (which is what this issue is for)
To run a function once a source end you append a second source of type EmptyCallback it takes as argument: Box<dyn Send + Fn()>. That is rust speak for a Boxed function that can be send from one thread to another.
Once your first source ends the queue 'plays' emptycallback. It does not make sound but runs your function. Once your function is done the queue immediately moves to the next source.
lol you found out about the same time as I typed my explanation.
But wondering about the reasons you chose to go for this API specifically
Its an old choice from before my time as maintainer. It does however make things internally easier. We are designing a more high level API to rodio (its probably going to be called Player and replace the current Sink that will make this easier.
If you have time please let us know what you need: https://github.com/RustAudio/rodio/issues/626
there is, we really need an example of that (which is what this issue is for)
That would be super useful - I hit exactly the same question.