package main import ( //"flag" "context" //"fmt" "os" //"io" //"reflect" //"google.golang.org/api/option" //"google.golang.org/api/youtube/v3" "github.com/wader/goutubedl" "github.com/BurntSushi/toml" "github.com/charmbracelet/log" "github.com/alexflint/go-arg" ) type _flags struct { Quiet bool `arg:"-q,--quiet" help:"Output only warnings and errors."` Verbose bool `arg:"-v,--verbose" help:"Enables debug output."` ConfigFile string `arg:"-c,--config,env:YTVA_CONFIG" help:"Specifies the path to a TOML formatted configuration file." default:"config.toml"` } func (_flags) Description() string { return "YouTube Video Archive - Downloads videos in bulk automatically" } var Flags _flags type ConfigFile struct { OutputDir string Channels []string YouTube struct { VideoFormat string AudioFormat string } } var MainConfig ConfigFile func main() { _ = arg.MustParse(&Flags) if Flags.Verbose { log.SetReportCaller(true) log.SetLevel(log.DebugLevel) if Flags.Quiet { log.Warn("Verbose and quiet specified. Defaulting to verbose.") } } else if Flags.Quiet { log.SetLevel(log.WarnLevel) } confFile, err := os.ReadFile(Flags.ConfigFile) if(err != nil) { log.Fatal(err) } confContent := string(confFile) _, err = toml.Decode(confContent, &MainConfig) log.Debug("", "config", MainConfig) goutubedl.Path = "yt-dlp" if _, err := os.Stat(MainConfig.OutputDir); err != nil { if os.IsNotExist(err) { if err := os.Mkdir(MainConfig.OutputDir, 0755); err != nil { log.Fatal(err) } } else { log.Fatal(err) } } for _, channel := range MainConfig.Channels { log.Info("==========================================================================================================") log.Infof("Channel URL: \"%s\"", channel) optType := goutubedl.TypeFromString["channel"] channel, err := goutubedl.New(context.Background(), channel, goutubedl.Options{ Type: optType, PlaylistEnd: 2, }, ) if err != nil { log.Fatalf("Error creating YouTube service: %v", err) } log.Infof("Channel Name: %s", channel.Info.Channel) basePath := MainConfig.OutputDir+"/"+channel.Info.Channel+"/" if _, err := os.Stat(basePath); err != nil { if os.IsNotExist(err) { if err := os.Mkdir(basePath, 0755); err != nil { log.Fatal(err) } } else { log.Fatal(err) } } for _, v := range channel.Info.Entries { log.Debugf("-----------------------------------------------------") log.Debugf("Title: %s", v.Title) log.Debugf("URL: %s", v.WebpageURL) log.Debugf("Playlist: %s", v.Playlist) log.Debugf("PublishedAt: %s", v.UploadDate) log.Debugf("IsLive: %t", v.IsLive) //log.Debugf("Description: %s\n", item.Snippet.Description) dirPath := basePath+"/"+v.Playlist+"/" if _, err := os.Stat(dirPath); err != nil { if os.IsNotExist(err) { if err := os.Mkdir(dirPath, 0755); err != nil { log.Fatal(err) } } else { log.Fatal(err) } } log.Infof("Downloading video: %s", v.Title) downloadVideo(v.WebpageURL, MainConfig.YouTube.VideoFormat, MainConfig.YouTube.AudioFormat, dirPath, 2^32) } } }