aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2022-07-26 22:23:37 +0200
committerFlorian Fischer <florian.fischer@muhq.space>2022-07-26 22:23:37 +0200
commit33fd4442dd8297d02d284e82cf09bbfec01c705a (patch)
treebe15f36161859c24971f62b3f89c4effe9c1e349
parent7e15ad1d8af4ee27f6c1d31e7b1608e2d751c402 (diff)
downloadWRMS-33fd4442dd8297d02d284e82cf09bbfec01c705a.tar.gz
WRMS-33fd4442dd8297d02d284e82cf09bbfec01c705a.zip
add youtube backend
-rw-r--r--go.mod9
-rw-r--r--go.sum16
-rw-r--r--player.go8
-rw-r--r--playlist.go3
-rw-r--r--web/client.html12
-rw-r--r--wrms.go9
-rw-r--r--youtube.go36
7 files changed, 79 insertions, 14 deletions
diff --git a/go.mod b/go.mod
index 013d1ec..29298e2 100644
--- a/go.mod
+++ b/go.mod
@@ -3,6 +3,7 @@ module muhq.space/wrms
go 1.18
require (
+ github.com/AnjanaMadu/YTSearch v1.0.0
github.com/google/uuid v1.3.0
github.com/librespot-org/librespot-golang v0.0.0-20220325184705-31669e5a889f
nhooyr.io/websocket v1.8.7
@@ -10,11 +11,13 @@ require (
require (
github.com/badfortrains/mdns v0.0.0-20160325001438-447166384f51 // indirect
+ github.com/buger/jsonparser v1.1.1 // indirect
github.com/golang/protobuf v1.5.0 // indirect
- github.com/klauspost/compress v1.10.3 // indirect
+ github.com/klauspost/compress v1.10.4 // indirect
github.com/miekg/dns v1.1.8 // indirect
+ github.com/stretchr/testify v1.5.1 // indirect
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 // indirect
- golang.org/x/net v0.0.0-20190420063019-afa5a82059c6 // indirect
- golang.org/x/sys v0.0.0-20200116001909-b77594299b42 // indirect
+ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect
+ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd // indirect
google.golang.org/protobuf v1.27.1 // indirect
)
diff --git a/go.sum b/go.sum
index afd47b7..2e5ce48 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,9 @@
+github.com/AnjanaMadu/YTSearch v1.0.0 h1:88ovSXJDVSr/bNQY90CYdpAIDSYtlW2Ik6D8VHRdfFo=
+github.com/AnjanaMadu/YTSearch v1.0.0/go.mod h1:ReflwduZK14df7oUOSuNDqLwox2D2heQknhYbEWQlD8=
github.com/badfortrains/mdns v0.0.0-20160325001438-447166384f51 h1:b6+GdpGhuzxPETrVLwY77iq0L/BqLpcPRmaLNW+SoRY=
github.com/badfortrains/mdns v0.0.0-20160325001438-447166384f51/go.mod h1:qHRkxMBkkpAWD2poeBYQt6O5IS4dE6w1Cr4Z8Q3feXI=
+github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
+github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -34,8 +38,9 @@ github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvK
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8=
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.10.4 h1:jFzIFaf586tquEB5EhzQG0HwGNSlgAJpG53G6Ss11wc=
+github.com/klauspost/compress v1.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/librespot-org/librespot-golang v0.0.0-20220325184705-31669e5a889f h1:tTMPsyVClxxV+CnlLqzgxTTTFM6J7i//rSejN1Md0b0=
@@ -52,8 +57,9 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
@@ -63,14 +69,16 @@ github.com/xlab/vorbis-go v0.0.0-20190125051917-087364aef51d/go.mod h1:AMqfx3jFw
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 h1:O5YqonU5IWby+w98jVUG9h7zlCWCcH4RHyPVReBmhzk=
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
-golang.org/x/net v0.0.0-20190420063019-afa5a82059c6 h1:HdqqaWmYAUI7/dmByKKEw+yxDksGSo+9GjkUc9Zp34E=
golang.org/x/net v0.0.0-20190420063019-afa5a82059c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
+golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
diff --git a/player.go b/player.go
index a672288..49b6d11 100644
--- a/player.go
+++ b/player.go
@@ -28,6 +28,7 @@ func NewPlayer(wrms *Wrms) Player {
log.Println("Error during initialization of the spotify backend:", err.Error())
}
available_backends["spotify"] = spotify
+ available_backends["youtube"] = &YoutubeBackend{}
available_backends["dummy"] = &DummyBackend{}
@@ -45,19 +46,20 @@ func (player *Player) Play(song *Song) {
}
func (player *Player) runMpv() {
- out, err := player.mpv.CombinedOutput()
+ _, err := player.mpv.CombinedOutput()
if err != nil {
log.Fatal(err)
}
- log.Println("mpv finished with", out, "resetting mpv, the current song and call play")
+ log.Println("mpv finished. Resetting mpv, the current song and call play")
player.mpv = nil
player.wrms.CurrentSong.Uri = ""
player.wrms.PlayPause()
}
func (player *Player) PlayUri(uri string) {
- player.mpv = exec.Command("mpv", uri)
+ log.Println("Start mpv with ", uri)
+ player.mpv = exec.Command("mpv", "--no-video", uri)
go player.runMpv()
}
diff --git a/playlist.go b/playlist.go
index b37ab3d..8f17055 100644
--- a/playlist.go
+++ b/playlist.go
@@ -36,6 +36,9 @@ func (pl *Playlist) Pop() any {
}
func (pl *Playlist) PopSong() *Song {
+ if len(*pl) == 0 {
+ return nil
+ }
return heap.Pop(pl).(*Song)
}
diff --git a/web/client.html b/web/client.html
index ba57839..3cddb29 100644
--- a/web/client.html
+++ b/web/client.html
@@ -76,6 +76,12 @@
let playing = {};
let votes = new Map();
+ function formatSong(song) {
+ if (song.artist)
+ return song.artist + ' - ' + song.title
+ return song.title
+ }
+
function renderPlaylist() {
playlist = document.getElementById("playlist");
playlist.innerHTML = "";
@@ -131,7 +137,7 @@
listItem.appendChild(upvoteBtn);
listItem.appendChild(downvoteBtn);
- const itemValue = document.createTextNode(song.artist + " - " + song.title);
+ const itemValue = document.createTextNode(formatSong(song));
listItem.appendChild(itemValue);
playlist.appendChild(listItem);
}
@@ -163,7 +169,7 @@
renderPlaylist();
}
- const songLabel = document.createTextNode(currentSong.artist + " - " + currentSong.title);
+ const songLabel = document.createTextNode(formatSong(currentSong));
playing = document.getElementById("playing");
playing.innerHTML = "";
@@ -234,7 +240,7 @@
listItem.classList.add("searchResult")
- let searchResultLabel = document.createTextNode(song.artist + " - " + song.title);
+ let searchResultLabel = document.createTextNode(formatSong(song));
listItem.appendChild(searchResultLabel);
searchResults.appendChild(listItem);
diff --git a/wrms.go b/wrms.go
index 4df78fa..12d7fd7 100644
--- a/wrms.go
+++ b/wrms.go
@@ -91,7 +91,14 @@ func (wrms *Wrms) AddSong(song Song) {
}
func (wrms *Wrms) Next() {
- wrms.CurrentSong = *wrms.Queue.PopSong()
+ next := wrms.Queue.PopSong()
+ if next == nil {
+ wrms.CurrentSong.Uri = ""
+ return
+ }
+
+ wrms.CurrentSong = *next
+
for i, s := range wrms.Songs {
if s.Uri == wrms.CurrentSong.Uri {
wrms.Songs[i] = wrms.Songs[len(wrms.Songs)-1]
diff --git a/youtube.go b/youtube.go
new file mode 100644
index 0000000..a3f92d7
--- /dev/null
+++ b/youtube.go
@@ -0,0 +1,36 @@
+package main
+
+import (
+ "fmt"
+ "github.com/AnjanaMadu/YTSearch"
+ "log"
+)
+
+type YoutubeBackend struct{}
+
+func (youtube *YoutubeBackend) Play(song *Song, player *Player) {
+ player.PlayUri("https://youtube.com/watch?v=" + song.Uri)
+}
+
+func (youtube *YoutubeBackend) Search(pattern string) []Song {
+ results, err := ytsearch.Search(pattern)
+ if err != nil {
+ log.Fatal("Youtube search failed with", err)
+ }
+
+ songs := []Song{}
+ for i, result := range results {
+ if i == 10 {
+ break
+ }
+
+ if result.VideoId == "" {
+ continue
+ }
+
+ songs = append(songs, NewSong(result.Title, "", "youtube", result.VideoId))
+ }
+
+ log.Println(fmt.Sprintf("youtube found %d matching videos", len(songs)))
+ return songs
+}