oto
oto copied to clipboard
Callback or Signal for Playback complete
Instead of polling the player, perhaps it would be better to offer either a callback or a channel style API.
// We can wait for the sound to finish playing using something like this
for player.IsPlaying() {
time.Sleep(time.Millisecond)
}
// Channel style.
<-player.Done()
// Callback style.
player.OnDone(func() {...})
You can get underneath the player with a custom io.Reader, but it is a bit annoying - but maybe a good route?
// TriggerReader invokes a callback when EOF is reached.
type TriggerReader struct {
r io.Reader
cb func()
}
func (t *TriggerReader) Read(p []byte) (n int, err error) {
n, err = t.r.Read(p)
if err == io.EOF {
t.Callback()
}
return n, err
}
func (t *TriggerReader) Callback() {
if t.cb != nil {
t.cb()
}
}
done := make(chan struct{})
data := []byte{...}
src := bytes.NewReader(data)
src = &TriggerReader{r: src, cb: func() {close(done)}}
p := ctx.NewPlayer(src)
p.Play()
<-done
I was wondering why you need to detect the timing when the player ends in the first place.
I have a program that wants to exit once playback is finished, but you could also imagine advancing a track in a playlist, or similar.
Another use case could be that we want to wait for the player to finish and all the samples be sent to the driver before suspending so that the last couple of samples don't get lost.
I was discussing this regarding Beep from this comment down: https://github.com/gopxl/beep/issues/137#issuecomment-1908810880