Fix ambiance download
parent
1888592d07
commit
b26b43f163
46
ambiance.go
46
ambiance.go
|
@ -5,7 +5,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -15,7 +14,7 @@ import (
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
var httpClient = new(http.Client)
|
//var httpClient = new(http.Client)
|
||||||
|
|
||||||
type Ambiance struct {
|
type Ambiance struct {
|
||||||
Id string
|
Id string
|
||||||
|
@ -67,6 +66,22 @@ 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
|
||||||
|
|
||||||
|
msg := make(map[string]interface{})
|
||||||
|
msg["event"] = "ambiance_add_start"
|
||||||
|
data := make(map[string]string)
|
||||||
|
data["name"] = title
|
||||||
|
msg["payload"] = data
|
||||||
|
ws_msg <- msg
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
msg = make(map[string]interface{})
|
||||||
|
msg["event"] = "ambiance_add_finish"
|
||||||
|
data = make(map[string]string)
|
||||||
|
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()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return amb, err
|
return amb, err
|
||||||
|
@ -74,28 +89,23 @@ func AddAmbiance(uri, title string) (Ambiance, error) {
|
||||||
|
|
||||||
tmpfile = tmpfile[:len(tmpfile)-1]
|
tmpfile = tmpfile[:len(tmpfile)-1]
|
||||||
|
|
||||||
|
log.Printf("Parsing vid from %s", uri)
|
||||||
vid, err := YTUrl(uri)
|
vid, err := YTUrl(uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return amb, err
|
return amb, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Start YTdl for %s", uri)
|
log.Printf("Start download with YTdl for %s", uri)
|
||||||
dluri, err := NewYTdl(vid)
|
ytfile, err := NewYTdl(vid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return amb, err
|
return amb, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Start download.. %s", uri)
|
log.Printf("Start ffmpeg for %s", string(ytfile))
|
||||||
resp, err := httpClient.Get(string(dluri))
|
|
||||||
if err != nil {
|
|
||||||
return amb, err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
ff := exec.Command(
|
ff := exec.Command(
|
||||||
"ffmpeg",
|
"ffmpeg",
|
||||||
"-y",
|
"-y",
|
||||||
"-i", "-",
|
"-i", string(ytfile),
|
||||||
"-vn",
|
"-vn",
|
||||||
"-acodec", "copy",
|
"-acodec", "copy",
|
||||||
"-movflags", "+faststart",
|
"-movflags", "+faststart",
|
||||||
|
@ -113,7 +123,6 @@ func AddAmbiance(uri, title string) (Ambiance, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ff.Stderr = os.Stderr
|
ff.Stderr = os.Stderr
|
||||||
ff.Stdin = resp.Body
|
|
||||||
|
|
||||||
err = ff.Start()
|
err = ff.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -121,9 +130,10 @@ 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))
|
||||||
msg := make(map[string]interface{})
|
|
||||||
|
msg = make(map[string]interface{})
|
||||||
msg["event"] = "ambiance_encode_start"
|
msg["event"] = "ambiance_encode_start"
|
||||||
data := make(map[string]string)
|
data = make(map[string]string)
|
||||||
data["name"] = title
|
data["name"] = title
|
||||||
msg["payload"] = data
|
msg["payload"] = data
|
||||||
ws_msg <- msg
|
ws_msg <- msg
|
||||||
|
@ -146,6 +156,7 @@ func AddAmbiance(uri, title string) (Ambiance, error) {
|
||||||
ws_msg <- msg
|
ws_msg <- msg
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := scanner.Err(); err != nil {
|
if err := scanner.Err(); err != nil {
|
||||||
return amb, err
|
return amb, err
|
||||||
}
|
}
|
||||||
|
@ -197,6 +208,11 @@ func AddAmbiance(uri, title string) (Ambiance, error) {
|
||||||
return amb, err
|
return amb, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = os.Remove(string(ytfile))
|
||||||
|
if err != nil {
|
||||||
|
return amb, err
|
||||||
|
}
|
||||||
|
|
||||||
err = os.Remove(string(tmpfile))
|
err = os.Remove(string(tmpfile))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return amb, err
|
return amb, err
|
||||||
|
|
|
@ -147,6 +147,39 @@ window.onload = function () {
|
||||||
avol.value = data.payload.ambiance
|
avol.value = data.payload.ambiance
|
||||||
avol.nextElementSibling.value = data.payload.ambiance
|
avol.nextElementSibling.value = data.payload.ambiance
|
||||||
break
|
break
|
||||||
|
case "ambiance_download_start":
|
||||||
|
var progress = document.querySelector("#progressambiance progress")
|
||||||
|
progress.style.display = "initial"
|
||||||
|
progress.style.width = "100%"
|
||||||
|
progress.value = 0
|
||||||
|
break
|
||||||
|
case "ambiance_download_progress":
|
||||||
|
var progress = document.querySelector("#progressambiance progress")
|
||||||
|
progress.style.display = "initial"
|
||||||
|
progress.value = data.payload.percent
|
||||||
|
console.log(data)
|
||||||
|
break
|
||||||
|
case "ambiance_download_complete":
|
||||||
|
var progress = document.querySelector("#progressambiance progress")
|
||||||
|
progress.style.display = "initial"
|
||||||
|
progress.value = 100
|
||||||
|
break
|
||||||
|
case "ambiance_add_finish":
|
||||||
|
var title = document.querySelector("#inputambiance > input[name='title']")
|
||||||
|
var url = document.querySelector("#inputambiance > input[name='url']")
|
||||||
|
var submit = document.querySelector("#inputambiance > input[name='submit']")
|
||||||
|
var progress = document.querySelector("#progressambiance progress")
|
||||||
|
|
||||||
|
title.value = ""
|
||||||
|
url.value = ""
|
||||||
|
|
||||||
|
title.disabled = false
|
||||||
|
url.disabled = false
|
||||||
|
submit.disabled = false
|
||||||
|
|
||||||
|
progress.value = 0
|
||||||
|
progress.style.display = "none"
|
||||||
|
break
|
||||||
case "ambiance_add":
|
case "ambiance_add":
|
||||||
const container = document.querySelector("#ambiance")
|
const container = document.querySelector("#ambiance")
|
||||||
var newdiv = document.createElement('div');
|
var newdiv = document.createElement('div');
|
||||||
|
@ -164,6 +197,21 @@ window.onload = function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
container.insertBefore(newdiv, document.querySelector("#ambiance div:last-child"))
|
container.insertBefore(newdiv, document.querySelector("#ambiance div:last-child"))
|
||||||
|
var title = document.querySelector("#inputambiance > input[name='title']")
|
||||||
|
var url = document.querySelector("#inputambiance > input[name='url']")
|
||||||
|
var submit = document.querySelector("#inputambiance > input[name='submit']")
|
||||||
|
var progress = document.querySelector("#progressambiance progress")
|
||||||
|
|
||||||
|
title.value = ""
|
||||||
|
url.value = ""
|
||||||
|
|
||||||
|
title.disabled = false
|
||||||
|
url.disabled = false
|
||||||
|
submit.disabled = false
|
||||||
|
|
||||||
|
progress.value = 0
|
||||||
|
progress.style.display = "none"
|
||||||
|
|
||||||
break
|
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")})
|
||||||
|
@ -218,6 +266,7 @@ window.onload = function () {
|
||||||
//output.innerText = ""
|
//output.innerText = ""
|
||||||
var title = document.querySelector("#inputambiance > input[name='title']")
|
var title = document.querySelector("#inputambiance > input[name='title']")
|
||||||
var url = document.querySelector("#inputambiance > input[name='url']")
|
var url = document.querySelector("#inputambiance > input[name='url']")
|
||||||
|
var submit = document.querySelector("#inputambiance > input[name='submit']")
|
||||||
if (title.value == "" || url.value == "") {
|
if (title.value == "" || url.value == "") {
|
||||||
console.log("Title or Url is empty!")
|
console.log("Title or Url is empty!")
|
||||||
return
|
return
|
||||||
|
@ -231,8 +280,9 @@ window.onload = function () {
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
title.value = ""
|
title.disabled = true
|
||||||
url.value = ""
|
url.disabled = true
|
||||||
|
submit.disabled = true
|
||||||
})
|
})
|
||||||
|
|
||||||
addInteractHandler(submit, (e, isTouch) => {
|
addInteractHandler(submit, (e, isTouch) => {
|
||||||
|
|
|
@ -59,6 +59,12 @@
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<div id="progressambiance" class="input-container">
|
||||||
|
<progress max="100" value="0" style="display:none">0%</progress>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<div id="inputambiance" class="input-container">
|
<div id="inputambiance" class="input-container">
|
||||||
<input class="u-full-width" name="title" type="text" placeholder="Enter name..">
|
<input class="u-full-width" name="title" type="text" placeholder="Enter name..">
|
||||||
|
|
85
ytdl.go
85
ytdl.go
|
@ -1,10 +1,15 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"math"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/time/rate"
|
"golang.org/x/time/rate"
|
||||||
|
@ -14,28 +19,92 @@ var prate = rate.Sometimes{Interval: 1 * time.Second}
|
||||||
var yturl = "https://youtu.be/%s"
|
var yturl = "https://youtu.be/%s"
|
||||||
|
|
||||||
func NewYTdl(vid string) ([]byte, error) {
|
func NewYTdl(vid string) ([]byte, error) {
|
||||||
|
tmpfile, err := exec.Command("mktemp", "/tmp/dnd_ytdlp_XXXXXXXXXXXX.m4a").Output()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpfile = tmpfile[:len(tmpfile)-1]
|
||||||
|
|
||||||
ytdl := config.GetString("youtube.ytdl")
|
ytdl := config.GetString("youtube.ytdl")
|
||||||
yt := exec.Command(
|
yt := exec.Command(
|
||||||
ytdl,
|
ytdl,
|
||||||
fmt.Sprintf(yturl, vid),
|
fmt.Sprintf(yturl, vid),
|
||||||
|
"-q",
|
||||||
"--cookies", "./cookies.txt",
|
"--cookies", "./cookies.txt",
|
||||||
"--no-call-home",
|
"--no-call-home",
|
||||||
"--no-cache-dir",
|
"--no-cache-dir",
|
||||||
"--ignore-errors",
|
"--ignore-errors",
|
||||||
"--newline",
|
"--newline",
|
||||||
"--restrict-filenames",
|
"--restrict-filenames",
|
||||||
|
"--force-overwrites",
|
||||||
|
"--progress",
|
||||||
|
"--progress-template", "download:{ \"dl_bytes\": \"%(progress.downloaded_bytes)s\", \"total_bytes\": \"%(progress.total_bytes)s\" }",
|
||||||
"-f", "251",
|
"-f", "251",
|
||||||
"--get-url",
|
"-o", string(tmpfile),
|
||||||
)
|
)
|
||||||
|
|
||||||
yt.Stderr = os.Stderr
|
yt.Stderr = os.Stderr
|
||||||
|
ytprogress, err := yt.StdoutPipe()
|
||||||
uri, err := yt.Output()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return uri[:len(uri)-1], nil
|
err = yt.Start()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Start ffmpeg to extract audio to %s", string(tmpfile))
|
||||||
|
msg := make(map[string]interface{})
|
||||||
|
msg["event"] = "ambiance_download_start"
|
||||||
|
data := make(map[string]string)
|
||||||
|
data["name"] = fmt.Sprintf(yturl, vid)
|
||||||
|
msg["payload"] = data
|
||||||
|
ws_msg <- msg
|
||||||
|
|
||||||
|
msg = make(map[string]interface{})
|
||||||
|
msg["event"] = "ambiance_download_progress"
|
||||||
|
data = make(map[string]string)
|
||||||
|
data["name"] = fmt.Sprintf(yturl, vid)
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(ytprogress)
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
err := json.Unmarshal(scanner.Bytes(), &data)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
dl, _ := strconv.ParseFloat(data["dl_bytes"], 64)
|
||||||
|
total, _ := strconv.ParseFloat(data["total_bytes"], 64)
|
||||||
|
percent := math.Floor((dl / total) * 100)
|
||||||
|
data["percent"] = strconv.FormatInt(int64(percent), 10)
|
||||||
|
|
||||||
|
prate.Do(func() {
|
||||||
|
msg["payload"] = data
|
||||||
|
ws_msg <- msg
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = yt.Wait()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = make(map[string]interface{})
|
||||||
|
msg["event"] = "ambiance_download_complete"
|
||||||
|
data = make(map[string]string)
|
||||||
|
data["name"] = fmt.Sprintf(yturl, vid)
|
||||||
|
msg["payload"] = data
|
||||||
|
ws_msg <- msg
|
||||||
|
|
||||||
|
return tmpfile, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func YTUrl(uri string) (vid string, err error) {
|
func YTUrl(uri string) (vid string, err error) {
|
||||||
|
@ -47,10 +116,18 @@ func YTUrl(uri string) (vid string, err error) {
|
||||||
switch u.Host {
|
switch u.Host {
|
||||||
case "youtu.be":
|
case "youtu.be":
|
||||||
vid = u.Path[1:]
|
vid = u.Path[1:]
|
||||||
|
case "m.youtube.com":
|
||||||
|
fallthrough
|
||||||
case "youtube.com":
|
case "youtube.com":
|
||||||
|
fallthrough
|
||||||
|
case "www.youtube.com":
|
||||||
vid = u.Query().Get("v")
|
vid = u.Query().Get("v")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if vid == "" {
|
||||||
|
return vid, fmt.Errorf("unable to parse vid")
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue