add sonos handler to play file

This commit is contained in:
kaedwen committed 2023-07-16 09:50:19 +02:00
1 parent b7e7db4127
commit 783aa5fd79
44 files changed
+12187 -14

No files matched your search

+9
View File
@@ -12,6 +12,7 @@ type Config struct {
AudioOut ConfigAudioOutputStream `arg:"group:AudioOut"`
AudioIn ConfigAudioInputStream `arg:"group:AudioIn"`
Logging ConfigLogging `arg:"group:Logging"`
Ring ConfigRing `arg:"group:Ring"`
Http ConfigHTTP `arg:"group:Http"`
}
@@ -25,6 +26,14 @@ type ConfigLogging struct {
Level string `arg:"--log-level,env:LOG_LEVEL" default:"debug"`
}
type ConfigRing struct {
Device string `arg:"--input-device,env:INPUT_DEVICE" default:"/dev/input/by-path/platform-gpio-keys-user-event"`
Key string `arg:"--ring-key" default:"KEY_F1"`
JingleName string `arg:"--jingle-name,env:JINGLE_NAME" default:"ding-dong.wav"`
JinglePath *string `arg:"--jingle-path,env:JINGLE_PATH"`
SonosTarget string `arg:"--sonos-target,env:SONOS_TARGET" default:"Living Room"`
}
type ConfigHTTP struct {
Host string `arg:"--http-host,env:HTTP_HOST" default:"0.0.0.0"`
Port uint `arg:"--http-port,env:HTTP_PORT" default:"8080"`
+74
View File
@@ -0,0 +1,74 @@
package ring
import (
"context"
"fmt"
"net/url"
"github.com/holoplot/go-evdev"
"github.com/kaedwen/webrtc/pkg/common"
"github.com/kaedwen/webrtc/pkg/ring/sonos"
"go.uber.org/zap"
)
type Player interface {
Play(uri *url.URL) error
}
type RingHandler struct {
lg *zap.Logger
cfg *common.ConfigRing
players []Player
}
func NewRingHandler(lg *zap.Logger, cfg *common.ConfigRing) (*RingHandler, error) {
sp, err := sonos.NewSonosPlayer(lg.With(zap.String("context", "sonos")), cfg.SonosTarget)
if err != nil {
return nil, err
}
return &RingHandler{lg, cfg, []Player{sp}}, nil
}
func (h *RingHandler) Watch(ctx context.Context) error {
d, err := evdev.Open(h.cfg.Device)
if err != nil {
return err
}
vMajor, vMinor, vMicro := d.DriverVersion()
h.lg.Info("input driver running", zap.String("version", fmt.Sprintf("%d.%d.%d", vMajor, vMinor, vMicro)))
key := evdev.KEYFromString[h.cfg.Key]
bu := url.URL{
Scheme: "http",
Host: "192.168.60.141:9099",
}
go func() {
err := d.NonBlock()
if err != nil {
h.lg.Fatal("failed to set non block", zap.Error(err))
}
for {
e, err := d.ReadOne()
if err == nil && e.Code == key && e.Value == 0 {
tu := bu.JoinPath(h.cfg.JingleName)
for _, p := range h.players {
if err := p.Play(tu); err != nil {
h.lg.Error("failed to play", zap.Error(err))
}
}
}
}
}()
go func() {
<-ctx.Done()
_ = d.Close()
}()
return nil
}
+55
View File
@@ -0,0 +1,55 @@
package sonos
import (
"errors"
"net/url"
"time"
so "github.com/szatmary/sonos"
"go.uber.org/zap"
)
type SonosPlayer struct {
lg *zap.Logger
zp *so.ZonePlayer
}
func NewSonosPlayer(lg *zap.Logger, target string) (*SonosPlayer, error) {
zp, err := SearchTarget(lg, target)
if err != nil {
return nil, err
}
return &SonosPlayer{lg, zp}, nil
}
func (p *SonosPlayer) Play(uri *url.URL) error {
err := p.zp.SetAVTransportURI(uri.String())
if err != nil {
return err
}
return p.zp.Play()
}
func SearchTarget(lg *zap.Logger, target string) (*so.ZonePlayer, error) {
son, err := so.NewSonos()
if err != nil {
return nil, err
}
defer son.Close()
found, _ := son.Search()
to := time.After(10 * time.Second)
for {
select {
case <-to:
return nil, errors.New("timeout")
case zp := <-found:
lg.Info("found player", zap.String("name", zp.RoomName()))
if zp.RoomName() == target {
return zp, nil
}
}
}
}
+7 -7
View File
@@ -25,7 +25,7 @@ type SignalingHandle struct {
type HttpServer struct {
http.Server
lg *zap.Logger
cfg *common.ConfigHTTP
cfg *common.Config
Hndl chan *SignalingHandle
}
@@ -37,7 +37,7 @@ func NewSignalingHandle(id string) SignalingHandle {
}
}
func NewHttpServer(lg *zap.Logger, cfg *common.ConfigHTTP) *HttpServer {
func NewHttpServer(lg *zap.Logger, cfg *common.Config) *HttpServer {
h := HttpServer{
Hndl: make(chan *SignalingHandle, 10),
cfg: cfg,
@@ -57,12 +57,12 @@ func NewHttpServer(lg *zap.Logger, cfg *common.ConfigHTTP) *HttpServer {
}
func (h *HttpServer) ListenAndServe(ctx context.Context) error {
if h.cfg.Tls {
if h.cfg.Http.Tls {
// set the configured address
h.Addr = h.cfg.Address()
h.Addr = h.cfg.Http.Address()
if h.cfg.TlsCert != nil && h.cfg.TlsKey != nil {
cert, err := tls.LoadX509KeyPair(*h.cfg.TlsCert, *h.cfg.TlsKey)
if h.cfg.Http.TlsCert != nil && h.cfg.Http.TlsKey != nil {
cert, err := tls.LoadX509KeyPair(*h.cfg.Http.TlsCert, *h.cfg.Http.TlsKey)
if err != nil {
return err
}
@@ -94,7 +94,7 @@ func (h *HttpServer) ListenAndServe(ctx context.Context) error {
}()
} else {
// set the configured address
h.Addr = h.cfg.Address()
h.Addr = h.cfg.Http.Address()
go func() {
// and listen