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)
|
# Dependency directories (remove the comment below to include it)
|
||||||
# vendor/
|
# 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