package main import ( "bufio" "fmt" "log" "os" "regexp" "strings" "sync" //"path/filepath" "github.com/gosuri/uiprogress" . "github.com/kkdai/youtube" ) type Batch struct { batchfile, destDir string } func NewBatch(batchFile, destinationDir string) *Batch { return &Batch{batchfile: batchFile, destDir: destinationDir} } func (b *Batch) Start() { //Start downloading all videos log.Println("Start downloading...") //open the file containing yt links linkfile, err := os.Open(b.batchfile) if err != nil { log.Fatal(err) } defer linkfile.Close() //Create scanner to go line by line through the file //This scanner allows 65536 characters per line. //That should be enough for yt links. scanner := bufio.NewScanner(linkfile) //Start rendering for progressbar //This is the initialization the actual bars //will be instantiated in the go routines uiprogress.Start() var wg sync.WaitGroup for scanner.Scan() { //Call download //add go routine to wait for if strings.TrimSpace(scanner.Text()) != "" { wg.Add(1) log.Println(scanner.Text()) go downloadVideo(b.destDir, strings.TrimSpace(scanner.Text()), &wg) } else { log.Println("Ignoring blank line") } } //wait for all go routines to finish wg.Wait() log.Println("All downloads finished") if err := scanner.Err(); err != nil { log.Fatal(err) } } func downloadVideo(destDir, url string, wg *sync.WaitGroup) { // NewYoutube(debug) if debug parameter will set true we can log of messages //defer Done() so that WaitGroup knows when the routine finishes defer wg.Done() y := NewYoutube(false) y.DecodeURL(url) re := regexp.MustCompile("(mp4|webm|3gpp)") fileext := re.FindString(y.StreamList[0]["type"]) filename := fmt.Sprintf("%s/%s.%s", destDir, y.StreamList[0]["title"], fileext) filenameRune := []rune(y.StreamList[0]["title"]) shortFilename := string(filenameRune[0:20]) + "..." go func() { bar := uiprogress.AddBar(100).AppendCompleted() //Custom decorator (the short name in front of the bar) bar.PrependFunc(func(b *uiprogress.Bar) string { return shortFilename }) var i int64 = 0 for i < 100 { i = <-y.DownloadPercent bar.Set(int(i)) } }() //start the actual download err := y.StartDownload(filename) if err != nil { log.Println("Failed to download", url) log.Println("Message:", err.Error()) } }