dndmusicbot/snapcast/client.go

80 lines
1.2 KiB
Go
Raw Normal View History

2023-11-02 20:30:29 +00:00
package snapcast
import (
"context"
"io"
"log"
"os"
"os/exec"
"strconv"
"sync"
"github.com/gopxl/beep"
)
type Stream struct {
sync.Mutex
Out io.ReadCloser
Cancel context.CancelFunc
Cmd *exec.Cmd
f beep.Format
buf []byte
}
func New(host string, port int) (ff beep.Streamer, err error) {
st := new(Stream)
ctx, cancel := context.WithCancel(context.Background())
st.Cancel = cancel
st.Cmd = exec.CommandContext(
ctx,
"/usr/bin/snapclient",
"-h", host,
"-p", strconv.Itoa(port),
"--player", "file:filename=stderr",
"--logfilter", "*:error",
)
st.Cmd.Stdout = os.Stdin
st.Out, err = st.Cmd.StderrPipe()
if err != nil {
return nil, err
}
err = st.Cmd.Start()
if err != nil {
return nil, err
}
st.buf = make([]byte, 4)
st.f = beep.Format{
SampleRate: beep.SampleRate(48000),
NumChannels: 2,
Precision: 2,
}
return st, nil
}
func (d *Stream) Stream(samples [][2]float64) (n int, ok bool) {
for i := range samples {
_, err := d.Out.Read(d.buf)
if err != nil {
log.Println(err)
ok = false
break
}
samples[i], _ = d.f.DecodeSigned(d.buf)
ok = true
}
return len(samples), ok
}
func (d *Stream) Err() error {
return nil
}