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 {
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
return nil
}

View File

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