audio/mp3: Try again decoding when timed out (#464)

This commit is contained in:
Hajime Hoshi 2017-12-26 00:08:25 +09:00
parent 623caad3ec
commit 908ccb9404

View File

@ -21,6 +21,7 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"time"
"github.com/gopherjs/gopherjs/js" "github.com/gopherjs/gopherjs/js"
"github.com/hajimehoshi/ebiten/audio" "github.com/hajimehoshi/ebiten/audio"
@ -34,7 +35,10 @@ type Stream struct {
posInBytes int posInBytes int
} }
var errTryAgain = errors.New("audio/mp3: try again") var (
errTryAgain = errors.New("audio/mp3: try again")
errTimeout = errors.New("audio/mp3: timeout")
)
func (s *Stream) Read(b []byte) (int, error) { func (s *Stream) Read(b []byte) (int, error) {
l := len(s.leftData)*4 - s.posInBytes l := len(s.leftData)*4 - s.posInBytes
@ -127,16 +131,20 @@ func Decode(context *audio.Context, src audio.ReadSeekCloser) (*Stream, error) {
var s *Stream var s *Stream
for { for {
s, err = decode(context, b) s, err = decode(context, b)
if err == errTryAgain { switch err {
case errTryAgain:
buf, ok := seekNextFrame(b) buf, ok := seekNextFrame(b)
if !ok { if !ok {
return nil, fmt.Errorf("audio/mp3: Decode failed: invalid format?") return nil, fmt.Errorf("audio/mp3: Decode failed: invalid format?")
} }
b = buf b = buf
continue continue
} case errTimeout:
if err != nil { continue
return nil, err default:
if err != nil {
return nil, err
}
} }
break break
} }
@ -192,8 +200,15 @@ func decode(context *audio.Context, buf []byte) (*Stream, error) {
} }
}) })
if err := <-ch; err != nil { select {
return nil, err case err := <-ch:
if err != nil {
return nil, err
}
case <-time.After(time.Second):
// Sometimes decode fails without calling the callbacks (#464).
// Let's just try again in this case.
return nil, errTimeout
} }
return s, nil return s, nil
} }