Handle ambiance somewhat differently.
parent
f2063f5d18
commit
45f9c0024a
204
ambiance.go
204
ambiance.go
|
@ -1,24 +1,216 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/davecheney/xattr"
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
func fnNoExt(fileName string) string {
|
var httpClient = new(http.Client)
|
||||||
return fileName[:len(fileName)-len(filepath.Ext(fileName))]
|
|
||||||
|
type Ambiance struct {
|
||||||
|
Id string
|
||||||
|
Title string
|
||||||
|
Path string
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAmbiance() ([]string, error) {
|
func GetAmbiance(id string) (amb Ambiance, err error) {
|
||||||
|
fp := filepath.Join("./ambiance", id+".opus")
|
||||||
|
_, err = os.Stat(fp)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
title, err := xattr.Getxattr(fp, "title")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ambiance{
|
||||||
|
Id: id,
|
||||||
|
Title: string(title),
|
||||||
|
Path: fp,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAmbiances() (amb []Ambiance, err error) {
|
||||||
files, err := os.ReadDir("./ambiance")
|
files, err := os.ReadDir("./ambiance")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var out []string
|
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
out = append(out, fnNoExt(file.Name()))
|
title, err := xattr.Getxattr(filepath.Join("./ambiance", file.Name()), "title")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
|
||||||
|
}
|
||||||
|
amb = append(amb, Ambiance{
|
||||||
|
Id: file.Name()[:len(file.Name())-len(filepath.Ext(file.Name()))],
|
||||||
|
Title: string(title),
|
||||||
|
Path: filepath.Join("./ambiance", file.Name()),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return out, nil
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddAmbiance(uri, title string) (Ambiance, error) {
|
||||||
|
var amb Ambiance
|
||||||
|
|
||||||
|
tmpfile, err := exec.Command("mktemp", "/tmp/dnd_XXXXXXXXXXXX.opus").Output()
|
||||||
|
if err != nil {
|
||||||
|
return amb, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpfile = tmpfile[:len(tmpfile)-1]
|
||||||
|
|
||||||
|
vid, err := YTUrl(uri)
|
||||||
|
if err != nil {
|
||||||
|
return amb, err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Start YTdl for %s", uri)
|
||||||
|
dluri, err := NewYTdl(vid)
|
||||||
|
if err != nil {
|
||||||
|
return amb, err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Start download.. %s", uri)
|
||||||
|
resp, err := httpClient.Get(string(dluri))
|
||||||
|
if err != nil {
|
||||||
|
return amb, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
ff := exec.Command(
|
||||||
|
"ffmpeg",
|
||||||
|
"-y",
|
||||||
|
"-i", "-",
|
||||||
|
"-vn",
|
||||||
|
"-acodec", "copy",
|
||||||
|
"-movflags", "+faststart",
|
||||||
|
"-t", "01:00:00",
|
||||||
|
"-v", "error",
|
||||||
|
// "-stats",
|
||||||
|
"-progress", "pipe:1",
|
||||||
|
// "-af", "loudnorm=I=-16:LRA=11:TP=-1.5",
|
||||||
|
string(tmpfile),
|
||||||
|
)
|
||||||
|
|
||||||
|
ffprogress, err := ff.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
return amb, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ff.Stderr = os.Stderr
|
||||||
|
ff.Stdin = resp.Body
|
||||||
|
|
||||||
|
err = ff.Start()
|
||||||
|
if err != nil {
|
||||||
|
return amb, err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Start ffmpeg to extract audio to %s", string(tmpfile))
|
||||||
|
msg := make(map[string]interface{})
|
||||||
|
msg["event"] = "ambiance_encode_start"
|
||||||
|
data := make(map[string]string)
|
||||||
|
data["name"] = title
|
||||||
|
msg["payload"] = data
|
||||||
|
ws_msg <- msg
|
||||||
|
|
||||||
|
msg = make(map[string]interface{})
|
||||||
|
msg["event"] = "ambiance_encode_progress"
|
||||||
|
data = make(map[string]string)
|
||||||
|
data["name"] = title
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(ffprogress)
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
p := strings.Split(scanner.Text(), "=")
|
||||||
|
if len(p) == 2 {
|
||||||
|
data[p[0]] = strings.TrimSpace(p[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
prate.Do(func() {
|
||||||
|
msg["payload"] = data
|
||||||
|
ws_msg <- msg
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return amb, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ff.Wait()
|
||||||
|
if err != nil {
|
||||||
|
return amb, err
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = make(map[string]interface{})
|
||||||
|
msg["event"] = "ambiance_encode_complete"
|
||||||
|
data = make(map[string]string)
|
||||||
|
data["name"] = title
|
||||||
|
msg["payload"] = data
|
||||||
|
ws_msg <- msg
|
||||||
|
|
||||||
|
id := uuid.New()
|
||||||
|
fn := filepath.Join("./ambiance", fmt.Sprintf("%s.opus", id.String()))
|
||||||
|
|
||||||
|
log.Printf("Moving to %s", fn)
|
||||||
|
|
||||||
|
in, err := os.Open(string(tmpfile))
|
||||||
|
if err != nil {
|
||||||
|
return amb, err
|
||||||
|
}
|
||||||
|
|
||||||
|
of, err := os.Create(fn)
|
||||||
|
if err != nil {
|
||||||
|
return amb, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(of, in)
|
||||||
|
if err != nil {
|
||||||
|
return amb, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = of.Sync()
|
||||||
|
if err != nil {
|
||||||
|
return amb, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = of.Close()
|
||||||
|
if err != nil {
|
||||||
|
return amb, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = in.Close()
|
||||||
|
if err != nil {
|
||||||
|
return amb, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.Remove(string(tmpfile))
|
||||||
|
if err != nil {
|
||||||
|
return amb, err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("Setting xattr")
|
||||||
|
err = xattr.Setxattr(fn, "title", []byte(title))
|
||||||
|
if err != nil {
|
||||||
|
return amb, err
|
||||||
|
}
|
||||||
|
|
||||||
|
amb.Id = id.String()
|
||||||
|
amb.Title = title
|
||||||
|
|
||||||
|
log.Println("Return info.")
|
||||||
|
return amb, nil
|
||||||
}
|
}
|
||||||
|
|
2
bot.go
2
bot.go
|
@ -52,7 +52,7 @@ type App struct {
|
||||||
youtube *youtube.Service
|
youtube *youtube.Service
|
||||||
queue *Queue
|
queue *Queue
|
||||||
ambiance beep.Mixer
|
ambiance beep.Mixer
|
||||||
curamb string
|
curamb Ambiance
|
||||||
events events.EventEmmiter
|
events events.EventEmmiter
|
||||||
next bool
|
next bool
|
||||||
db *pgx.Conn
|
db *pgx.Conn
|
||||||
|
|
35
events.go
35
events.go
|
@ -1,9 +1,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"dndmusicbot/opus"
|
||||||
discordspeaker "dndmusicbot/speaker"
|
discordspeaker "dndmusicbot/speaker"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
@ -12,7 +12,6 @@ import (
|
||||||
|
|
||||||
"github.com/faiface/beep"
|
"github.com/faiface/beep"
|
||||||
"github.com/faiface/beep/effects"
|
"github.com/faiface/beep/effects"
|
||||||
"github.com/faiface/beep/mp3"
|
|
||||||
"github.com/fhs/gompd/v2/mpd"
|
"github.com/fhs/gompd/v2/mpd"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/kataras/go-events"
|
"github.com/kataras/go-events"
|
||||||
|
@ -146,11 +145,11 @@ func (app *App) ambiancePlay(payload ...interface{}) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var fn string
|
var id string
|
||||||
switch data := payload[0].(type) {
|
switch data := payload[0].(type) {
|
||||||
case json.RawMessage:
|
case json.RawMessage:
|
||||||
var err error
|
var err error
|
||||||
err = json.Unmarshal(data, &fn)
|
err = json.Unmarshal(data, &id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return
|
||||||
|
@ -160,21 +159,30 @@ func (app *App) ambiancePlay(payload ...interface{}) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := os.Open(fmt.Sprintf("./ambiance/%s.mp3", fn))
|
amb, err := GetAmbiance(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Println(err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
play, _, err := mp3.Decode(f)
|
f, err := os.Open(amb.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Println(err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
play, err := opus.New(f)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
loop := beep.Loop(-1, play)
|
loop := beep.Loop(-1, play)
|
||||||
|
|
||||||
volume := &effects.Volume{
|
volume := &effects.Volume{
|
||||||
Streamer: loop,
|
Streamer: loop,
|
||||||
Base: 2,
|
Base: 2,
|
||||||
Volume: -2,
|
Volume: -2.5,
|
||||||
Silent: false,
|
Silent: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,10 +195,10 @@ func (app *App) ambiancePlay(payload ...interface{}) {
|
||||||
msg := make(map[string]interface{})
|
msg := make(map[string]interface{})
|
||||||
out := make(map[string]interface{})
|
out := make(map[string]interface{})
|
||||||
|
|
||||||
app.curamb = fn
|
app.curamb = amb
|
||||||
|
|
||||||
msg["event"] = "ambiance_play"
|
msg["event"] = "ambiance_play"
|
||||||
out["type"] = fn
|
out["id"] = id
|
||||||
msg["payload"] = out
|
msg["payload"] = out
|
||||||
ws_msg <- msg
|
ws_msg <- msg
|
||||||
}
|
}
|
||||||
|
@ -235,7 +243,7 @@ func (app *App) ambianceAdd(payload ...interface{}) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err := DownloadAmbiance(amburl, ambtitle)
|
amb, err := AddAmbiance(amburl, ambtitle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return
|
||||||
|
@ -244,7 +252,8 @@ func (app *App) ambianceAdd(payload ...interface{}) {
|
||||||
msg := make(map[string]interface{})
|
msg := make(map[string]interface{})
|
||||||
out := make(map[string]interface{})
|
out := make(map[string]interface{})
|
||||||
msg["event"] = "ambiance_add"
|
msg["event"] = "ambiance_add"
|
||||||
out["type"] = ambtitle
|
out["title"] = amb.Title
|
||||||
|
out["id"] = amb.Id
|
||||||
msg["payload"] = out
|
msg["payload"] = out
|
||||||
ws_msg <- msg
|
ws_msg <- msg
|
||||||
}
|
}
|
||||||
|
|
5
go.mod
5
go.mod
|
@ -6,6 +6,7 @@ go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/bwmarrin/discordgo v0.26.1
|
github.com/bwmarrin/discordgo v0.26.1
|
||||||
|
github.com/davecheney/xattr v0.0.0-20151008032638-dc6dbbe49f0b
|
||||||
github.com/faiface/beep v1.1.0
|
github.com/faiface/beep v1.1.0
|
||||||
github.com/fhs/gompd/v2 v2.3.0
|
github.com/fhs/gompd/v2 v2.3.0
|
||||||
github.com/gohugoio/hugo v0.106.0
|
github.com/gohugoio/hugo v0.106.0
|
||||||
|
@ -15,13 +16,16 @@ require (
|
||||||
github.com/jackc/pgx/v5 v5.1.0
|
github.com/jackc/pgx/v5 v5.1.0
|
||||||
github.com/julienschmidt/httprouter v1.3.0
|
github.com/julienschmidt/httprouter v1.3.0
|
||||||
github.com/kataras/go-events v0.0.3
|
github.com/kataras/go-events v0.0.3
|
||||||
|
github.com/peterhellberg/link v1.2.0
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/sosodev/duration v1.0.1
|
github.com/sosodev/duration v1.0.1
|
||||||
github.com/spf13/afero v1.9.3
|
github.com/spf13/afero v1.9.3
|
||||||
github.com/spf13/viper v1.14.0
|
github.com/spf13/viper v1.14.0
|
||||||
github.com/tidwall/gjson v1.14.3
|
github.com/tidwall/gjson v1.14.3
|
||||||
|
golang.org/x/net v0.2.0
|
||||||
golang.org/x/time v0.2.0
|
golang.org/x/time v0.2.0
|
||||||
google.golang.org/api v0.103.0
|
google.golang.org/api v0.103.0
|
||||||
|
gopkg.in/hraban/opus.v2 v2.0.0-20220302220929-eeacdbcb92d0
|
||||||
layeh.com/gopus v0.0.0-20210501142526-1ee02d434e32
|
layeh.com/gopus v0.0.0-20210501142526-1ee02d434e32
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -75,7 +79,6 @@ require (
|
||||||
github.com/yuin/goldmark v1.5.3 // indirect
|
github.com/yuin/goldmark v1.5.3 // indirect
|
||||||
go.opencensus.io v0.24.0 // indirect
|
go.opencensus.io v0.24.0 // indirect
|
||||||
golang.org/x/crypto v0.2.0 // indirect
|
golang.org/x/crypto v0.2.0 // indirect
|
||||||
golang.org/x/net v0.2.0 // indirect
|
|
||||||
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect
|
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect
|
||||||
golang.org/x/sys v0.2.0 // indirect
|
golang.org/x/sys v0.2.0 // indirect
|
||||||
golang.org/x/text v0.4.0 // indirect
|
golang.org/x/text v0.4.0 // indirect
|
||||||
|
|
13
go.sum
13
go.sum
|
@ -91,11 +91,11 @@ github.com/d4l3k/messagediff v1.2.2-0.20190829033028-7e0a312ae40b/go.mod h1:Oozb
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecheney/xattr v0.0.0-20151008032638-dc6dbbe49f0b h1:a/CjIrvEH2NkUUIo4sqWIw+h3E63ttmS8L8Vx3ZaLS0=
|
||||||
|
github.com/davecheney/xattr v0.0.0-20151008032638-dc6dbbe49f0b/go.mod h1:Gc/R1HBRJIEElnD4PGXGQZQYMb14oPbvTovm6WeuAvk=
|
||||||
github.com/disintegration/gift v1.2.1 h1:Y005a1X4Z7Uc+0gLpSAsKhWi4qLtsdEcMIbbdvdZ6pc=
|
github.com/disintegration/gift v1.2.1 h1:Y005a1X4Z7Uc+0gLpSAsKhWi4qLtsdEcMIbbdvdZ6pc=
|
||||||
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
|
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
|
||||||
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||||
github.com/dpup/gohubbub v0.0.0-20140517235056-2dc6969d22d8 h1:t1Ox7k2+GSzIv3fihjV7YFGb40nb/e2oyrTM/ngbzbA=
|
|
||||||
github.com/dpup/gohubbub v0.0.0-20140517235056-2dc6969d22d8/go.mod h1:QqXVl9BAyVoWIZE4oA9XfkwCjQ3JaajiX4vq7Zh8Vzs=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
|
@ -277,6 +277,8 @@ github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3v
|
||||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
|
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
||||||
|
github.com/peterhellberg/link v1.2.0 h1:UA5pg3Gp/E0F2WdX7GERiNrPQrM1K6CVJUUWfHa4t6c=
|
||||||
|
github.com/peterhellberg/link v1.2.0/go.mod h1:gYfAh+oJgQu2SrZHg5hROVRQe1ICoK0/HHJTcE0edxc=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
@ -284,8 +286,6 @@ github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qR
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/r3labs/sse/v2 v2.8.2 h1:YWZy2i2nLoD5fE3vLLTdTz/8wxIYIFp5XbLNmmrrNts=
|
|
||||||
github.com/r3labs/sse/v2 v2.8.2/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I=
|
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||||
|
@ -406,7 +406,6 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
@ -663,14 +662,14 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y=
|
|
||||||
gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/fatih/set.v0 v0.2.1 h1:Xvyyp7LXu34P0ROhCyfXkmQCAoOUKb1E2JS9I7SE5CY=
|
gopkg.in/fatih/set.v0 v0.2.1 h1:Xvyyp7LXu34P0ROhCyfXkmQCAoOUKb1E2JS9I7SE5CY=
|
||||||
gopkg.in/fatih/set.v0 v0.2.1/go.mod h1:5eLWEndGL4zGGemXWrKuts+wTJR0y+w+auqUJZbmyBg=
|
gopkg.in/fatih/set.v0 v0.2.1/go.mod h1:5eLWEndGL4zGGemXWrKuts+wTJR0y+w+auqUJZbmyBg=
|
||||||
|
gopkg.in/hraban/opus.v2 v2.0.0-20220302220929-eeacdbcb92d0 h1:B8lK1KhYrE4H3urNYBAL/UquYftW65IHPY8JP3gpZ4M=
|
||||||
|
gopkg.in/hraban/opus.v2 v2.0.0-20220302220929-eeacdbcb92d0/go.mod h1:/L5E7a21VWl8DeuCPKxQBdVG5cy+L0MRZ08B1wnqt7g=
|
||||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/neurosnap/sentences.v1 v1.0.6/go.mod h1:YlK+SN+fLQZj+kY3r8DkGDhDr91+S3JmTb5LSxFRQo0=
|
gopkg.in/neurosnap/sentences.v1 v1.0.6/go.mod h1:YlK+SN+fLQZj+kY3r8DkGDhDr91+S3JmTb5LSxFRQo0=
|
||||||
|
|
10
mpd.go
10
mpd.go
|
@ -145,7 +145,17 @@ func (m *MPD) Err() error {
|
||||||
func (m *MPD) Stream(samples [][2]float64) (n int, ok bool) {
|
func (m *MPD) Stream(samples [][2]float64) (n int, ok bool) {
|
||||||
tmp := make([]byte, m.f.NumChannels+2)
|
tmp := make([]byte, m.f.NumChannels+2)
|
||||||
|
|
||||||
|
status, err := app.mpd.Status()
|
||||||
|
if err != nil {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
for i := range samples {
|
for i := range samples {
|
||||||
|
if status["state"] != "play" {
|
||||||
|
samples[i] = [2]float64{}
|
||||||
|
ok = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
dn, err := m.file.Read(tmp)
|
dn, err := m.file.Read(tmp)
|
||||||
if dn == len(tmp) {
|
if dn == len(tmp) {
|
||||||
samples[i], _ = m.f.DecodeSigned(tmp)
|
samples[i], _ = m.f.DecodeSigned(tmp)
|
||||||
|
|
5
queue.go
5
queue.go
|
@ -13,11 +13,6 @@ import (
|
||||||
discordspeaker "dndmusicbot/speaker"
|
discordspeaker "dndmusicbot/speaker"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Ambiance struct {
|
|
||||||
Type string
|
|
||||||
URL string
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log.Println("queue.go loading..")
|
log.Println("queue.go loading..")
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ func init() {
|
||||||
|
|
||||||
type IndexData struct {
|
type IndexData struct {
|
||||||
Playlists []Playlist
|
Playlists []Playlist
|
||||||
Ambiance []string
|
Ambiance []Ambiance
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app App) ServeFiles(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
func (app App) ServeFiles(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||||
|
@ -79,7 +79,7 @@ func (app App) Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params
|
||||||
http.Error(w, "Unable to get playlists. "+err.Error(), http.StatusInternalServerError)
|
http.Error(w, "Unable to get playlists. "+err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
amblist, err := GetAmbiance()
|
amblist, err := GetAmbiances()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -107,9 +107,27 @@ window.onload = function () {
|
||||||
ws.onmessage = (e) => {
|
ws.onmessage = (e) => {
|
||||||
data = JSON.parse(e.data)
|
data = JSON.parse(e.data)
|
||||||
switch (data.event) {
|
switch (data.event) {
|
||||||
|
case "ambiance_add":
|
||||||
|
const container = document.querySelector("#ambiance")
|
||||||
|
var newdiv = document.createElement('div');
|
||||||
|
newdiv.className = "item"
|
||||||
|
newdiv.dataset.id = data.payload.id
|
||||||
|
newdiv.innerText = data.payload.title
|
||||||
|
addInteractHandler(newdiv, (e, isTouch) => {
|
||||||
|
isTouch && e.preventDefault()
|
||||||
|
|
||||||
|
var id = e.target.dataset.id
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
"event": ((id === "reset") ? "ambiance_stop" : "ambiance_play"),
|
||||||
|
"payload": id
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
|
||||||
|
container.insertBefore(newdiv, document.querySelector("#ambiance div:last-child"))
|
||||||
|
break
|
||||||
case "ambiance_play":
|
case "ambiance_play":
|
||||||
document.querySelectorAll("#ambiance > div").forEach((e) => {e.style.removeProperty("background-color")})
|
document.querySelectorAll("#ambiance > div").forEach((e) => {e.style.removeProperty("background-color")})
|
||||||
document.querySelector(`#ambiance > div[data-id='${data.payload.type}']`).style.backgroundColor = "burlywood"
|
document.querySelector(`#ambiance > div[data-id='${data.payload.id}']`).style.backgroundColor = "burlywood"
|
||||||
ambiance.style.pointerEvents = 'auto'
|
ambiance.style.pointerEvents = 'auto'
|
||||||
break
|
break
|
||||||
case "ambiance_stop":
|
case "ambiance_stop":
|
||||||
|
@ -172,6 +190,9 @@ window.onload = function () {
|
||||||
"url": url.value
|
"url": url.value
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
title.value = ""
|
||||||
|
url.value = ""
|
||||||
})
|
})
|
||||||
|
|
||||||
addInteractHandler(submit, (e, isTouch) => {
|
addInteractHandler(submit, (e, isTouch) => {
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
<title>D&D Music Bot!</title>
|
<title>D&D Music Bot!</title>
|
||||||
<link rel="stylesheet" href="/css/solarized-dark.css">
|
<link rel="stylesheet" href="/css/solarized-dark.css">
|
||||||
<link rel="stylesheet" href="/css/style.css">
|
<link rel="stylesheet" href="/css/style.css">
|
||||||
|
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAACNklEQVQ4jaWSy0vUcRTFP/f7G4cUUqzAZtQsgzYWiDMjjYgotbOtYLSIFlKBix7YH9DWXQaRFRREi8hN9MCFPZDUzB4IUkRo5Oho1CLTcEbne1o0UWCI0FndC+cezr33wH/C/m5mkvFOw04JIsBrmXVVDI0OryfgfhepZH0bWA/wFaMLqDXp/nQyuWVDAhi1wIz36k5n/BXgMVAamI+vJxD6o7TS61Uw7QLbEXH+OGIOQzmtTG7IgVfBPjOdE6oXdtrQd8mOVQ6/+vCbM9XcvGmipia8xsFsLLZN6DBQZWIRKJPZISd5gLFYrCBaYF3KLB0IFxdVzyQTZYZukNXZEEA2CDaH8SUS5zHbBVZo+AE5OzrXEL+eyxHxZo2IyzL/FqywcnhsFCCktrYgnZrqWc35nsCCqHM2mJMWkXuD+RVPUIvzRxB3K0Ze3F5zg8/pj1XCEkEQ9OHoZnH5uaFAYfXjrcmhUkPvyit39v7zC9lcKO1Y3QoEwOD28fEl4CRAqiFxJyddAHuUnpwsnW9MFIdW3JeMW41Ghl++N/AOMuX5YTCqlU/nbCxWZLDXQRfQRNiNr+Z0L+OUFHZwNhm/CRBaWMh8Ki0u+iYoQeyZ3Z+4lcKeytSBqPOyZ2a+X1grWESoE6wFWAZwNRMTWaEzBk/yLtrNdAmow7gaHRm96HEpYCC/divGjGEdv+h5qLk5lM4utUvWAvxw8g8iI2MPAeYbE9VeFMrbNZl2GzoRHRrrWy+hG8ZPg13xb+XS+CIAAAAASUVORK5CYII=">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
@ -52,7 +53,7 @@
|
||||||
<section>
|
<section>
|
||||||
<div id="ambiance" class="item-container">
|
<div id="ambiance" class="item-container">
|
||||||
{{ range .Ambiance }}
|
{{ range .Ambiance }}
|
||||||
<div class="item drag" data-id="{{ . }}">{{ . }}</div>
|
<div class="item drag" data-id="{{ .Id }}">{{ .Title }}</div>
|
||||||
{{ end}}
|
{{ end}}
|
||||||
<div class="item locked stop" data-id="reset">Stop</div>
|
<div class="item locked stop" data-id="reset">Stop</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
2
ws.go
2
ws.go
|
@ -73,7 +73,7 @@ func handleWS(c *websocket.Conn) error {
|
||||||
msg := make(map[string]interface{})
|
msg := make(map[string]interface{})
|
||||||
out := make(map[string]interface{})
|
out := make(map[string]interface{})
|
||||||
msg["event"] = "ambiance_play"
|
msg["event"] = "ambiance_play"
|
||||||
out["type"] = app.curamb
|
out["id"] = app.curamb.Id
|
||||||
msg["payload"] = out
|
msg["payload"] = out
|
||||||
c.WriteJSON(msg)
|
c.WriteJSON(msg)
|
||||||
} else {
|
} else {
|
||||||
|
|
39
ytdl.go
39
ytdl.go
|
@ -1,16 +1,12 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/tidwall/gjson"
|
|
||||||
"golang.org/x/time/rate"
|
"golang.org/x/time/rate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,7 +15,7 @@ var yturl = "https://youtu.be/%s"
|
||||||
|
|
||||||
func NewYTdl(vid string) ([]byte, error) {
|
func NewYTdl(vid string) ([]byte, error) {
|
||||||
ytdl := config.GetString("youtube.ytdl")
|
ytdl := config.GetString("youtube.ytdl")
|
||||||
uri, err := exec.Command(
|
yt := exec.Command(
|
||||||
ytdl,
|
ytdl,
|
||||||
fmt.Sprintf(yturl, vid),
|
fmt.Sprintf(yturl, vid),
|
||||||
"--cookies", "./cookies.txt",
|
"--cookies", "./cookies.txt",
|
||||||
|
@ -30,7 +26,11 @@ func NewYTdl(vid string) ([]byte, error) {
|
||||||
"--restrict-filenames",
|
"--restrict-filenames",
|
||||||
"-f", "251",
|
"-f", "251",
|
||||||
"--get-url",
|
"--get-url",
|
||||||
).Output()
|
)
|
||||||
|
|
||||||
|
yt.Stderr = os.Stderr
|
||||||
|
|
||||||
|
uri, err := yt.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -38,15 +38,25 @@ func NewYTdl(vid string) ([]byte, error) {
|
||||||
return uri[:len(uri)-1], nil
|
return uri[:len(uri)-1], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DownloadAmbiance(uri string, name string) error {
|
func YTUrl(uri string) (vid string, err error) {
|
||||||
ytdl := config.GetString("youtube.ytdl")
|
u, err := url.Parse(uri)
|
||||||
|
|
||||||
tmpfile, err := exec.Command("mktemp", "/tmp/dnd_XXXXXXXXXXXX.aac").Output()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpfile = tmpfile[:len(tmpfile)-1]
|
switch u.Host {
|
||||||
|
case "youtu.be":
|
||||||
|
vid = u.Path[1:]
|
||||||
|
case "youtube.com":
|
||||||
|
vid = u.Query().Get("v")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
func DownloadAmbiance(uri string, name string) error {
|
||||||
|
ytdl := config.GetString("youtube.ytdl")
|
||||||
|
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
ytdl,
|
ytdl,
|
||||||
|
@ -55,7 +65,7 @@ func DownloadAmbiance(uri string, name string) error {
|
||||||
"--no-cache-dir",
|
"--no-cache-dir",
|
||||||
"-f", "140",
|
"-f", "140",
|
||||||
"--cookies", "../cookies.txt",
|
"--cookies", "../cookies.txt",
|
||||||
"-o", string(tmpfile),
|
"-o", "-",
|
||||||
"--force-overwrites",
|
"--force-overwrites",
|
||||||
"-q",
|
"-q",
|
||||||
"--progress",
|
"--progress",
|
||||||
|
@ -180,3 +190,4 @@ func DownloadAmbiance(uri string, name string) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
Loading…
Reference in New Issue