Compare commits
No commits in common. "master" and "youtube" have entirely different histories.
|
@ -16,6 +16,3 @@ ambiance
|
||||||
public/
|
public/
|
||||||
node_modules/
|
node_modules/
|
||||||
src/node_modules
|
src/node_modules
|
||||||
*.aac
|
|
||||||
*.opus
|
|
||||||
*.mp3
|
|
|
@ -1,61 +1,18 @@
|
||||||
FROM golang:1.21-bookworm as builder
|
FROM golang:1.21-bookworm as builder
|
||||||
|
|
||||||
ENV FFMPEG_VERSION=5.1.2
|
|
||||||
ENV MPD_VERSION=0.23.14
|
|
||||||
|
|
||||||
RUN apt-get update && apt-get -y install \
|
|
||||||
libopus-dev libopusfile-dev \
|
|
||||||
meson g++ nasm \
|
|
||||||
libfmt-dev \
|
|
||||||
libpcre2-dev \
|
|
||||||
libmad0-dev libmpg123-dev libid3tag0-dev \
|
|
||||||
libflac-dev libvorbis-dev libopus-dev libogg-dev \
|
|
||||||
libadplug-dev libaudiofile-dev libsndfile1-dev libfaad-dev \
|
|
||||||
libsamplerate0-dev libsoxr-dev \
|
|
||||||
libcurl4-gnutls-dev \
|
|
||||||
libboost-dev \
|
|
||||||
zlib1g-dev
|
|
||||||
WORKDIR /tmp
|
|
||||||
RUN curl -LOs http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.xz && tar xvf ffmpeg-${FFMPEG_VERSION}.tar.xz && \
|
|
||||||
cd ffmpeg-${FFMPEG_VERSION} && \
|
|
||||||
./configure \
|
|
||||||
--enable-version3 \
|
|
||||||
--enable-gpl \
|
|
||||||
--enable-nonfree \
|
|
||||||
--enable-small \
|
|
||||||
--enable-libvorbis \
|
|
||||||
--enable-libopus \
|
|
||||||
--enable-postproc \
|
|
||||||
--enable-openssl \
|
|
||||||
--disable-debug && \
|
|
||||||
make && \
|
|
||||||
make install
|
|
||||||
RUN curl -LOs https://www.musicpd.org/download/mpd/0.23/mpd-${MPD_VERSION}.tar.xz && tar xvf mpd-${MPD_VERSION}.tar.xz && \
|
|
||||||
cd mpd-${MPD_VERSION} && \
|
|
||||||
meson . output/release --buildtype=minsize -Db_ndebug=true && \
|
|
||||||
ninja -C output/release
|
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN go build
|
RUN apt-get update && apt-get -y install libopus-dev libopusfile-dev && \
|
||||||
|
go build
|
||||||
|
|
||||||
FROM debian:bookworm-slim
|
FROM debian:bookworm-slim
|
||||||
RUN apt-get update && apt-get -y install \
|
RUN apt-get update && apt-get -y install \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
libopus-dev libopusfile-dev \
|
libopus-dev libopusfile-dev \
|
||||||
libfmt-dev \
|
mpd ffmpeg curl && \
|
||||||
libpcre2-dev \
|
|
||||||
libmad0-dev libmpg123-dev libid3tag0-dev \
|
|
||||||
libflac-dev libvorbis-dev libopus-dev libogg-dev \
|
|
||||||
libadplug-dev libaudiofile-dev libsndfile1-dev libfaad-dev \
|
|
||||||
libsamplerate0-dev libsoxr-dev \
|
|
||||||
libcurl4-gnutls-dev \
|
|
||||||
curl && \
|
|
||||||
curl -L https://github.com/badaix/snapcast/releases/download/v0.27.0/snapclient_0.27.0-1_without-pulse_amd64.deb -o /tmp/snapcast.deb && \
|
curl -L https://github.com/badaix/snapcast/releases/download/v0.27.0/snapclient_0.27.0-1_without-pulse_amd64.deb -o /tmp/snapcast.deb && \
|
||||||
curl -L http://ftp.no.debian.org/debian/pool/main/f/flac/libflac8_1.3.3-2+deb11u2_amd64.deb -o /tmp/libflac8.deb && \
|
curl -L http://ftp.no.debian.org/debian/pool/main/f/flac/libflac8_1.3.3-2+deb11u2_amd64.deb -o /tmp/libflac8.deb && \
|
||||||
apt -y install /tmp/snapcast.deb /tmp/libflac8.deb && rm -rf /tmp/*.deb
|
apt -y install /tmp/snapcast.deb /tmp/libflac8.deb
|
||||||
COPY --from=builder /src/dndmusicbot /app/
|
COPY --from=builder /src/dndmusicbot /app/
|
||||||
COPY --from=builder /tmp/mpd-0.23.14/output/release/mpd /usr/local/bin
|
|
||||||
COPY --from=builder /usr/local/bin/ffmpeg /usr/local/bin
|
|
||||||
COPY mp3 /app/mp3
|
|
||||||
ADD tmpl /app/tmpl
|
ADD tmpl /app/tmpl
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ENTRYPOINT [ "/app/dndmusicbot" ]
|
ENTRYPOINT [ "/app/dndmusicbot" ]
|
||||||
|
|
52
ambiance.go
52
ambiance.go
|
@ -69,17 +69,20 @@ func GetAmbiances() (amb []Ambiance, err error) {
|
||||||
func AddAmbiance(uri, title string) (Ambiance, error) {
|
func AddAmbiance(uri, title string) (Ambiance, error) {
|
||||||
var amb Ambiance
|
var amb Ambiance
|
||||||
|
|
||||||
ev := Event{"ambiance_add_start", map[string]string{
|
msg := make(map[string]interface{})
|
||||||
"name": title,
|
msg["event"] = "ambiance_add_start"
|
||||||
}}
|
data := make(map[string]string)
|
||||||
|
data["name"] = title
|
||||||
go ws.SendEvent(ev)
|
msg["payload"] = data
|
||||||
|
ws_msg <- msg
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
ev = Event{"ambiance_add_finish", map[string]string{
|
msg = make(map[string]interface{})
|
||||||
"name": title,
|
msg["event"] = "ambiance_add_finish"
|
||||||
}}
|
data = make(map[string]string)
|
||||||
go ws.SendEvent(ev)
|
data["name"] = title
|
||||||
|
msg["payload"] = data
|
||||||
|
ws_msg <- msg
|
||||||
}()
|
}()
|
||||||
|
|
||||||
tmpfile, err := exec.Command("mktemp", "/tmp/dnd_XXXXXXXXXXXX.opus").Output()
|
tmpfile, err := exec.Command("mktemp", "/tmp/dnd_XXXXXXXXXXXX.opus").Output()
|
||||||
|
@ -131,13 +134,16 @@ func AddAmbiance(uri, title string) (Ambiance, error) {
|
||||||
|
|
||||||
log.Printf("Start ffmpeg to extract audio to %s", string(tmpfile))
|
log.Printf("Start ffmpeg to extract audio to %s", string(tmpfile))
|
||||||
|
|
||||||
ev = Event{"ambiance_encode_start", map[string]string{
|
msg = make(map[string]interface{})
|
||||||
"name": title,
|
msg["event"] = "ambiance_encode_start"
|
||||||
}}
|
data = make(map[string]string)
|
||||||
|
data["name"] = title
|
||||||
|
msg["payload"] = data
|
||||||
|
ws_msg <- msg
|
||||||
|
|
||||||
go ws.SendEvent(ev)
|
msg = make(map[string]interface{})
|
||||||
|
msg["event"] = "ambiance_encode_progress"
|
||||||
data := make(map[string]string)
|
data = make(map[string]string)
|
||||||
data["name"] = title
|
data["name"] = title
|
||||||
|
|
||||||
scanner := bufio.NewScanner(ffprogress)
|
scanner := bufio.NewScanner(ffprogress)
|
||||||
|
@ -156,7 +162,8 @@ func AddAmbiance(uri, title string) (Ambiance, error) {
|
||||||
data["percent"] = percent
|
data["percent"] = percent
|
||||||
}
|
}
|
||||||
|
|
||||||
go ws.SendEvent(Event{"ambiance_encode_progress", data})
|
msg["payload"] = data
|
||||||
|
ws_msg <- msg
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,14 +176,15 @@ func AddAmbiance(uri, title string) (Ambiance, error) {
|
||||||
return amb, err
|
return amb, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ev = Event{"ambiance_encode_complete", map[string]string{
|
msg = make(map[string]interface{})
|
||||||
"name": title,
|
msg["event"] = "ambiance_encode_complete"
|
||||||
}}
|
data = make(map[string]string)
|
||||||
|
data["name"] = title
|
||||||
go ws.SendEvent(ev)
|
msg["payload"] = data
|
||||||
|
ws_msg <- msg
|
||||||
|
|
||||||
id := uuid.New()
|
id := uuid.New()
|
||||||
fn := filepath.Join(config.GetString("ambiance.path"), fmt.Sprintf("%s.aac", id.String()))
|
fn := filepath.Join(config.GetString("ambiance.path"), fmt.Sprintf("%s.opus", id.String()))
|
||||||
|
|
||||||
log.Printf("Moving to %s", fn)
|
log.Printf("Moving to %s", fn)
|
||||||
|
|
||||||
|
|
121
events.go
121
events.go
|
@ -148,70 +148,74 @@ func (app *App) volset(payload ...interface{}) {
|
||||||
amb_volume.Volume = vol
|
amb_volume.Volume = vol
|
||||||
}
|
}
|
||||||
|
|
||||||
ev := Event{"volume", map[string]float64{
|
app.sendVolume()
|
||||||
"playlist": pl_volume.Volume,
|
|
||||||
"ambiance": amb_volume.Volume,
|
|
||||||
}}
|
|
||||||
|
|
||||||
go ws.SendEvent(ev)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) songInfoEvent(event string) (ev Event, err error) {
|
func (app *App) sendVolume() {
|
||||||
ev.Event = event
|
msg := make(map[string]interface{})
|
||||||
|
out := make(map[string]float64)
|
||||||
|
msg["event"] = "volume"
|
||||||
|
out["playlist"] = pl_volume.Volume
|
||||||
|
out["ambiance"] = amb_volume.Volume
|
||||||
|
msg["payload"] = out
|
||||||
|
ws_msg <- msg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (app *App) songInfoEvent(event string) map[string]interface{} {
|
||||||
|
msg := make(map[string]interface{})
|
||||||
|
msg["event"] = event
|
||||||
status, err := app.mpd.Status()
|
status, err := app.mpd.Status()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
log.Println(err)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cur, err := app.mpd.CurrentSong()
|
cur, err := app.mpd.CurrentSong()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
log.Println(err)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
info := new(SongInfo)
|
info := new(SongInfo)
|
||||||
|
|
||||||
if status["state"] != "play" {
|
if status["state"] != "play" {
|
||||||
info.Pause = true
|
info.Pause = true
|
||||||
ev.Payload = info
|
msg["payload"] = info
|
||||||
return
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
duration, ok := status["duration"]
|
duration, ok := status["duration"]
|
||||||
if ok && duration != "" {
|
if ok && duration != "" {
|
||||||
var slen float64
|
slen, err := strconv.ParseFloat(duration, 64)
|
||||||
slen, err = strconv.ParseFloat(duration, 64)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
info.Length = time.Duration(slen * float64(time.Second)).Milliseconds()
|
info.Length = time.Duration(slen * float64(time.Second)).Milliseconds()
|
||||||
}
|
}
|
||||||
|
|
||||||
elapsed, ok := status["elapsed"]
|
elapsed, ok := status["elapsed"]
|
||||||
if ok && elapsed != "" {
|
if ok && elapsed != "" {
|
||||||
var spos float64
|
spos, err := strconv.ParseFloat(elapsed, 64)
|
||||||
spos, err = strconv.ParseFloat(elapsed, 64)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
info.Position = time.Duration(spos * float64(time.Second)).Milliseconds()
|
info.Position = time.Duration(spos * float64(time.Second)).Milliseconds()
|
||||||
}
|
}
|
||||||
|
|
||||||
album, ok := cur["Album"]
|
album, ok := cur["Album"]
|
||||||
if ok {
|
if ok {
|
||||||
var plid uuid.UUID
|
plid, err := uuid.ParseBytes([]byte(album))
|
||||||
plid, err = uuid.ParseBytes([]byte(album))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
var pl *Playlist
|
|
||||||
pl, err = app.GetPlaylist(plid)
|
pl, err := app.GetPlaylist(plid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
info.Playlist = pl.Id
|
info.Playlist = pl.Id
|
||||||
|
@ -233,9 +237,9 @@ func (app *App) songInfoEvent(event string) (ev Event, err error) {
|
||||||
info.Song = location
|
info.Song = location
|
||||||
}
|
}
|
||||||
|
|
||||||
ev.Payload = *info
|
msg["payload"] = *info
|
||||||
|
|
||||||
return ev, nil
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) ambiancePlay(payload ...interface{}) {
|
func (app *App) ambiancePlay(payload ...interface{}) {
|
||||||
|
@ -288,13 +292,15 @@ func (app *App) ambiancePlay(payload ...interface{}) {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msg := make(map[string]interface{})
|
||||||
|
out := make(map[string]interface{})
|
||||||
|
|
||||||
app.curamb = amb
|
app.curamb = amb
|
||||||
|
|
||||||
ev := Event{"ambiance_play", map[string]string{
|
msg["event"] = "ambiance_play"
|
||||||
"id": id,
|
out["id"] = id
|
||||||
}}
|
msg["payload"] = out
|
||||||
|
ws_msg <- msg
|
||||||
go ws.SendEvent(ev)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) ambianceStop(payload ...interface{}) {
|
func (app *App) ambianceStop(payload ...interface{}) {
|
||||||
|
@ -313,7 +319,10 @@ func (app *App) ambianceStop(payload ...interface{}) {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
go ws.SendEvent(Event{"ambiance_stop", nil})
|
msg := make(map[string]interface{})
|
||||||
|
msg["event"] = "ambiance_stop"
|
||||||
|
ws_msg <- msg
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) ambianceAdd(payload ...interface{}) {
|
func (app *App) ambianceAdd(payload ...interface{}) {
|
||||||
|
@ -350,12 +359,13 @@ func (app *App) ambianceAdd(payload ...interface{}) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ev := Event{"ambiance_add", map[string]string{
|
msg := make(map[string]interface{})
|
||||||
"title": amb.Title,
|
out := make(map[string]interface{})
|
||||||
"id": amb.Id,
|
msg["event"] = "ambiance_add"
|
||||||
}}
|
out["title"] = amb.Title
|
||||||
|
out["id"] = amb.Id
|
||||||
go ws.SendEvent(ev)
|
msg["payload"] = out
|
||||||
|
ws_msg <- msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) songPosition(payload ...interface{}) {
|
func (app *App) songPosition(payload ...interface{}) {
|
||||||
|
@ -370,16 +380,18 @@ func (app *App) songPosition(payload ...interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
l.Do(func() {
|
l.Do(func() {
|
||||||
|
msg := make(map[string]interface{})
|
||||||
|
out := make(map[string]interface{})
|
||||||
|
|
||||||
slen, _ := strconv.ParseFloat(status["duration"], 64)
|
slen, _ := strconv.ParseFloat(status["duration"], 64)
|
||||||
spos, _ := strconv.ParseFloat(status["elapsed"], 64)
|
spos, _ := strconv.ParseFloat(status["elapsed"], 64)
|
||||||
|
|
||||||
ev := Event{"song_position", map[string]int64{
|
msg["event"] = "song_position"
|
||||||
"len": time.Duration(slen * float64(time.Second)).Milliseconds(),
|
out["len"] = time.Duration(slen * float64(time.Second)).Milliseconds()
|
||||||
"position": time.Duration(spos * float64(time.Second)).Milliseconds(),
|
out["position"] = time.Duration(spos * float64(time.Second)).Milliseconds()
|
||||||
}}
|
|
||||||
|
|
||||||
go ws.SendEvent(ev)
|
msg["payload"] = out
|
||||||
|
ws_msg <- msg
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -387,12 +399,10 @@ func (app *App) songPosition(payload ...interface{}) {
|
||||||
func (app *App) songInfo(payload ...interface{}) {
|
func (app *App) songInfo(payload ...interface{}) {
|
||||||
log.Println("song_info event received")
|
log.Println("song_info event received")
|
||||||
|
|
||||||
ev, err := app.songInfoEvent("song_info")
|
msg := app.songInfoEvent("song_info")
|
||||||
if err != nil {
|
if msg != nil {
|
||||||
log.Println(err)
|
ws_msg <- msg
|
||||||
return
|
|
||||||
}
|
}
|
||||||
go ws.SendEvent(ev)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) stop(payload ...interface{}) {
|
func (app *App) stop(payload ...interface{}) {
|
||||||
|
@ -405,7 +415,10 @@ func (app *App) stop(payload ...interface{}) {
|
||||||
app.mpd.Stop()
|
app.mpd.Stop()
|
||||||
app.plmutex.Unlock()
|
app.plmutex.Unlock()
|
||||||
|
|
||||||
go ws.SendEvent(Event{"stop", nil})
|
msg := make(map[string]interface{})
|
||||||
|
msg["event"] = "stop"
|
||||||
|
|
||||||
|
ws_msg <- msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) prevSong(payload ...interface{}) {
|
func (app *App) prevSong(payload ...interface{}) {
|
||||||
|
@ -479,12 +492,12 @@ func (app *App) addPlaylist(payload ...interface{}) {
|
||||||
log.Println("Error getting youtube playlist info,", plid)
|
log.Println("Error getting youtube playlist info,", plid)
|
||||||
}
|
}
|
||||||
|
|
||||||
ev := Event{"new_playlist", map[string]string{
|
msg := make(map[string]interface{})
|
||||||
"url": id.String(),
|
|
||||||
"title": pltitle,
|
|
||||||
}}
|
|
||||||
|
|
||||||
go ws.SendEvent(ev)
|
msg["event"] = "new_playlist"
|
||||||
|
msg["payload"] = map[string]string{"url": id.String(), "title": pltitle}
|
||||||
|
|
||||||
|
ws_msg <- msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) loadPlaylist(payload ...interface{}) {
|
func (app *App) loadPlaylist(payload ...interface{}) {
|
||||||
|
|
1
mpd.go
1
mpd.go
|
@ -41,6 +41,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
mpd_conf := config.GetStringMapString("mpd")
|
mpd_conf := config.GetStringMapString("mpd")
|
||||||
|
mpd_conf["proxy_port"] = strconv.Itoa(proxy_port)
|
||||||
|
|
||||||
err = t.Execute(f, mpd_conf)
|
err = t.Execute(f, mpd_conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -69,7 +69,7 @@ func init() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ws.join(conn)
|
err = handleWS(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("WS connection closed, %v\n", r.RemoteAddr)
|
log.Printf("WS connection closed, %v\n", r.RemoteAddr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "esbuild app/root.tsx --bundle --outfile=/public/script.js"
|
"build": "esbuild app/root.tsx --bundle --outfile=../public_test/script.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/react": "^18.2.33",
|
"@types/react": "^18.2.33",
|
||||||
|
|
66
ws.go
66
ws.go
|
@ -12,21 +12,18 @@ import (
|
||||||
"github.com/kataras/go-events"
|
"github.com/kataras/go-events"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Websocket struct {
|
|
||||||
sync.Mutex
|
|
||||||
|
|
||||||
clients *bcast.Group
|
|
||||||
}
|
|
||||||
|
|
||||||
var ws *Websocket
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log.Println("ws.go loading..")
|
log.Println("ws.go loading..")
|
||||||
ws = new(Websocket)
|
go ws_clients.Broadcast(0)
|
||||||
|
ws_msg = make(chan interface{})
|
||||||
|
|
||||||
ws.clients = bcast.NewGroup()
|
go func() {
|
||||||
|
var msg interface{}
|
||||||
go ws.clients.Broadcast(0)
|
for {
|
||||||
|
msg = <-ws_msg
|
||||||
|
ws_clients.Send(msg)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
log.Println("ws.go done.")
|
log.Println("ws.go done.")
|
||||||
}
|
}
|
||||||
|
@ -36,19 +33,12 @@ type WSmsg struct {
|
||||||
Payload json.RawMessage
|
Payload json.RawMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
type Event struct {
|
var ws_clients = bcast.NewGroup()
|
||||||
Event string `json:"event"`
|
var ws_msg chan interface{}
|
||||||
Payload any `json:"payload,omitempty"`
|
var WSMutex = &sync.Mutex{}
|
||||||
}
|
|
||||||
|
|
||||||
func (ws *Websocket) SendEvent(e Event) {
|
func handleWS(c *websocket.Conn) error {
|
||||||
ws.Lock()
|
memb := ws_clients.Join()
|
||||||
ws.clients.Send(e)
|
|
||||||
ws.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ws *Websocket) join(c *websocket.Conn) error {
|
|
||||||
memb := ws.clients.Join()
|
|
||||||
defer memb.Close()
|
defer memb.Close()
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
@ -74,27 +64,29 @@ func (ws *Websocket) join(c *websocket.Conn) error {
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
msg, err := app.songInfoEvent("song_info")
|
msg := app.songInfoEvent("song_info")
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
vol := Event{"volume", map[string]float64{
|
vol := make(map[string]interface{})
|
||||||
"playlist": pl_volume.Volume,
|
volout := make(map[string]float64)
|
||||||
"ambiance": amb_volume.Volume,
|
vol["event"] = "volume"
|
||||||
}}
|
volout["playlist"] = pl_volume.Volume
|
||||||
|
volout["ambiance"] = amb_volume.Volume
|
||||||
|
vol["payload"] = volout
|
||||||
|
|
||||||
c.SetWriteDeadline(time.Now().Add(10 * time.Second))
|
c.SetWriteDeadline(time.Now().Add(10 * time.Second))
|
||||||
c.WriteJSON(msg)
|
c.WriteJSON(msg)
|
||||||
c.WriteJSON(vol)
|
c.WriteJSON(vol)
|
||||||
|
|
||||||
if app.ambiance.Len() > 0 {
|
if app.ambiance.Len() > 0 {
|
||||||
msg := Event{"ambiance_play", map[string]string{
|
msg := make(map[string]interface{})
|
||||||
"id": app.curamb.Id,
|
out := make(map[string]interface{})
|
||||||
}}
|
msg["event"] = "ambiance_play"
|
||||||
|
out["id"] = app.curamb.Id
|
||||||
|
msg["payload"] = out
|
||||||
c.WriteJSON(msg)
|
c.WriteJSON(msg)
|
||||||
} else {
|
} else {
|
||||||
msg := Event{"ambiance_stop", nil}
|
msg := make(map[string]interface{})
|
||||||
|
msg["event"] = "ambiance_stop"
|
||||||
c.WriteJSON(msg)
|
c.WriteJSON(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +97,6 @@ func (ws *Websocket) join(c *websocket.Conn) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
app.events.Emit(events.EventName(msg.Event), msg.Payload, memb)
|
app.events.Emit(events.EventName(msg.Event), msg.Payload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
58
ytdl.go
58
ytdl.go
|
@ -1,42 +1,23 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"math"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/time/rate"
|
"golang.org/x/time/rate"
|
||||||
)
|
)
|
||||||
|
|
||||||
var prate = rate.Sometimes{Interval: 1 * time.Second}
|
var prate = rate.Sometimes{Interval: 1 * time.Second}
|
||||||
|
var yturl = "https://youtu.be/%s"
|
||||||
|
|
||||||
// var yturl = "https://youtu.be/%s"
|
|
||||||
|
|
||||||
func YTUrl(uri string) (vid string, err error) {
|
|
||||||
u, err := url.Parse(uri)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch u.Host {
|
|
||||||
case "youtu.be":
|
|
||||||
vid = u.Path[1:]
|
|
||||||
case "m.youtube.com":
|
|
||||||
fallthrough
|
|
||||||
case "youtube.com":
|
|
||||||
fallthrough
|
|
||||||
case "www.youtube.com":
|
|
||||||
vid = u.Query().Get("v")
|
|
||||||
}
|
|
||||||
|
|
||||||
if vid == "" {
|
|
||||||
return vid, fmt.Errorf("unable to parse vid")
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
func NewYTdlUrl(vid string) ([]byte, error) {
|
func NewYTdlUrl(vid string) ([]byte, error) {
|
||||||
ytdl := config.GetString("youtube.ytdl")
|
ytdl := config.GetString("youtube.ytdl")
|
||||||
yt := exec.Command(
|
yt := exec.Command(
|
||||||
|
@ -151,6 +132,29 @@ func NewYTdl(vid string) ([]byte, error) {
|
||||||
return tmpfile, nil
|
return tmpfile, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func YTUrl(uri string) (vid string, err error) {
|
||||||
|
u, err := url.Parse(uri)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch u.Host {
|
||||||
|
case "youtu.be":
|
||||||
|
vid = u.Path[1:]
|
||||||
|
case "m.youtube.com":
|
||||||
|
fallthrough
|
||||||
|
case "youtube.com":
|
||||||
|
fallthrough
|
||||||
|
case "www.youtube.com":
|
||||||
|
vid = u.Query().Get("v")
|
||||||
|
}
|
||||||
|
|
||||||
|
if vid == "" {
|
||||||
|
return vid, fmt.Errorf("unable to parse vid")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
func DownloadAmbiance(uri string, name string) error {
|
func DownloadAmbiance(uri string, name string) error {
|
||||||
|
|
Loading…
Reference in New Issue