audio: Bug fix: consider seeking streams when reading multiple sources

This commit is contained in:
Hajime Hoshi 2017-06-04 04:05:30 +09:00
parent e0bc85e790
commit 7ad82dab44

View File

@ -63,7 +63,14 @@ func (p *players) Read(b []byte) (int, error) {
p.Lock() p.Lock()
defer p.Unlock() defer p.Unlock()
if len(p.players) == 0 { players := []*Player{}
for player := range p.players {
if _, ok := p.seekings[player]; ok {
continue
}
players = append(players, player)
}
if len(players) == 0 {
l := len(b) l := len(b)
l &= mask l &= mask
copy(b, make([]byte, l)) copy(b, make([]byte, l))
@ -71,10 +78,7 @@ func (p *players) Read(b []byte) (int, error) {
} }
closed := []*Player{} closed := []*Player{}
l := len(b) l := len(b)
for player := range p.players { for _, player := range players {
if _, ok := p.seekings[player]; ok {
continue
}
if err := player.readToBuffer(l); err == io.EOF { if err := player.readToBuffer(l); err == io.EOF {
closed = append(closed, player) closed = append(closed, player)
} else if err != nil { } else if err != nil {
@ -84,10 +88,7 @@ func (p *players) Read(b []byte) (int, error) {
} }
l &= mask l &= mask
b16s := [][]int16{} b16s := [][]int16{}
for player := range p.players { for _, player := range players {
if _, ok := p.seekings[player]; ok {
continue
}
b16s = append(b16s, player.bufferToInt16(l)) b16s = append(b16s, player.bufferToInt16(l))
} }
for i := 0; i < l/2; i++ { for i := 0; i < l/2; i++ {
@ -104,10 +105,7 @@ func (p *players) Read(b []byte) (int, error) {
b[2*i] = byte(x) b[2*i] = byte(x)
b[2*i+1] = byte(x >> 8) b[2*i+1] = byte(x >> 8)
} }
for player := range p.players { for _, player := range players {
if _, ok := p.seekings[player]; ok {
continue
}
player.proceed(l) player.proceed(l)
} }
for _, pl := range closed { for _, pl := range closed {
@ -457,6 +455,7 @@ func (p *Player) Seek(offset time.Duration) error {
o := int64(offset) * bytesPerSample * channelNum * int64(p.sampleRate) / int64(time.Second) o := int64(offset) * bytesPerSample * channelNum * int64(p.sampleRate) / int64(time.Second)
o &= mask o &= mask
p.srcM.Lock() p.srcM.Lock()
// TODO: Seek finishes soon but after that, Read takes long time and players.Read can block.
pos, err := p.src.Seek(o, io.SeekStart) pos, err := p.src.Seek(o, io.SeekStart)
p.srcM.Unlock() p.srcM.Unlock()
if err != nil { if err != nil {