Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Callback/signal when sink finishes playback of a sound #278

Open
glalonde opened this issue Mar 24, 2020 · 5 comments
Open

Callback/signal when sink finishes playback of a sound #278

glalonde opened this issue Mar 24, 2020 · 5 comments

Comments

@glalonde
Copy link

This would be useful for implementing continuous playback type functionality. e.g. always keep a sound queued up and only enqueue when a sound finishes to minimize polling. Looks like this is sort of already done with the inner Queue class, so would it make sense to expose similar functionality at the sink level?

@doylep
Copy link

doylep commented Jun 27, 2020

I'm considering implementing a simple loop functionality (using the existing methods in Queue). Would this fit your needs or do you need a callback ability that can not be met by the sleep_until_end() function?

(Not a project contributor. I've only just started working with rodio so perhaps it already has looping functionality I haven't discovered.)

@mxnemu
Copy link

mxnemu commented Dec 21, 2023

I don't think sleep_until_end will cut it. Unless I'm wrong, you need to hold a reference to the sink while it waits, that means you can't pause/play/append more stuff to the sink in the meantime.

Also from the doc it's not entirely clear if it stops waiting when being stopped/cleared or if one sound is played to the end, or when the entire queue ends.

I would like to have a callback/singal that fires after a source ends playing, so I can load in the next file from a playlist and only keep a few sources in memory.

@setoelkahfi
Copy link

Do you know if there is a continuation of this discussion?

@dvdsk
Copy link
Collaborator

dvdsk commented Aug 21, 2024

There is: #600 and sort of related #506. Clearly there the whole sink struct needs to be expanded/redone with this in mind.

Unfortunately I do not have the time to do that now. Maybe, just maybe, I'll have some time in a few months. I am okay with it being a breaking change however its quite difficult to get a design that servers all the needs and is easy to port from. One of the other needs for the sink is a more efficient and lower latency method for manipulating playing sources (think changing mixing of two sources). That is probably doable with some atomics, they can even be Relaxed.

All of this needs design, working out, writing docs, writing porting guides and then a ton of testing. The first two are fun the last two not really my cup of tea but very important. And they all take time and familiarity with rodio, its inner workings and usecases. Something in short supply unfortunatly.

@setoelkahfi
Copy link

setoelkahfi commented Aug 22, 2024

@dvdsk I ended up doing pooling and checking the .empty() method:

async fn start_pooling(app: tauri::AppHandle, audio_id: &str) {
    let (send, recv) = oneshot::channel::<()>();
    let id = audio_id.to_string();
    tokio::spawn(async {
        tokio::select! {
            _ = task_inner(app, id) => {},
            _ = recv => {
                info!("finished, break the loop, call it a day");
            }
        }
        info!("finished in the walking task");
    });
    unsafe {
        let _ = PLAYBACK_POOLING_SENDER.set(send);
    }
}

async fn task_inner(app: tauri::AppHandle, audio_id: String) {
    let mut interval = time::interval(Duration::from_secs(1));
    loop {
        interval.tick().await;
        info!("interval, do the work here");
        if let Some(sink) = unsafe { VOCALS_SINK.get() } {
            if sink.empty() {
                info!("Vocals sink is empty. Stopping player.");
                stop_playing(app, &audio_id, true).await;
                unsafe {
                    if let Some(sender) = PLAYBACK_POOLING_SENDER.take() {
                        let _ = sender.send(());
                    }
                }
                return;
            }
            info!("Still playing...");
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants