Skip to content

Commit

Permalink
Multi-threading
Browse files Browse the repository at this point in the history
  • Loading branch information
lukecold committed Nov 21, 2015
1 parent bf993ac commit 267849f
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ Gotube is a YouTube downloader using go language.
go language is a new light-weight language developed by Google,
it provides not only many powerful libraries, but also a simple multi-threading syntax.

This tool is an easy way to download any non-age-restricted videos in YouTube.
You can also perform batch downloading by keywords via search function.
Gotube will generate a number of go-routines (no more than the number of your CPU cores) to download multiple videos simultaneously.

##Installation
- Install go from [https://golang.org/](https://golang.org/)
- Set up go environment as in [https://golang.org/doc/install](https://golang.org/doc/install)
Expand Down
37 changes: 34 additions & 3 deletions script.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"fmt"
. "github.com/KeluDiao/gotube/api"
"log"
"runtime"
"sync"
)

func main() {
Expand Down Expand Up @@ -77,25 +79,42 @@ func main() {
if *isRetList {
fmt.Printf("The top %v results for key words \"%v\" are:\n\n", *k, *search)
}
//Waiting group is used to prevent main thread ending before child threads end
wg := new(sync.WaitGroup)
wg.Add(len(ids))
//Channel is used to control the maximum threads
end := make(chan bool, MaxParallelism())
for _, vid := range ids {
vl, err = GetVideoListFromId(vid)
if err != nil {
log.Fatal(err)
}
Exec(vl, *isDownload, *isRetList, *rep, *quality, *extension)
go Exec(vl, *isDownload, *isRetList, *rep, *quality, *extension, wg, end)
end <- true
}
wg.Wait()
return
}
if err != nil {
log.Fatal(err)
}
Exec(vl, *isDownload, *isRetList, *rep, *quality, *extension)
//dummy variables
wg := new(sync.WaitGroup)
wg.Add(1)
var end chan bool
Exec(vl, *isDownload, *isRetList, *rep, *quality, *extension, wg, end)
}

/*
* Choose either downloading or retrieving video list
*/
func Exec(vl VideoList, isDownload, isRetList bool, rep, quality, extension string) {
func Exec(vl VideoList, isDownload, isRetList bool, rep, quality, extension string, wg *sync.WaitGroup, end chan bool) {
//Set up synchronization function
defer func() {
<- end
wg.Done()
}

if isDownload {
fmt.Printf("Downloading %v...\n", vl.Title)
err := vl.Download(rep, quality, extension)
Expand All @@ -110,4 +129,16 @@ func Exec(vl VideoList, isDownload, isRetList bool, rep, quality, extension stri
}
fmt.Println(vl)
}
}

/*
* Find out the maximum go routines allowed
*/
func MaxParallelism() int {
maxProcs := runtime.GOMAXPROCS(0)
numCPU := runtime.NumCPU()
if maxProcs < numCPU {
return maxProcs
}
return numCPU
}

0 comments on commit 267849f

Please sign in to comment.