rodio icon indicating copy to clipboard operation
rodio copied to clipboard

Callback on source end example

Open yara-blue opened this issue 1 year ago • 5 comments

Would have helped with: https://github.com/RustAudio/rodio/pull/600 (see last few messages there)

yara-blue avatar Dec 03 '24 11:12 yara-blue

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?

geeseofbeverlyroad avatar Dec 06 '24 16:12 geeseofbeverlyroad

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".

geeseofbeverlyroad avatar Dec 06 '24 17:12 geeseofbeverlyroad

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.

yara-blue avatar Dec 06 '24 17:12 yara-blue

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

yara-blue avatar Dec 06 '24 17:12 yara-blue

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.

ch3pjw avatar Jan 01 '25 16:01 ch3pjw