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

WIP: Add httpchunksize option #208

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ audio and video codec)
`retranscode` - Retranscode even if input codec is same as output
`time` - Only download specificed time range. Ex: `30s`, `20m30s`, `1h20s30s` will limit
duration. `10s-30s` will seek 10 seconds and stop at 30 seconds (20 second output duration)
`items` - If playlist only include this many items
`items` - If playlist only include this many items
`httpchunksize`- Make youtube-dl do range requests of specified size (see youtube-dl `--http-chunk-size`)

`option` - Codec name, time range, `retranscode` or `<N>items`

Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/wader/ydls

go 1.12
go 1.13

require (
// bump: leaktest /github.com\/fortytw2\/leaktest v(.*)/ git:https://github.com/fortytw2/leaktest.git|^1
Expand All @@ -19,3 +19,5 @@ require (
// bump: sync command go get -d golang.org/x/sync && go mod tidy
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
)

replace github.com/wader/goutubedl => /Users/wader/src/goutubedl
41 changes: 41 additions & 0 deletions internal/humnum/humnum.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package humnum

import (
"fmt"
"strconv"
"strings"
"unicode"
)

func Atoi(s string) (int, error) {
i := strings.IndexFunc(s, func(r rune) bool {
return !unicode.IsDigit(r)
})
if i == -1 {
i = len(s)
}

prefix, suffix := s[0:i], s[i:]
n, _ := strconv.Atoi(prefix)
m := 1
if suffix != "" {
switch strings.ToLower(suffix) {
case "k":
m = 1000
case "ki", "kibi":
m = 1024
case "m":
m = 1000 * 1000
case "mi", "mibi":
m = 1024 * 1024
case "g":
m = 1000 * 1000 * 1000
case "gi", "gibi":
m = 1024 * 1024 * 1024
default:
return 9, fmt.Errorf("unknown suffix %q", suffix)
}
}

return n * m, nil
}
37 changes: 37 additions & 0 deletions internal/humnum/numnum_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package humnum_test

import (
"testing"

"github.com/wader/ydls/internal/humnum"
)

func TestAtoi(t *testing.T) {
testCases := []struct {
s string
expectedN int
expectedErr string
}{
{s: "", expectedN: 0},
{s: "1000", expectedN: 1000},
{s: "1K", expectedN: 1000},
{s: "1k", expectedN: 1000},
{s: "1M", expectedN: 1000_000},
{s: "1G", expectedN: 1000_000_000},
{s: "1Ki", expectedN: 1024},
{s: "1Mi", expectedN: 1024 * 1024},
{s: "1Gi", expectedN: 1024 * 1024 * 1024},
{s: "1Kibi", expectedN: 1024},
{s: "1Mibi", expectedN: 1024 * 1024},
{s: "1Gibi", expectedN: 1024 * 1024 * 1024},
{s: "123abc", expectedErr: `unknown suffix "abc"`},
}
for _, tC := range testCases {
t.Run(tC.s, func(t *testing.T) {
actualN, actualErr := humnum.Atoi(tC.s)
if (tC.expectedErr != "" && (actualErr == nil || tC.expectedErr != actualErr.Error())) && actualN != tC.expectedN {
t.Errorf("expected %v (%v), got %v (%v)", tC.expectedN, tC.expectedErr, actualN, actualErr)
}
})
}
}
41 changes: 28 additions & 13 deletions internal/ydls/requestoptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@ import (
"strconv"
"strings"

"github.com/wader/ydls/internal/humnum"
"github.com/wader/ydls/internal/timerange"
)

// RequestOptions request options
type RequestOptions struct {
MediaRawURL string // youtubedl media URL
Format *Format // output format
Codecs []string // force codecs
Retranscode bool // force retranscode even if same input codec
TimeRange timerange.TimeRange // time range limit
Items uint // feed item count limit
MediaRawURL string // youtubedl media URL
Format *Format // output format
Codecs []string // force codecs
Retranscode bool // force retranscode even if same input codec
TimeRange timerange.TimeRange // time range limit
Items uint // feed item count limit
HTTPChunkSize uint // youtubedl http chunk size option
}

// NewRequestOptionsFromQuery /?url=...&format=...
Expand Down Expand Up @@ -70,13 +72,24 @@ func NewRequestOptionsFromQuery(v url.Values, formats Formats) (RequestOptions,
items = uint(itemsN)
}

httpChunkSize := uint(0)
httpChunkSizeStr := v.Get("httpchunksize")
if httpChunkSizeStr != "" {
httpChunkSizeN, httpChunkSizeNErr := humnum.Atoi(httpChunkSizeStr)
if httpChunkSizeNErr != nil {
return RequestOptions{}, fmt.Errorf("invalid HTTP chunk size")
}
httpChunkSize = uint(httpChunkSizeN)
}

return RequestOptions{
MediaRawURL: mediaRawURL,
Format: format,
Codecs: codecs,
Retranscode: v.Get("retranscode") != "",
TimeRange: timeRange,
Items: items,
MediaRawURL: mediaRawURL,
Format: format,
Codecs: codecs,
Retranscode: v.Get("retranscode") != "",
TimeRange: timeRange,
Items: items,
HTTPChunkSize: httpChunkSize,
}, nil
}

Expand Down Expand Up @@ -173,7 +186,6 @@ func NewRequestOptionsFromOpts(opts []string, formats Formats) (RequestOptions,
return RequestOptions{}, fmt.Errorf("invalid items count")
}
r.Items = uint(itemsN)
strconv.ParseUint("", 10, 32)
} else if _, ok := codecNames[opt]; ok {
r.Codecs = append(r.Codecs, opt)
} else if tr, trErr := timerange.NewTimeRangeFromString(opt); trErr == nil {
Expand Down Expand Up @@ -206,5 +218,8 @@ func (r RequestOptions) QueryValues() url.Values {
if r.Items > 0 {
v.Set("items", strconv.Itoa(int(r.Items)))
}
if r.HTTPChunkSize != 0 {
v.Set("httpchunksize", strconv.Itoa(int(r.HTTPChunkSize)))
}
return v
}
4 changes: 4 additions & 0 deletions internal/ydls/ydls.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,10 @@ func (ydls *YDLS) download(ctx context.Context, options DownloadOptions, attempt
}
}

if options.RequestOptions.HTTPChunkSize != 0 {
ydlOptions.HTTPChunkSize = options.RequestOptions.HTTPChunkSize
}

ydlResult, err := goutubedl.New(ctx, options.RequestOptions.MediaRawURL, ydlOptions)
if err != nil {
log.Printf("Failed to download: %s", err)
Expand Down