package ytdl import ( "errors" "fmt" "log" "os/exec" "path/filepath" "time" "github.com/gohugoio/hugo/cache/filecache" "github.com/spf13/afero" "github.com/tidwall/gjson" ) var cache *filecache.Cache var yturl = "https://youtu.be/%s" func init() { fs := afero.NewMemMapFs() cache = filecache.NewCache(fs, 6*time.Hour, "") } type YTdl struct { Title string Url string Channel string Len time.Duration } func NewYTdl(vid string) (*YTdl, error) { log.Printf("Loading %s from youtube\n", vid) _, ytdl_js, err := cache.GetOrCreateBytes(vid+".json", func() ([]byte, error) { log.Printf("%s not found in cache, downloading info.\n", vid) js, err := exec.Command( "./bin/yt-dlp_linux", fmt.Sprintf(yturl, vid), "--cookies", "./cookies.txt", "--no-call-home", "--no-cache-dir", "--ignore-errors", "--newline", "--restrict-filenames", "-f", "140", "-j", ).Output() if err != nil { return nil, err } log.Printf("%s is now cached.\n", vid) return js, nil }) if err != nil { return nil, err } if !gjson.ValidBytes(ytdl_js) { return nil, errors.New("invalid json") } results := gjson.GetManyBytes(ytdl_js, "title", "url", "duration", "channel") title := results[0].String() geturl := results[1].String() duration, err := time.ParseDuration(fmt.Sprintf("%ds", results[2].Int())) channel := results[3].String() return &YTdl{title, geturl, channel, duration}, nil } func DownloadAmbiance(uri string, name string) error { err := exec.Command( "./bin/yt-dlp_linux", uri, "-x", "--audio-format", "mp3", "--postprocessor-args", "-ar 48000 -ac 2", "--cookies", "./cookies.txt", "--no-call-home", "--no-cache-dir", "--restrict-filenames", "-f", "140", "-o", filepath.Join("./ambiance/", name+".mp3"), ).Run() if err != nil { return nil } return nil }