Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

downloader: ⬆️ aria2 #286

Merged
merged 2 commits into from
Oct 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,21 @@ $ annie -j https://www.bilibili.com/video/av20203945
Youku ccode
```

#### aria2:

> Note: If you use aria2 to download, you need to merge the multi-part videos yourself.

```
-aria2
Use Aria2 RPC to download
-aria2addr string
Aria2 Address (default "localhost:6800")
-aria2method string
Aria2 Method (default "http")
-aria2token string
Aria2 RPC Token
```


## Supported Sites

Expand Down
8 changes: 4 additions & 4 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ var (
OutputName string
// ExtractedData print extracted data
ExtractedData bool
// Aria2 RPC
// UseAria2RPC Use Aria2 RPC to download
UseAria2RPC bool
// Aria2 RPC Token
// Aria2Token Aria2 RPC Token
Aria2Token string
// Aria2 Address, use localhost:6800 as default
// Aria2Addr Aria2 Address (default "localhost:6800")
Aria2Addr string
// Aria2 Method, use http as default
// Aria2Method Aria2 Method (default "http")
Aria2Method string
// ThreadNumber The number of download thread (only works for multiple-parts video)
ThreadNumber int
Expand Down
76 changes: 43 additions & 33 deletions downloader/downloader.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package downloader

import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"sort"
"strings"
"time"
"net/http"
"bytes"

"github.com/cheggaaa/pb"
"github.com/fatih/color"
Expand Down Expand Up @@ -38,19 +38,19 @@ type FormatData struct {
name string
}

// JsonRPC 2.0 for Aria2
// Aria2RPCData json RPC 2.0 for Aria2
type Aria2RPCData struct {
// More info about RPC interface please refer to
// More info about RPC interface please refer to
// https://aria2.github.io/manual/en/html/aria2c.html#rpc-interface
Jsonrpc string `json:"jsonrpc"`
Id string `json:"id"`
JSONRPC string `json:"jsonrpc"`
ID string `json:"id"`
// For a simple download, only inplemented `addUri`
Method string `json:"method"`
// secret, uris, options
Params [3]interface{} `json:"params"`
}

// Options for `aria2.addUri`
// Aria2Input options for `aria2.addUri`
// https://aria2.github.io/manual/en/html/aria2c.html#id3
type Aria2Input struct {
// For a simple download, only add headers
Expand Down Expand Up @@ -226,7 +226,8 @@ func Save(

// close and rename temp file at the end of this function
defer func() {
// must close the file before rename or it will cause `The process cannot access the file because it is being used by another process.` error.
// must close the file before rename or it will cause
// `The process cannot access the file because it is being used by another process.` error.
file.Close()
if err == nil {
os.Rename(tempFilePath, filePath)
Expand Down Expand Up @@ -296,31 +297,6 @@ func (v VideoData) Download(refer string) error {
fmt.Printf("%s\n", jsonData)
return nil
}
// User aria2 rpc to download
if config.UseAria2RPC {
rpcData := Aria2RPCData {
Jsonrpc: "2.0",
Id: "annie", // can be modified
Method: "aria2.addUri",
}
rpcData.Params[0] = "token:" + config.Aria2Token
var urls []string
for _, p := range v.sortedFormats[0].URLs {
urls = append(urls, p.URL)
}
rpcData.Params[1] = &urls
var inputs Aria2Input
inputs.Header = append(inputs.Header, "Referer: " + refer)
rpcData.Params[2] = &inputs
jsonData, _ := json.Marshal(rpcData)
reqUrl := config.Aria2Method + "://" + config.Aria2Addr + "/jsonrpc"
req, _ := http.NewRequest("POST", reqUrl, bytes.NewBuffer(jsonData))
req.Header.Set("Content-Type", "application/json")
var client http.Client
resp, _ := client.Do(req)
defer resp.Body.Close()
return nil
}
var (
title string
format string
Expand All @@ -343,6 +319,40 @@ func (v VideoData) Download(refer string) error {
if config.InfoOnly {
return nil
}
// Use aria2 rpc to download
if config.UseAria2RPC {
rpcData := Aria2RPCData{
JSONRPC: "2.0",
ID: "annie", // can be modified
Method: "aria2.addUri",
}
rpcData.Params[0] = "token:" + config.Aria2Token
var urls []string
for _, p := range data.URLs {
urls = append(urls, p.URL)
}
rpcData.Params[1] = &urls
var inputs Aria2Input
inputs.Header = append(inputs.Header, "Referer: "+refer)
rpcData.Params[2] = &inputs
jsonData, err := json.Marshal(rpcData)
if err != nil {
return err
}
reqURL := fmt.Sprintf("%s://%s/jsonrpc", config.Aria2Method, config.Aria2Addr)
req, err := http.NewRequest("POST", reqURL, bytes.NewBuffer(jsonData))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
var client http.Client
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
return nil
}
var err error
// Skip the complete file that has been merged
mergedFilePath, err := utils.FilePath(title, "mp4", false)
Expand Down
11 changes: 6 additions & 5 deletions extractors/youku/youku_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import (

func TestDownload(t *testing.T) {
config.InfoOnly = true
config.Ccode = "0103010102"
config.RetryTimes = 100
config.Ccode = "0590"
tests := []struct {
name string
args test.Args
Expand All @@ -19,17 +20,17 @@ func TestDownload(t *testing.T) {
args: test.Args{
URL: "http://v.youku.com/v_show/id_XMzUzMjE3NDczNg==.html",
Title: "车事儿:智能汽车已经不在遥远 东风风光iX5发布",
Size: 45185427,
Quality: "mp4hd3 1920x1080",
Size: 22692900,
Quality: "mp4hd2v2 1280x720",
},
},
{
name: "normal test",
args: test.Args{
URL: "http://v.youku.com/v_show/id_XMzQ1MTAzNjQwNA==.html",
Title: "这!就是街舞 第一季 第3期:百强“互杀”队长不忍直视",
Size: 1419459808,
Quality: "mp4hd3 1920x1080 国语",
Size: 750911635,
Quality: "mp4hd2v2 1280x720 国语",
},
},
}
Expand Down
16 changes: 6 additions & 10 deletions test/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,11 @@ func CheckData(args, data Args) bool {
return false
}
// not every video got quality information
if args.Quality != "" {
if args.Quality != data.Quality {
return false
}
if args.Quality != "" && args.Quality != data.Quality {
return false
}
if args.Size != 0 {
if args.Size != data.Size {
return false
}
if args.Size != 0 && args.Size != data.Size {
return false
}
return true
}
Expand All @@ -42,13 +38,13 @@ func Check(t *testing.T, args Args, data downloader.VideoData) {
Size: defaultData.Size,
}
if !CheckData(args, temp) {
t.Errorf("Got: %v\nExpected: %v", data, args)
t.Errorf("Got: %v\nExpected: %v", temp, args)
}
}

// CheckError check the error
func CheckError(t *testing.T, err error) {
if err != nil {
t.Errorf("Unexpected error: %v", err)
t.Fatalf("Unexpected error: %v", err)
}
}