Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add sonos handler to play file #6

Merged
merged 9 commits into from
Jul 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
service*
service*
renew.local.env
8 changes: 6 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@
"program": "${workspaceFolder}/main.go",
"env": {
"HTTP_STATIC": "${workspaceFolder}/static/dist",
"VIDEO_OUT_DEVICE": "/dev/video4",
"AUDIO_OUT_DEVICE": "plughw:0,1,0"
//"VIDEO_OUT_DEVICE": "/dev/video4",
"AUDIO_OUT_DEVICE": "plughw:0,1,0",
"INPUT_DEVICE": "/dev/input/event5",
"JINGLE_PATH": "${workspaceFolder}/audio",
"SONOS_TARGET": "Living Room",
"VIDEO_OUT_CODEC": "h264",
}
},
{
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ build:

build-static:
npm --prefix static ci && npm --prefix static run build
cp -r audio static/dist/audio

build-armhf:
GOARCH=arm \
Expand Down
11 changes: 11 additions & 0 deletions assets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# GPIO setup

## Using Linux Device-Tree
For ring trigger it is necessary to configure a Key Stroke. This can be achived with configuring an gpio.

Copy the `gpio.dts` to `/boot/overlay-user/gpio.dts` and if you are using armbian execute
```
armbian-add-overlay /boot/overlay-user/gpio.dts
```

This will compile the `dts` file to a `dtbo` compiled one and will append the overlay to your `armbianEnv.txt
5 changes: 5 additions & 0 deletions assets/cert/renew.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
HTTPREQ_ENDPOINT=<your httpreq endpoint>
ACME_KID=<your acme kid>
ACME_HMAC=<your acme hmac>
ACME_DOMAINS=<your domain>
ACME_EMAIL=<your email>
10 changes: 10 additions & 0 deletions assets/cert/renew.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Unit]
Description=Renew certificate

[Service]
Type=simple
EnvironmentFile=/etc/ring/renew.env
ExecStart=/usr/local/bin/renew.sh

[Install]
WantedBy=multi-user.target
13 changes: 13 additions & 0 deletions assets/cert/renew.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/sh

set +x

lego --path "/etc/ldap/cert" --email "${ACME_EMAIL}" --server "https://acme.zerossl.com/v2/DV90" --accept-tos --eab \
--kid "${ACME_KID}" \
--hmac "${ACME_HMAC}" \
--key-type "rsa4096" \
--dns "httpreq" \
--domains "${ACME_DOMAINS}" \
--pem \
renew \
--renew-hook="systemctl restart ring"
10 changes: 10 additions & 0 deletions assets/cert/renew.timer
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Unit]
Description=Renew certificate

[Timer]
Persistent=true
OnCalendar=*-*-* 3:35
RandomizedDelaySec=1h

[Install]
WantedBy=timers.target
42 changes: 42 additions & 0 deletions assets/gpio.dts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/dts-v1/;
/plugin/;

/ {
compatible = "allwinner,sun4i-a10", "allwinner,sun7i-a20", "allwinner,sun8i-h3", "allwinner,sun50i-a64", "allwinner,sun50i-h5";

/*
* This fragment is needed only for the internal pull-up activation,
* external pull-up resistor is highly recommended if using long wires
*/
fragment@0 {
target = <&pio>;
__overlay__ {
gpio_button_0: gpio_button_0 {
pins = "PA7";
function = "gpio_in";
bias-pull-up;
};
};
};

fragment@1 {
target-path = "/";
__overlay__ {
gpio-keys-user {
/*
* Use "gpio-keys" for EINT capable pins, "gpio-keys-polled" for other pins
* add "poll-interval" property if using "gpio-keys-polled"
*/
compatible = "gpio-keys";
pinctrl-names = "default";
pinctrl-0 = <&gpio_button_0>;

f1_button {
label = "GPIO Key F1";
linux,code = <59>; /* KEY_F1, see include/uapi/linux/input-event-codes.h */
gpios = <&pio 0 7 1>; /* PA07 GPIO_ACTIVE_LOW */
};
};
};
};
};
9 changes: 9 additions & 0 deletions assets/ring.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[Unit]
Description=WebRTC Ring Service

[Service]
ExecStart=/usr/local/bin/ring
EnvironmentFile=-/etc/ring/ring.conf

[Install]
WantedBy=multi-user.target
Binary file added audio/ding-dong.wav
Binary file not shown.
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ go 1.20
require (
github.com/alexflint/go-arg v1.4.3
github.com/gin-gonic/gin v1.9.1
github.com/google/uuid v1.3.0
github.com/hashicorp/mdns v1.0.5
github.com/holoplot/go-evdev v0.0.0-20230626094006-70c9462cc0f2
github.com/pion/rtcp v1.2.10
github.com/pion/webrtc/v3 v3.2.10
github.com/tinyzimmer/go-glib v0.0.25
Expand All @@ -24,13 +27,13 @@ require (
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.1 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.10.3 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-pointer v0.0.1 // indirect
github.com/miekg/dns v1.1.41 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
Expand Down
11 changes: 11 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/mdns v1.0.5 h1:1M5hW1cunYeoXOqHwEb/GBDDHAFo0Yqb/uz/beC6LbE=
github.com/hashicorp/mdns v1.0.5/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
github.com/holoplot/go-evdev v0.0.0-20230626094006-70c9462cc0f2 h1:bxudnRpvfq2PMYEYN7VGj03+MXG4EobVUmONigCx1yA=
github.com/holoplot/go-evdev v0.0.0-20230626094006-70c9462cc0f2/go.mod h1:iHAf8OIncO2gcQ8XOjS7CMJ2aPbX2Bs0wl5pZyanEqk=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
Expand All @@ -85,6 +89,8 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0=
github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
Expand Down Expand Up @@ -199,6 +205,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
Expand All @@ -212,7 +219,9 @@ golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand All @@ -225,6 +234,8 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down
13 changes: 12 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"syscall"

"github.com/kaedwen/webrtc/pkg/common"
"github.com/kaedwen/webrtc/pkg/ring"
"github.com/kaedwen/webrtc/pkg/server"
"github.com/kaedwen/webrtc/pkg/webrtc"
"github.com/tinyzimmer/go-glib/glib"
Expand All @@ -26,7 +27,17 @@ func main() {
panic(err)
}

http := server.NewHttpServer(lg.With(zap.String("context", "server")), &cfg.Http)
http := server.NewHttpServer(lg.With(zap.String("context", "server")), &cfg)

rh, err := ring.NewRingHandler(lg.With(zap.String("context", "ring")), &cfg.Ring)
if err != nil {
panic(err)
}

err = rh.Watch(ctx)
if err != nil {
panic(err)
}

err = webrtc.NewWebrtcHandler(ctx, lg.With(zap.String("context", "webrtc")), cfg.Stream(), http.Hndl)
if err != nil {
Expand Down
52 changes: 52 additions & 0 deletions pkg/common/codec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package common

import (
"fmt"
"strings"

"github.com/pion/webrtc/v3"
)

type StreamCodec string

const (
// video codecs
H264 StreamCodec = "H264"
VP8 StreamCodec = "VP8"
VP9 StreamCodec = "VP9"

// audio codecs
OPUS StreamCodec = "OPUS"
)

func (c *StreamCodec) UnmarshalText(text []byte) error {
switch strings.ToUpper(string(text)) {
case string(H264):
*c = H264
case string(VP8):
*c = VP8
case string(VP9):
*c = VP9
case string(OPUS):
*c = OPUS
default:
return fmt.Errorf("unsupported codec - %s", text)
}

return nil
}

func (c StreamCodec) Mime() string {
switch c {
case H264:
return webrtc.MimeTypeH264
case VP8:
return webrtc.MimeTypeVP8
case VP9:
return webrtc.MimeTypeVP9
case OPUS:
return webrtc.MimeTypeOpus
default:
return "UNKNOWN"
}
}
32 changes: 22 additions & 10 deletions pkg/common/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
}

Expand All @@ -25,6 +26,15 @@ type ConfigLogging struct {
Level string `arg:"--log-level,env:LOG_LEVEL" default:"debug"`
}

type ConfigRing struct {
Device *string `arg:"--input-device,env:INPUT_DEVICE"`
Key string `arg:"--ring-key" default:"KEY_F1"`
JingleBaseUri *string `arg:"--jingle-base-uri,env:JINGLE_BASE_URI"`
JinglePath string `arg:"--jingle-path,env:JINGLE_PATH" default:"audio/ding-dong.wav"`
SonosTarget string `arg:"--sonos-target,env:SONOS_TARGET" default:"-"`
SonosVolume int `arg:"--sonos-volume,env:SONOS_VOLUME" default:"50"`
}

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"`
Expand All @@ -37,19 +47,21 @@ type ConfigHTTP struct {
}

type ConfigVideoOutputStream struct {
Source string `arg:"--video-out-src,env:VIDEO_OUT_SRC" default:"v4l2src"`
Device string `arg:"--video-out-device,env:VIDEO_OUT_DEVICE" default:"/dev/video0"`
Codec string `arg:"--video-out-codec,env:VIDEO_OUT_CODEC" default:"vp8"`
Height uint `arg:"--video-out-height,env:VIDEO_OUT_HEIGHT" default:"480"`
Width uint `arg:"--video-out-width,env:VIDEO_OUT_WIDTH" default:"640"`
Source string `arg:"--video-out-src,env:VIDEO_OUT_SRC" default:"v4l2src"`
Device string `arg:"--video-out-device,env:VIDEO_OUT_DEVICE" default:"/dev/video0"`
Codec StreamCodec `arg:"--video-out-codec,env:VIDEO_OUT_CODEC" default:"vp8"`
Height uint `arg:"--video-out-height,env:VIDEO_OUT_HEIGHT" default:"480"`
Width uint `arg:"--video-out-width,env:VIDEO_OUT_WIDTH" default:"640"`
USE_QUEUE bool `arg:"--video-out-queue,env:VIDEO_OUT_QUEUE" default:"false"`
}

type ConfigAudioOutputStream struct {
Source string `arg:"--audio-out-src,env:AUDIO_OUT_SRC" default:"alsasrc"`
DeviceName string `arg:"--audio-out-device-name,env:AUDIO_OUT_DEVICE" default:"default"`
Device *string `arg:"--audio-out-device,env:AUDIO_OUT_DEVICE"`
Codec string `arg:"--audio-out-codec,env:AUDIO_OUT_CODEC" default:"opus"`
Channels uint `arg:"--audio-out-channels,env:AUDIO_OUT_CHANNELS" default:"1"`
Source string `arg:"--audio-out-src,env:AUDIO_OUT_SRC" default:"alsasrc"`
DeviceName string `arg:"--audio-out-device-name,env:AUDIO_OUT_DEVICE" default:"default"`
Device *string `arg:"--audio-out-device,env:AUDIO_OUT_DEVICE"`
Codec StreamCodec `arg:"--audio-out-codec,env:AUDIO_OUT_CODEC" default:"opus"`
Channels uint `arg:"--audio-out-channels,env:AUDIO_OUT_CHANNELS" default:"1"`
USE_QUEUE bool `arg:"--audio-out-queue,env:AUDIO_OUT_QUEUE" default:"false"`
}

type ConfigAudioInputStream struct {
Expand Down
4 changes: 4 additions & 0 deletions pkg/common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ func Time[T any](runnable func() (T, error)) (time.Duration, T, error) {
res, err := runnable()
return time.Since(t), res, err
}

func Ptr[T any](v T) *T {
return &v
}
Loading