Skip to content

Commit

Permalink
oto: ensure resuming on browsers
Browse files Browse the repository at this point in the history
AudioContext.resume might fail in theory. This change addresses the
issue where resuming fails by ensuring the promise result.

Updates hajimehoshi/ebiten#3122
  • Loading branch information
hajimehoshi committed Oct 2, 2024
1 parent c2a8efc commit 03f5f70
Showing 1 changed file with 24 additions and 21 deletions.
45 changes: 24 additions & 21 deletions driver_js.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ type context struct {
scriptProcessor js.Value
scriptProcessorCallback js.Func
ready bool
callbacks map[string]js.Func

mux *mux.Mux
}
Expand Down Expand Up @@ -165,28 +164,32 @@ registerProcessor('oto-worklet-processor', OtoWorkletProcessor);
sp.Call("connect", d.audioContext.Get("destination"))
}

setCallback := func(event string) js.Func {
var f js.Func
f = js.FuncOf(func(this js.Value, arguments []js.Value) any {
if !d.ready {
d.audioContext.Call("resume")
d.ready = true
close(ready)
}
js.Global().Get("document").Call("removeEventListener", event, f)
return nil
})
js.Global().Get("document").Call("addEventListener", event, f)
d.callbacks[event] = f
return f
}

// Browsers require user interaction to start the audio.
// https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio
d.callbacks = map[string]js.Func{}
setCallback("touchend")
setCallback("keyup")
setCallback("mouseup")

events := []string{"touchend", "keyup", "mouseup"}

var onEventFired js.Func
var onResumeSuccess js.Func
onResumeSuccess = js.FuncOf(func(this js.Value, arguments []js.Value) any {
d.ready = true
close(ready)
for _, event := range events {
js.Global().Get("document").Call("removeEventListener", event, onEventFired)
}
onEventFired.Release()
onResumeSuccess.Release()
return nil
})
onEventFired = js.FuncOf(func(this js.Value, arguments []js.Value) any {
if !d.ready {
d.audioContext.Call("resume").Call("then", onResumeSuccess)
}
return nil
})
for _, event := range events {
js.Global().Get("document").Call("addEventListener", event, onEventFired)
}

return d, ready, nil
}
Expand Down

0 comments on commit 03f5f70

Please sign in to comment.