rylio / ytdl Goto Github PK
View Code? Open in Web Editor NEWYouTube download library and CLI written in Go
License: MIT License
YouTube download library and CLI written in Go
License: MIT License
$ ytdl https://www.youtube.com/watch?v=qD8hOJoOGtk
INFO[0000] Fetching video info...
FATA[0000] Unable to fetch video info: Error extracting json
No debug log produced when adding the -d option:
$ ytdl -d https://www.youtube.com/watch?v=qD8hOJoOGtk
INFO[0000] Fetching video info...
FATA[0000] Unable to fetch video info: Error extracting json
Hi,
I am using "go version go1.12.9 windows/amd64" with Windows 10.
Executing the code from the example results in 0 bytes file.
Did youtube change the api again or... ?
It would be great if there were binaries of ytdl as part of releases..
This can be done very easily with Go Releaser
This would take care of generating binaries for all platforms in the planet and you would
get the below automagically
If ffmpeg is available in the system the flag -mp3
will convert the downloaded video into mp3
ytdl -mp3 'https://www.youtube.com/watch?v=9bZkp7q19f0'
If you are fine with this i am willing to do it and create a PR
It would be nice if ytdl
supported youtube-dl
's shortcut format selectors: best, worst, bestvideo, bestaudio, worstvideo, worstaudio
diff --git a/cmd/ytdl/main.go b/cmd/ytdl/main.go
index 0ae1b8a..4655437 100644
--- a/cmd/ytdl/main.go
+++ b/cmd/ytdl/main.go
@@ -48,7 +48,7 @@ func main() {
cli.StringFlag{
Name: "output, o",
Usage: "Write output to a file, passing - outputs to stdout",
- Value: "{{.Title}}.{{.Ext}}",
+ Value: "{{.Title}} [{{.ID}}].{{.Ext}}",
},
cli.BoolFlag{
Name: "info, i",
@@ -221,6 +221,7 @@ func handler(identifier string, options options) {
if out == nil {
var fileName string
fileName, err = createFileName(options.outputFile, outputFileName{
+ ID: sanitizeFileNamePart(info.ID),
Title: sanitizeFileNamePart(info.Title),
Ext: sanitizeFileNamePart(format.Extension),
DatePublished: sanitizeFileNamePart(info.DatePublished.Format("2006-01-02")),
diff --git a/cmd/ytdl/utils.go b/cmd/ytdl/utils.go
index 396f7ed..8032103 100644
--- a/cmd/ytdl/utils.go
+++ b/cmd/ytdl/utils.go
@@ -62,6 +62,7 @@ func parseFilter(filterString string) (func(ytdl.FormatList) ytdl.FormatList, er
}
type outputFileName struct {
+ ID string
Title string
Author string
Ext string
Hello!
I am trying to download best available audio for a youtube video. But not able to understand how to achieve that. The example in README is seriously outdated I guess. The import points to "github.com/otium/ytdl" whereas your username is rylio.Can you please provide a complete up to date example as to how to download videos?
Cheers!
Please tag the master branch with the latest version (probably v0.5.1) because the latest tag, v0.5.0, has a bug with getting videos by ID. The bug is fixed in master, but anyone using golang/dep for package dependency management will be forced to upgrade manually.
For a specific video, the list of formats returned does not include worst audio format (compared with youtube-dl
which does include this).
./ytdl -f worst-audio https://www.youtube.com/watch?v=xwx4QzEAKKw
This results in the highest quality video being downloaded!
Doesn't sanitize file names when creating output file.
Very useful project. Thanks.
The type Info
with method func (*Info) Download
makes confusing. Info makes me think it's just some information about something, eg os.FileInfo. Maybe Video
is a better name that Info
. Video.Downlad(...)
is better to understand.
Andrew
Are you going for the "Unix" type flow, where we would pass in multiple Video Id's. Or do you think Playlist support would be ideal in this? I'm willing to look into this over the weekend - unless you already have :), just wanted to know your thoughts on this.
https://www.youtube.com/embed/GxC7llQRovo?list=PLEbnTDJUr_IegfoqO4iPnPYQui46QqT0j
https://www.youtube.com/embed/TbQToa__-bQ
unable to extract video info from this url, and this works
https://youtu.be/TbQToa__-bQ
https://youtu.be/GxC7llQRovo
Thank you.
--verion, -v
- print out ytdl cli version
s/verion/version
The last line in the example golang code is incorrect and does not work.
It should be something like the code below with the first argument being the file format
vid.Download(vid.Formats[0],file)
using the ytdl binary like:
./ytdl -u
or using ytdl in code, has the same issue. On random videos i get this error
When using for example:
./ytdl https://www.youtube.com/watch?v=YqUyNvGsM9s
I get this:
FATA[0000] Unable to get download url: Error parsing signature tokens
Or when using in Go Code:
panic: Error parsing signature tokens
I have reproduced this on Windows 10, Void Linux and Arch Linux.
Videos that do work
https://www.youtube.com/watch?v=1gOQiFEwnZ8
https://www.youtube.com/watch?v=MXgnIP4rMoI
https://www.youtube.com/watch?v=peBgUMT26jM
Videos that don't work
https://www.youtube.com/watch?v=aQZDbBGBJsM
https://www.youtube.com/watch?v=cRS4mS4gKwg
https://www.youtube.com/watch?v=0fllyJTBsRU
I have been unable to find any pattern.
Currently go mod
would download the latest release 0.5.1, which imports github.com/Sirupsen/logrus
as a dependency, for which would make go build complaining a conflict. Have to modify go.mod to specify master branch to workaround this issue, please release a new tag to fix, thanks in advance.
Currently, anything can be passed to GetVideoInfo
, and a *VideoInfo
will be returned, regardless whether or not the passed string is a valid YouTube video link or not.
For example, if i pass if
to GetVideoInfo
, i will be given a *VideoInfo
without an error being returned. I can call Download
on this too and no error is returned from this either, even though its not a valid YouTube video
The returned *VideoInfo
:
&{if 0001-01-01 00:00:00 +0000 UTC [] [] 0s /yts/jsbin/player-vflHDhBq1/en_US/base.js}
Get http:///yts/jsbin/player-en_GB-vflJIlAsj/base.js: http: no Host in request URL
Recently my bot (github.com/vadimyer/RealMusicBot) stopped working for almost all videos because of the error from GetDownloadURL
.
As it seems it constructs a URL without a host.
Can we use proxy to download video?Or if you don't mind,i suggest to add the feature
Add support for converting videos to other media types with ffmpeg or avconv
My current use for youtube-dl
is downloading videos from a specific point onwards, this isn't supported but done by using the URL provided with -g
inside curl
and appending the begin
query parameter.
Example of using the begin
param (it's in milliseconds):
curl $(youtube-dl -g fjImkK1xAZI)'&begin=38000' -o kobe-block.mp4
There is an issue that youtube starts playing from the nearest keyframe which could be before or after the given time. My workflow now is download the video starting 10 seconds prior, run that through ffprobe
, find the closest preceding keyframe and start the download again from there.
I am not sure that google provides an end
or equivalent parameter but it would be useful to have that functionality as well. Ideally I'd be ably to do something like this:
ytdl fjImkK1xAZI --start 38 --end 42 --output --format 18 kobe-block.mp4
If ytdl fails to fetch the video, such as it being blocked or age-restricted, being able to check why would be great for software that needs such functionality.
Something like info.errmsg
from GetVideoInfo
or something might work, or even have a []string
for multiple possible error reasons/messages.
The tokens function decipherTokens generates are invalid right now. I am receiving 403 from the generated URLs =/
it should be possible to resume a previously started (but interrupted) download.
I thought the --append,-a
option was it, but it just restarts from the beginning, appending to the previous short-file.
If we have a server based in say, France, ytdl will get the French title.
A way to specify what language we want our response to be in would be nice.
I think https://www.youtube.com/get_video_info?video_id=${ID}
gets the default title that the uploader uses, if nothing else.
Yeah, it's not on YouTube, but is seems interesting anyway:
$ ytdl https://www.facebook.com/video.php?v=10153820411888896
INFO[0000] Fetching video info...
panic: regexp: Compile(`yt.setConfig('PLAYER_CONFIG', (.*?)</script>`): error parsing regexp: missing closing ): `yt.setConfig('PLAYER_CONFIG', (.*?)</script>`
goroutine 1 [running]:
regexp.MustCompile(0x8dcf80, 0x2c, 0xc8204e2000)
/usr/local/go/src/regexp/regexp.go:221 +0x16f
github.com/otium/ytdl.getInfoFromHTML(0x7ffeafafd0ae, 0x11, 0xc8204e2000, 0x3fc7, 0x7e00, 0x0, 0x0, 0x0)
/home/nl/go-code/src/github.com/otium/ytdl/info.go:173 +0x265e
github.com/otium/ytdl.GetInfoFromID(0x7ffeafafd0ae, 0x11, 0x0, 0x0, 0x0)
/home/nl/go-code/src/github.com/otium/ytdl/info.go:91 +0x4c8
github.com/otium/ytdl.GetInfoFromURL(0xc8200a2700, 0x36, 0x0, 0x0)
/home/nl/go-code/src/github.com/otium/ytdl/info.go:69 +0xfb
github.com/otium/ytdl.GetInfo(0x73c1c0, 0xc820102ad0, 0xc820102ad0, 0x0, 0x0)
/home/nl/go-code/src/github.com/otium/ytdl/info.go:57 +0x16d
main.handler(0x7ffeafafd089, 0x36, 0x0, 0xc82000bde0, 0x13, 0x0, 0xc820014bc0, 0x4, 0x4, 0x0, ...)
/home/nl/go-code/src/github.com/otium/ytdl/cmd/ytdl/main.go:147 +0x340
main.main.func1(0xc8200f79e0)
/home/nl/go-code/src/github.com/otium/ytdl/cmd/ytdl/main.go:109 +0x592
github.com/codegangsta/cli.(*App).Run(0xc8200f78c0, 0xc82000a5a0, 0x2, 0x2, 0x0, 0x0)
/home/nl/go-code/src/github.com/codegangsta/cli/app.go:180 +0x1051
main.main()
/home/nl/go-code/src/github.com/otium/ytdl/cmd/ytdl/main.go:112 +0x10b4
[...]
vid.Download expects 2 parameters instead of 1 as in README. I'm trying to download a video/audio but no matter how I constract the format field it doesn't download it:
vid.Download(ytdl.Format{
Extension: "mp4",
Resolution: "360p",
VideoEncoding: "H.264",
AudioEncoding: "aac",
Itag: 18,
AudioBitrate: 96,
}, file)
What am I doing wrong?
Getting this error while trying to create the FreeBSD port:
# _/usr/ports/www/ytdl/work/ytdl-0.5.1/cmd/ytdl
./main.go:95:13: cannot use func literal (type func(*cli.Context) error) as type func(*cli.Context) in assignment
*** Error code 2
ytld-0.5.1
FreeBSD 11.1
go-1.9.2,1
../go/src/github.com/rylio/ytdl/cmd/ytdl/main.go:47:17: cannot use cli.StringFlag literal (type cli.StringFlag) as type cli.Flag in slice literal:
cli.StringFlag does not implement cli.Flag (Apply method has pointer receiver)
../go/src/github.com/rylio/ytdl/cmd/ytdl/main.go:52:15: cannot use cli.BoolFlag literal (type cli.BoolFlag) as type cli.Flag in slice literal:
cli.BoolFlag does not implement cli.Flag (Apply method has pointer receiver)
../go/src/github.com/rylio/ytdl/cmd/ytdl/main.go:56:15: cannot use cli.BoolFlag literal (type cli.BoolFlag) as type cli.Flag in slice literal:
cli.BoolFlag does not implement cli.Flag (Apply method has pointer receiver)
../go/src/github.com/rylio/ytdl/cmd/ytdl/main.go:60:15: cannot use cli.BoolFlag literal (type cli.BoolFlag) as type cli.Flag in slice literal:
cli.BoolFlag does not implement cli.Flag (Apply method has pointer receiver)
../go/src/github.com/rylio/ytdl/cmd/ytdl/main.go:64:15: cannot use cli.BoolFlag literal (type cli.BoolFlag) as type cli.Flag in slice literal:
cli.BoolFlag does not implement cli.Flag (Apply method has pointer receiver)
../go/src/github.com/rylio/ytdl/cmd/ytdl/main.go:68:22: cannot use cli.StringSliceFlag literal (type cli.StringSliceFlag) as type cli.Flag in slice literal:
cli.StringSliceFlag does not implement cli.Flag (Apply method has pointer receiver)
../go/src/github.com/rylio/ytdl/cmd/ytdl/main.go:72:17: cannot use cli.StringFlag literal (type cli.StringFlag) as type cli.Flag in slice literal:
cli.StringFlag does not implement cli.Flag (Apply method has pointer receiver)
../go/src/github.com/rylio/ytdl/cmd/ytdl/main.go:76:15: cannot use cli.BoolFlag literal (type cli.BoolFlag) as type cli.Flag in slice literal:
cli.BoolFlag does not implement cli.Flag (Apply method has pointer receiver)
../go/src/github.com/rylio/ytdl/cmd/ytdl/main.go:80:15: cannot use cli.BoolFlag literal (type cli.BoolFlag) as type cli.Flag in slice literal:
cli.BoolFlag does not implement cli.Flag (Apply method has pointer receiver)
../go/src/github.com/rylio/ytdl/cmd/ytdl/main.go:84:17: cannot use cli.StringFlag literal (type cli.StringFlag) as type cli.Flag in slice literal:
cli.StringFlag does not implement cli.Flag (Apply method has pointer receiver)
../go/src/github.com/rylio/ytdl/cmd/ytdl/main.go:84:17: too many errors
github.com/Sirupsen/logrus: github.com/Sirupsen/[email protected]: parsing go.mod: module declares its path as: github.com/sirupsen/logrus but was required as: github.com/Sirupsen/logrus
Can you update the import path?
Doesn't the "--append, -a" flag intend to enable http partial request? For example, when there is a partial file downloaded locally and a new http download request is supposed to pick up where it left off. If so, it does not work as expected. The download process just starts all over again and appends to the partial file.
I'm unable to build ytdl:
$ go version
go version go1.13.4 darwin/amd64
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.1
BuildVersion: 19B88
$ go get -u -ldflags "-s -w" github.com/otium/ytdl/...
# github.com/otium/ytdl/cmd/ytdl
go/src/github.com/otium/ytdl/cmd/ytdl/main.go:50:17: cannot use cli.StringFlag literal (type cli.StringFlag) as type cli.Flag in array or slice literal:
cli.StringFlag does not implement cli.Flag (Apply method has pointer receiver)
go/src/github.com/otium/ytdl/cmd/ytdl/main.go:55:15: cannot use cli.BoolFlag literal (type cli.BoolFlag) as type cli.Flag in array or slice literal:
cli.BoolFlag does not implement cli.Flag (Apply method has pointer receiver)
go/src/github.com/otium/ytdl/cmd/ytdl/main.go:59:15: cannot use cli.BoolFlag literal (type cli.BoolFlag) as type cli.Flag in array or slice literal:
cli.BoolFlag does not implement cli.Flag (Apply method has pointer receiver)
go/src/github.com/otium/ytdl/cmd/ytdl/main.go:63:15: cannot use cli.BoolFlag literal (type cli.BoolFlag) as type cli.Flag in array or slice literal:
cli.BoolFlag does not implement cli.Flag (Apply method has pointer receiver)
go/src/github.com/otium/ytdl/cmd/ytdl/main.go:67:15: cannot use cli.BoolFlag literal (type cli.BoolFlag) as type cli.Flag in array or slice literal:
cli.BoolFlag does not implement cli.Flag (Apply method has pointer receiver)
go/src/github.com/otium/ytdl/cmd/ytdl/main.go:71:15: cannot use cli.BoolFlag literal (type cli.BoolFlag) as type cli.Flag in array or slice literal:
cli.BoolFlag does not implement cli.Flag (Apply method has pointer receiver)
go/src/github.com/otium/ytdl/cmd/ytdl/main.go:75:22: cannot use cli.StringSliceFlag literal (type cli.StringSliceFlag) as type cli.Flag in array or slice literal:
cli.StringSliceFlag does not implement cli.Flag (Apply method has pointer receiver)
go/src/github.com/otium/ytdl/cmd/ytdl/main.go:79:17: cannot use cli.StringFlag literal (type cli.StringFlag) as type cli.Flag in array or slice literal:
cli.StringFlag does not implement cli.Flag (Apply method has pointer receiver)
go/src/github.com/otium/ytdl/cmd/ytdl/main.go:83:15: cannot use cli.BoolFlag literal (type cli.BoolFlag) as type cli.Flag in array or slice literal:
cli.BoolFlag does not implement cli.Flag (Apply method has pointer receiver)
go/src/github.com/otium/ytdl/cmd/ytdl/main.go:87:15: cannot use cli.BoolFlag literal (type cli.BoolFlag) as type cli.Flag in array or slice literal:
cli.BoolFlag does not implement cli.Flag (Apply method has pointer receiver)
go/src/github.com/otium/ytdl/cmd/ytdl/main.go:87:15: too many errors
Some high quality formats don't have combined audio and video. Should automatically merge them together if ffmpeg or avconv is available.
Passing video ID starting with a dash (even like this: ytdl -o - "-2TrtmssNPA"
) leads to Incorrect Usage.
It seems like it is trying to parse it as a flag, but I'm not sure how to fix that.
FATA[0001] Unable to open output file: open Instalasi & Hello World di Golang : Tutorial Golang Indonesia [Part1].mp4: invalid argument
There seems to be a problem with the name of the output.
Everything went smoothly when I used the ID from the video for the file name
den@febf7f699c38:tmp$ ytdl https://www.youtube.com/watch?v=-KGfp2aTnHs
INFO[0000] Fetching video info...
panic: regexp: Compile(`yt.setConfig('PLAYER_CONFIG', (.*?)</script>`): error parsing regexp: missing closing ): `yt.setConfig('PLAYER_CONFIG', (.*?)</script>`
den@febf7f699c38:tmp$ ytdl -KGfp2aTnHs
Incorrect Usage.
den@febf7f699c38:tmp$ ytdl -- -KGfp2aTnHs
INFO[0000] Fetching video info...
panic: regexp: Compile(`yt.setConfig('PLAYER_CONFIG', (.*?)</script>`): error parsing regexp: missing closing ): `yt.setConfig('PLAYER_CONFIG', (.*?)</script>`
Please don't judge me for my choice of an example video! :D
I'm getting files with appropriate titles but zero bytes.
No errors.
I tried go get -u
to no avail.
Not sure what's not working.
Thanks
As per title. Currently there is no way to differentiate between Format
s by frames-per-second.
YouTube supports 60fps video now, so it would be nice if the Format
struct reflected that.
Bonus points for making the best
format selector opt for higher-framerate, rather than only higher-resolution.
Would it be possible to bypass age-restricted videos, or for that matter, country-restricted videos?
{"level":"debug","time":"2019-12-19T12:06:49+07:00","message":"Fetching https://www.youtube.com/watch?v=TDgn8k9uyW4"}
{"level":"debug","time":"2019-12-19T12:06:50+07:00","message":"No formats found"}
Hello, I am using you lib in a music bot and today appeared an error at getting the url:
"Error parsing signature tokens".
Also I test the ytdl client and have the same error:
Example: ./ytdl -u https://www.youtube.com/watch?v=8TTTcVHNvrc
"Unable to get download url: Error parsing signature tokens"
Did youtube change something?
Thanks.
The ytdl library appears to log to the global zerolog logger, which writes directly to stderr. I don't use zerolog (or any global logger), so the messages that appear interfere with my normal structured logging. For example:
irc_1 | 2019-12-28T01:16:21.238Z DEBUG birc/connecton.go:305 sent {"subconnID": 1, "xid": "bo3app8k2nhpek5284f0", "m": "PRIVMSG #zikaeroh :[HB] YouTube link parsing is now enabled."}
bot_1 | 2019-12-28T01:16:21.243Z DEBUG bot/handle.go:66 handled message {"xid": "bo3app8k2nhpek5284f0", "irc_command": "PRIVMSG", "took": "11.31543ms"}
bot_1 | 2019-12-28T01:16:21.439Z DEBUG bot/handle.go:66 handled message {"xid": "bo3app8k2nhpek5284g0", "irc_command": "USERSTATE", "took": "502.141µs"}
bot_1 | {"level":"debug","time":"2019-12-28T01:16:36Z","message":"Fetching https://www.youtube.com/watch?v=WjNssEVlB6M"}
irc_1 | 2019-12-28T01:16:37.270Z DEBUG birc/connecton.go:305 sent {"subconnID": 1, "xid": "bo3apt0k2nhpek5284h0", "m": "PRIVMSG #zikaeroh :[HB] Linked YouTube video: \"Jamie xx - Gosh (Official Music Video)\""}
bot_1 | 2019-12-28T01:16:37.276Z DEBUG bot/handle.go:66 handled message {"xid": "bo3apt0k2nhpek5284h0", "irc_command": "PRIVMSG", "took": "998.170646ms"}
Can the use of a global logger be removed? Perhaps, convert this package to have a client struct with methods and some logger field that can be set for use in cmd/ytdl
? net/http
has global functions, which really just work on some http.Client
global var. I'd think you could maintain backwards compatibility by doing something similar.
$ ytdl txtxdwE5woA
INFO[0000] Fetching video info...
FATA[0000] Unable to fetch video info: Unable to extract signature tokens:
Get http:///yts/jsbin/player-it_IT-vfl7gxQ_f/base.js: http: no Host in request URL
Running into this error on some YT downloads, any idea what it could be? https://github.com/rylio/ytdl/blob/master/video_info.go#L194
I'll find some example videos, but thought you might know if you've run into it.
In cmd/ytdl/main.go:39
, app.Version should be "0.4.0"
instead of "0.3.1"
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.