audio: Bug fix: Seeking might block forever when another seeking is not done yet

This commit is contained in:
Hajime Hoshi 2017-06-24 23:33:19 +09:00
parent cb63c1a300
commit 1f28c687cf
2 changed files with 20 additions and 18 deletions

View File

@ -477,6 +477,15 @@ func (p *Player) Seek(offset time.Duration) error {
if err != nil { if err != nil {
return err return err
} }
// When the player p is not playing, as readToBuffer is never called,
// seekCh will never solved.
// Solve the current seeking here if necessary.
select {
case pos := <-p.seekCh:
p.buf = []uint8{}
p.pos = pos
default:
}
p.seekCh <- pos p.seekCh <- pos
return nil return nil
} }

View File

@ -88,8 +88,8 @@ type Player struct {
input *Input input *Input
audioContext *audio.Context audioContext *audio.Context
audioPlayer *audio.Player audioPlayer *audio.Player
current time.Duration
total time.Duration total time.Duration
seekedCh chan error
seBytes []uint8 seBytes []uint8
seCh chan []uint8 seCh chan []uint8
volume128 int volume128 int
@ -162,14 +162,11 @@ func (p *Player) update() error {
case p.seBytes = <-p.seCh: case p.seBytes = <-p.seCh:
close(p.seCh) close(p.seCh)
p.seCh = nil p.seCh = nil
case err := <-p.seekedCh:
if err != nil {
return err
}
close(p.seekedCh)
p.seekedCh = nil
default: default:
} }
if p.audioPlayer.IsPlaying() {
p.current = p.audioPlayer.Current()
}
p.updateBar() p.updateBar()
p.updatePlayPause() p.updatePlayPause()
p.updateSE() p.updateSE()
@ -219,9 +216,6 @@ func (p *Player) updatePlayPause() {
} }
func (p *Player) updateBar() { func (p *Player) updateBar() {
if p.seekedCh != nil {
return
}
if !p.input.isMouseButtonTriggered(ebiten.MouseButtonLeft) { if !p.input.isMouseButtonTriggered(ebiten.MouseButtonLeft) {
return return
} }
@ -236,10 +230,8 @@ func (p *Player) updateBar() {
return return
} }
pos := time.Duration(x-bx) * p.total / time.Duration(bw) pos := time.Duration(x-bx) * p.total / time.Duration(bw)
p.seekedCh = make(chan error, 1) p.current = pos
go func() { p.audioPlayer.Seek(pos)
p.seekedCh <- p.audioPlayer.Seek(pos)
}()
} }
func (p *Player) close() error { func (p *Player) close() error {
@ -252,11 +244,9 @@ func (p *Player) draw(screen *ebiten.Image) {
op.GeoM.Translate(float64(x), float64(y)) op.GeoM.Translate(float64(x), float64(y))
screen.DrawImage(playerBarImage, op) screen.DrawImage(playerBarImage, op)
currentTimeStr := "00:00" currentTimeStr := "00:00"
c := p.audioPlayer.Current()
prev := p.previousPos
p.previousPos = c
// Current Time // Current Time
c := p.current
m := (c / time.Minute) % 100 m := (c / time.Minute) % 100
s := (c / time.Second) % 60 s := (c / time.Second) % 60
currentTimeStr = fmt.Sprintf("%02d:%02d", m, s) currentTimeStr = fmt.Sprintf("%02d:%02d", m, s)
@ -274,7 +264,10 @@ Press S to toggle Play/Pause
Press P to play SE Press P to play SE
Press Z or X to change volume of the music Press Z or X to change volume of the music
%s`, ebiten.CurrentFPS(), currentTimeStr) %s`, ebiten.CurrentFPS(), currentTimeStr)
if p.audioPlayer.IsPlaying() && prev == c { current := p.audioPlayer.Current()
prev := p.previousPos
p.previousPos = p.audioPlayer.Current()
if p.audioPlayer.IsPlaying() && prev == current {
msg += "\nLoading..." msg += "\nLoading..."
} }
ebitenutil.DebugPrint(screen, msg) ebitenutil.DebugPrint(screen, msg)