Improving backend
This commit is contained in:
parent
e2013351d1
commit
c67b43ab3c
9 changed files with 301 additions and 47 deletions
|
|
@ -2,16 +2,19 @@ package amp1gpio
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
|
||||
"git.nemunai.re/nemunaire/hathoris/sources"
|
||||
)
|
||||
|
||||
type AMP1GPIOSource struct {
|
||||
Path string
|
||||
process *exec.Cmd
|
||||
Path string
|
||||
}
|
||||
|
||||
const GPIODirectory = "/sys/class/gpio/gpio46/"
|
||||
|
|
@ -39,7 +42,7 @@ func (s *AMP1GPIOSource) read() ([]byte, error) {
|
|||
}
|
||||
|
||||
func (s *AMP1GPIOSource) IsActive() bool {
|
||||
return s.IsEnabled()
|
||||
return s.process != nil
|
||||
}
|
||||
|
||||
func (s *AMP1GPIOSource) IsEnabled() bool {
|
||||
|
|
@ -49,7 +52,7 @@ func (s *AMP1GPIOSource) IsEnabled() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
return bytes.Compare(b, []byte{'1'}) == 0
|
||||
return bytes.Compare(b, []byte{'1', '\n'}) == 0
|
||||
}
|
||||
|
||||
func (s *AMP1GPIOSource) write(value string) error {
|
||||
|
|
@ -65,9 +68,33 @@ func (s *AMP1GPIOSource) write(value string) error {
|
|||
}
|
||||
|
||||
func (s *AMP1GPIOSource) Enable() error {
|
||||
if s.process != nil {
|
||||
return fmt.Errorf("Already running")
|
||||
}
|
||||
|
||||
s.process = exec.Command("aplay", "-f", "cd", "/dev/zero")
|
||||
if err := s.process.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go func() {
|
||||
err := s.process.Wait()
|
||||
if err != nil {
|
||||
s.process.Process.Kill()
|
||||
}
|
||||
|
||||
s.process = nil
|
||||
}()
|
||||
|
||||
return s.write("1")
|
||||
}
|
||||
|
||||
func (s *AMP1GPIOSource) Disable() error {
|
||||
if s.process != nil {
|
||||
if s.process.Process != nil {
|
||||
s.process.Process.Kill()
|
||||
}
|
||||
}
|
||||
|
||||
return s.write("0")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,3 +11,7 @@ type SoundSource interface {
|
|||
Enable() error
|
||||
Disable() error
|
||||
}
|
||||
|
||||
type PlayingSource interface {
|
||||
CurrentlyPlaying() string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,26 +2,41 @@ package mpv
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"github.com/DexterLB/mpvipc"
|
||||
|
||||
"git.nemunai.re/nemunaire/hathoris/sources"
|
||||
)
|
||||
|
||||
type MPVSource struct {
|
||||
process *exec.Cmd
|
||||
Options []string
|
||||
File string
|
||||
process *exec.Cmd
|
||||
ipcSocket string
|
||||
Name string
|
||||
Options []string
|
||||
File string
|
||||
}
|
||||
|
||||
func init() {
|
||||
sources.SoundSources["mpv"] = &MPVSource{
|
||||
Options: []string{"--no-video"},
|
||||
File: "https://mediaserv38.live-streams.nl:18030/stream",
|
||||
sources.SoundSources["mpv-1"] = &MPVSource{
|
||||
Name: "Radio 1",
|
||||
ipcSocket: "/tmp/tmpmpv.radio-1",
|
||||
Options: []string{"--no-video", "--no-terminal"},
|
||||
File: "https://mediaserv38.live-streams.nl:18030/stream",
|
||||
}
|
||||
sources.SoundSources["mpv-2"] = &MPVSource{
|
||||
Name: "Radio 2",
|
||||
ipcSocket: "/tmp/tmpmpv.radio-2",
|
||||
Options: []string{"--no-video", "--no-terminal"},
|
||||
File: "https://mediaserv38.live-streams.nl:18040/live",
|
||||
}
|
||||
}
|
||||
|
||||
func (s *MPVSource) GetName() string {
|
||||
return "Radio 1"
|
||||
return s.Name
|
||||
}
|
||||
|
||||
func (s *MPVSource) IsActive() bool {
|
||||
|
|
@ -39,6 +54,9 @@ func (s *MPVSource) Enable() (err error) {
|
|||
|
||||
var opts []string
|
||||
opts = append(opts, s.Options...)
|
||||
if s.ipcSocket != "" {
|
||||
opts = append(opts, "--input-ipc-server="+s.ipcSocket, "--pause")
|
||||
}
|
||||
opts = append(opts, s.File)
|
||||
|
||||
s.process = exec.Command("mpv", opts...)
|
||||
|
|
@ -55,6 +73,39 @@ func (s *MPVSource) Enable() (err error) {
|
|||
s.process = nil
|
||||
}()
|
||||
|
||||
if s.ipcSocket != "" {
|
||||
_, err = os.Stat(s.ipcSocket)
|
||||
for i := 20; i >= 0 && err != nil; i-- {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
_, err = os.Stat(s.ipcSocket)
|
||||
}
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
|
||||
conn := mpvipc.NewConnection(s.ipcSocket)
|
||||
err = conn.Open()
|
||||
for i := 20; i >= 0 && err != nil; i-- {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
err = conn.Open()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
_, err = conn.Get("media-title")
|
||||
for err != nil {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
_, err = conn.Get("media-title")
|
||||
}
|
||||
|
||||
conn.Set("ao-volume", 50)
|
||||
|
||||
err = conn.Set("pause", false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -67,3 +118,24 @@ func (s *MPVSource) Disable() error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MPVSource) CurrentlyPlaying() string {
|
||||
if s.ipcSocket != "" {
|
||||
conn := mpvipc.NewConnection(s.ipcSocket)
|
||||
err := conn.Open()
|
||||
if err != nil {
|
||||
log.Println("Unable to open mpv socket:", err.Error())
|
||||
return "!"
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
title, err := conn.Get("media-title")
|
||||
if err != nil {
|
||||
log.Println("Unable to retrieve title:", err.Error())
|
||||
return "!"
|
||||
}
|
||||
return title.(string)
|
||||
}
|
||||
|
||||
return "-"
|
||||
}
|
||||
|
|
|
|||
116
sources/spdif/source.go
Normal file
116
sources/spdif/source.go
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
package spdif
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
|
||||
"git.nemunai.re/nemunaire/hathoris/sources"
|
||||
)
|
||||
|
||||
type SPDIFSource struct {
|
||||
processRec *exec.Cmd
|
||||
processPlay *exec.Cmd
|
||||
DeviceIn string
|
||||
DeviceOut string
|
||||
Bitrate int64
|
||||
Channels int64
|
||||
Format string
|
||||
}
|
||||
|
||||
func init() {
|
||||
if dirs, err := os.ReadDir("/sys/class/sound"); err == nil {
|
||||
for _, dir := range dirs {
|
||||
thisdir := path.Join("/sys/class/sound", dir.Name())
|
||||
if s, err := os.Stat(thisdir); err == nil && s.IsDir() {
|
||||
idfile := path.Join(thisdir, "id")
|
||||
if fd, err := os.Open(idfile); err == nil {
|
||||
if cnt, err := io.ReadAll(fd); err == nil && string(cnt) == "imxspdif\n" {
|
||||
sources.SoundSources["imxspdif"] = &SPDIFSource{
|
||||
DeviceIn: "imxspdif",
|
||||
DeviceOut: "is31ap2121",
|
||||
Bitrate: 48000,
|
||||
Channels: 2,
|
||||
Format: "S24_LE",
|
||||
}
|
||||
}
|
||||
fd.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SPDIFSource) GetName() string {
|
||||
return "S/PDIF"
|
||||
}
|
||||
|
||||
func (s *SPDIFSource) IsActive() bool {
|
||||
return s.processRec != nil
|
||||
}
|
||||
|
||||
func (s *SPDIFSource) IsEnabled() bool {
|
||||
return s.processRec != nil
|
||||
}
|
||||
|
||||
func (s *SPDIFSource) Enable() error {
|
||||
if s.processRec != nil {
|
||||
return fmt.Errorf("Already running")
|
||||
}
|
||||
if s.processPlay != nil {
|
||||
s.processPlay.Process.Kill()
|
||||
}
|
||||
|
||||
pipeR, pipeW, err := os.Pipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.processPlay = exec.Command("aplay", "-c", fmt.Sprintf("%d", s.Channels), "-D", "hw:"+s.DeviceOut, "--period-size=512", "-B0", "--buffer-size=512")
|
||||
s.processPlay.Stdin = pipeR
|
||||
if err := s.processPlay.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go func() {
|
||||
err := s.processPlay.Wait()
|
||||
if err != nil {
|
||||
s.processPlay.Process.Kill()
|
||||
pipeR.Close()
|
||||
pipeW.Close()
|
||||
}
|
||||
|
||||
s.processPlay = nil
|
||||
}()
|
||||
|
||||
s.processRec = exec.Command("arecord", "-t", "wav", "-f", s.Format, fmt.Sprintf("-r%d", s.Bitrate), fmt.Sprintf("-c%d", s.Channels), "-D", "hw:"+s.DeviceIn, "-B0", "--buffer-size=512")
|
||||
s.processRec.Stdout = pipeW
|
||||
if err := s.processRec.Start(); err != nil {
|
||||
s.processPlay.Process.Kill()
|
||||
return err
|
||||
}
|
||||
|
||||
go func() {
|
||||
err := s.processRec.Wait()
|
||||
if err != nil {
|
||||
s.processRec.Process.Kill()
|
||||
}
|
||||
|
||||
s.processRec = nil
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SPDIFSource) Disable() error {
|
||||
if s.processRec != nil && s.processRec.Process != nil {
|
||||
s.processRec.Process.Kill()
|
||||
}
|
||||
if s.processPlay != nil && s.processPlay.Process != nil {
|
||||
s.processPlay.Process.Kill()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue