Initial commit
This commit is contained in:
parent
d350105040
commit
69686418ef
2
.gitignore
vendored
2
.gitignore
vendored
@ -13,3 +13,5 @@
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
|
||||
*.mp3
|
||||
|
13
cmd/main.go
Normal file
13
cmd/main.go
Normal file
@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
marlinbox "github.com/itsscb/marlin-box"
|
||||
)
|
||||
|
||||
func main() {
|
||||
mb := marlinbox.New("playlist.json")
|
||||
mb.Run()
|
||||
time.Sleep(time.Minute * 5)
|
||||
}
|
28
cmd/playlist.json
Normal file
28
cmd/playlist.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"devicename":"Sycreader RFID Technology Co., Ltd SYC ID&IC USB Reader",
|
||||
"volume": 1.0,
|
||||
"playlist": [
|
||||
{
|
||||
"id": "0002693373",
|
||||
"file": "./music/ACDC - Back In Black.mp3"
|
||||
},
|
||||
{
|
||||
"id": "0011415256",
|
||||
"file": "./music/ACDC - TNT.mp3"
|
||||
},
|
||||
{
|
||||
"id": "0011394336",
|
||||
"file": "./music/ACDC - Thunderstruck.mp3"
|
||||
}
|
||||
],
|
||||
"controlcards": [
|
||||
{
|
||||
"id": "0011462127",
|
||||
"function": "vol+"
|
||||
},
|
||||
{
|
||||
"id": "0011394129",
|
||||
"function": "vol-"
|
||||
}
|
||||
]
|
||||
}
|
11
go.mod
Normal file
11
go.mod
Normal file
@ -0,0 +1,11 @@
|
||||
module marlinbox
|
||||
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/gvalkov/golang-evdev v0.0.0-20220815104727-7e27d6ce89b6
|
||||
github.com/hajimehoshi/go-mp3 v0.3.4
|
||||
github.com/hajimehoshi/oto/v2 v2.3.1
|
||||
)
|
||||
|
||||
require golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e // indirect
|
8
go.sum
Normal file
8
go.sum
Normal file
@ -0,0 +1,8 @@
|
||||
github.com/gvalkov/golang-evdev v0.0.0-20220815104727-7e27d6ce89b6 h1:K9b8efT9f1NkITNgNAm2A1LuoamhG4pAhXVjz5Sfa5Q=
|
||||
github.com/gvalkov/golang-evdev v0.0.0-20220815104727-7e27d6ce89b6/go.mod h1:SAzVFKCRezozJTGavF3GX8MBUruETCqzivVLYiywouA=
|
||||
github.com/hajimehoshi/go-mp3 v0.3.4 h1:NUP7pBYH8OguP4diaTZ9wJbUbk3tC0KlfzsEpWmYj68=
|
||||
github.com/hajimehoshi/go-mp3 v0.3.4/go.mod h1:fRtZraRFcWb0pu7ok0LqyFhCUrPeMsGRSVop0eemFmo=
|
||||
github.com/hajimehoshi/oto/v2 v2.3.1 h1:qrLKpNus2UfD674oxckKjNJmesp9hMh7u7QCrStB3Rc=
|
||||
github.com/hajimehoshi/oto/v2 v2.3.1/go.mod h1:seWLbgHH7AyUMYKfKYT9pg7PhUu9/SisyJvNTT+ASQo=
|
||||
golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e h1:NHvCuwuS43lGnYhten69ZWqi2QOj/CiDNcKbVqwVoew=
|
||||
golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
215
marlinbox.go
Normal file
215
marlinbox.go
Normal file
@ -0,0 +1,215 @@
|
||||
package marlinbox
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
evdev "github.com/gvalkov/golang-evdev"
|
||||
"github.com/hajimehoshi/go-mp3"
|
||||
"github.com/hajimehoshi/oto/v2"
|
||||
)
|
||||
|
||||
type MarlinBox struct {
|
||||
DeviceName string `json:"devicename"`
|
||||
DevicePath string `json:"devicepath,omitempty"`
|
||||
CurrentID string
|
||||
Volume float64 `json:"volume,omitempty"`
|
||||
Playlist []*PlayCard `json:"playlist,omitempty"`
|
||||
ControlCards []*ControlCard `json:"controlcards,omitempty"`
|
||||
Device *evdev.InputDevice
|
||||
CurrentPlayCard *PlayCard
|
||||
Player oto.Player
|
||||
PlayerContext *oto.Context
|
||||
}
|
||||
|
||||
type RFIDCard struct {
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
type PlayCard struct {
|
||||
RFIDCard
|
||||
File string `json:"file,omitempty"`
|
||||
}
|
||||
type ControlCard struct {
|
||||
RFIDCard
|
||||
Function string `json:"function,omitempty"`
|
||||
}
|
||||
|
||||
var KeyMap = map[uint16]string{
|
||||
2: "1",
|
||||
3: "2",
|
||||
4: "3",
|
||||
5: "4",
|
||||
6: "5",
|
||||
7: "6",
|
||||
8: "7",
|
||||
9: "8",
|
||||
10: "9",
|
||||
11: "0",
|
||||
28: "ENTER",
|
||||
}
|
||||
|
||||
func New(path string) *MarlinBox {
|
||||
var mb *MarlinBox
|
||||
|
||||
f, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(f, &mb)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if mb.Volume == 0 {
|
||||
mb.Volume = 1
|
||||
}
|
||||
|
||||
if mb.DeviceName == "" {
|
||||
panic("No DeviceName given")
|
||||
}
|
||||
|
||||
devices, err := evdev.ListInputDevices()
|
||||
|
||||
for _, dev := range devices {
|
||||
if dev.Name == mb.DeviceName {
|
||||
mb.DevicePath = dev.Fn
|
||||
}
|
||||
}
|
||||
|
||||
if mb.DevicePath == "" {
|
||||
panic("Device not found")
|
||||
}
|
||||
|
||||
return mb
|
||||
}
|
||||
|
||||
func (mb *MarlinBox) Run() {
|
||||
var err error
|
||||
mb.Device, err = evdev.Open(mb.DevicePath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mb.Device.Grab()
|
||||
|
||||
go func() {
|
||||
for {
|
||||
events, err := mb.Device.Read()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
for _, ev := range events {
|
||||
if ev.Value != 0x1 {
|
||||
continue
|
||||
}
|
||||
val, ok := KeyMap[ev.Code]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if val == "ENTER" {
|
||||
err := mb.GetCurrentCard()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
fmt.Println(mb.CurrentPlayCard)
|
||||
mb.CurrentID = ""
|
||||
// err =
|
||||
// if err != nil {
|
||||
// log.Println(err)
|
||||
// panic(err)
|
||||
// }
|
||||
continue
|
||||
}
|
||||
|
||||
mb.CurrentID += val
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (mb *MarlinBox) GetCurrentCard() error {
|
||||
fmt.Println(mb.ControlCards)
|
||||
for _, c := range mb.ControlCards {
|
||||
if mb.CurrentID == c.ID {
|
||||
switch c.Function {
|
||||
case "vol+":
|
||||
fmt.Println("vol+")
|
||||
if mb.Volume < 1.0 {
|
||||
mb.Volume = mb.Volume + 0.2
|
||||
}
|
||||
case "vol-":
|
||||
fmt.Println("vol-")
|
||||
if mb.Volume > 0 {
|
||||
mb.Volume = mb.Volume - 0.2
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
for _, c := range mb.Playlist {
|
||||
if mb.CurrentID == c.ID {
|
||||
mb.CurrentPlayCard = c
|
||||
if mb.PlayerContext != nil {
|
||||
mb.Player.Reset()
|
||||
}
|
||||
mb.Play()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return errors.New("Card not found: " + mb.CurrentID)
|
||||
}
|
||||
|
||||
func (mb *MarlinBox) Play() {
|
||||
go func() {
|
||||
var err error
|
||||
var ready chan struct{}
|
||||
playingID := mb.CurrentPlayCard.ID
|
||||
f, err := os.Open(mb.CurrentPlayCard.File)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
d, err := mp3.NewDecoder(f)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
mb.PlayerContext, ready, err = oto.NewContext(d.SampleRate(), 2, 2)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
<-ready
|
||||
|
||||
mb.Player = mb.PlayerContext.NewPlayer(d)
|
||||
defer mb.Player.Close()
|
||||
mb.Player.SetVolume(mb.Volume)
|
||||
mb.Player.Play()
|
||||
|
||||
for {
|
||||
if mb.CurrentPlayCard.ID != playingID {
|
||||
break
|
||||
}
|
||||
if mb.Volume != mb.Player.Volume() {
|
||||
mb.Player.SetVolume(mb.Volume)
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
if !mb.Player.IsPlaying() {
|
||||
break
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user