dndmusicbot/ambiance.go

238 lines
4.3 KiB
Go
Raw Normal View History

2022-11-18 21:18:12 +00:00
package main
import (
2022-11-25 13:06:26 +00:00
"bufio"
"fmt"
"io"
"log"
2023-10-26 20:44:53 +00:00
"math"
2022-11-18 21:18:12 +00:00
"os"
2022-11-25 13:06:26 +00:00
"os/exec"
2022-11-18 21:18:12 +00:00
"path/filepath"
2023-10-26 20:44:53 +00:00
"strconv"
2022-11-25 13:06:26 +00:00
"strings"
2023-10-26 20:44:53 +00:00
"time"
2022-11-25 13:06:26 +00:00
"github.com/davecheney/xattr"
"github.com/google/uuid"
2022-11-18 21:18:12 +00:00
)
2023-09-06 20:46:05 +00:00
//var httpClient = new(http.Client)
2022-11-25 13:06:26 +00:00
type Ambiance struct {
Id string
Title string
Path string
}
func GetAmbiance(id string) (amb Ambiance, err error) {
2023-10-26 20:44:53 +00:00
fp := filepath.Join(config.GetString("ambiance.path"), id+".opus")
2022-11-25 13:06:26 +00:00
_, 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
2022-11-18 21:18:12 +00:00
}
2022-11-25 13:06:26 +00:00
func GetAmbiances() (amb []Ambiance, err error) {
2023-10-26 20:44:53 +00:00
files, err := os.ReadDir(config.GetString("ambiance.path"))
2022-11-18 21:18:12 +00:00
if err != nil {
return nil, err
}
for _, file := range files {
2023-10-26 20:44:53 +00:00
title, err := xattr.Getxattr(filepath.Join(config.GetString("ambiance.path"), file.Name()), "title")
2022-11-25 13:06:26 +00:00
if err != nil {
return nil, err
}
amb = append(amb, Ambiance{
Id: file.Name()[:len(file.Name())-len(filepath.Ext(file.Name()))],
Title: string(title),
2023-10-26 20:44:53 +00:00
Path: filepath.Join(config.GetString("ambiance.path"), file.Name()),
2022-11-25 13:06:26 +00:00
})
2022-11-18 21:18:12 +00:00
}
2022-11-25 13:06:26 +00:00
return
}
func AddAmbiance(uri, title string) (Ambiance, error) {
var amb Ambiance
2023-09-06 20:46:05 +00:00
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
}()
2022-11-25 13:06:26 +00:00
tmpfile, err := exec.Command("mktemp", "/tmp/dnd_XXXXXXXXXXXX.opus").Output()
if err != nil {
return amb, err
}
tmpfile = tmpfile[:len(tmpfile)-1]
2023-09-06 20:46:05 +00:00
log.Printf("Parsing vid from %s", uri)
2022-11-25 13:06:26 +00:00
vid, err := YTUrl(uri)
if err != nil {
return amb, err
}
2023-10-26 20:44:53 +00:00
vinfo, err := app.youtube.GetVideoFromID(vid)
2022-11-25 13:06:26 +00:00
if err != nil {
return amb, err
}
2023-10-26 20:44:53 +00:00
log.Printf("Start ffmpeg for %s (%s)", vid, vinfo.VideoDetails.Title)
2022-11-25 13:06:26 +00:00
ff := exec.Command(
"ffmpeg",
"-y",
2023-10-26 20:44:53 +00:00
"-i", vinfo.GetHLSPlaylist("234"),
2022-11-25 13:06:26 +00:00
"-vn",
2023-10-26 20:44:53 +00:00
//"-acodec", "copy",
2022-11-25 13:06:26 +00:00
"-movflags", "+faststart",
"-t", "01:00:00",
2023-10-26 20:44:53 +00:00
"-ar", "48000",
"-v", "quiet",
2022-11-25 13:06:26 +00:00
// "-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
err = ff.Start()
if err != nil {
return amb, err
}
log.Printf("Start ffmpeg to extract audio to %s", string(tmpfile))
2023-09-06 20:46:05 +00:00
msg = make(map[string]interface{})
2022-11-25 13:06:26 +00:00
msg["event"] = "ambiance_encode_start"
2023-09-06 20:46:05 +00:00
data = make(map[string]string)
2022-11-25 13:06:26 +00:00
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() {
2023-10-26 20:44:53 +00:00
out_time, ok := data["out_time_ms"]
if ok {
out_time_ms, _ := strconv.Atoi(out_time)
percent := fmt.Sprintf("%.0f", math.Floor((float64(out_time_ms)/float64(time.Hour.Microseconds()))*100))
data["percent"] = percent
}
2022-11-25 13:06:26 +00:00
msg["payload"] = data
ws_msg <- msg
})
}
2023-09-06 20:46:05 +00:00
2022-11-25 13:06:26 +00:00
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()
2023-10-26 20:44:53 +00:00
fn := filepath.Join(config.GetString("ambiance.path"), fmt.Sprintf("%s.opus", id.String()))
2022-11-25 13:06:26 +00:00
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
2022-11-18 21:18:12 +00:00
}