}
var player io.WriteCloser
+ playerTx := make(chan []byte, 5)
var cmd *exec.Cmd
if *playCmd != "" {
cmd = makeCmd(*playCmd)
if err != nil {
log.Fatal(err)
}
+ go func() {
+ var pcmbuf []byte
+ var ok bool
+ var err error
+ for {
+ for len(playerTx) > 1 {
+ <-playerTx
+ stream.stats.reorder++
+ }
+ pcmbuf, ok = <-playerTx
+ if !ok {
+ break
+ }
+ if _, err = io.Copy(player,
+ bytes.NewReader(pcmbuf)); err != nil {
+ log.Println("play:", err)
+ }
+ }
+ cmd.Process.Kill()
+ }()
}
var ciph *chacha20.Cipher
tag := make([]byte, poly1305.TagSize)
var ctr uint32
pcm := make([]int16, vors.FrameLen)
- pcmbuf := make([]byte, 2*vors.FrameLen)
nonce := make([]byte, 12)
var pkt []byte
lost := -1
if cmd == nil {
continue
}
+ pcmbuf := make([]byte, 2*lastDur)
pcmConv(pcmbuf, pcm[:lastDur])
- if _, err = io.Copy(player, bytes.NewReader(
- pcmbuf[:2*lastDur])); err != nil {
- log.Println("play:", err)
- }
+ playerTx <- pcmbuf
}
_, err = dec.Decode(pkt, pcm)
if err != nil {
if cmd == nil {
continue
}
+ pcmbuf := make([]byte, 2*len(pcm))
pcmConv(pcmbuf, pcm)
- if _, err = io.Copy(player,
- bytes.NewReader(pcmbuf)); err != nil {
- log.Println("play:", err)
- }
+ playerTx <- pcmbuf
}
if cmd != nil {
- cmd.Process.Kill()
+ close(playerTx)
}
}()
go statsDrawer(stream.stats, stream.name)