
Show HN: Interactively select the quality and format for youtube-dl - synox
https://github.com/synox/youtube-dl-interactive
======
synox
PS: I coded this in an evening. This proves for me that nodejs makes it so
easy to make beautiful CLI apps. It is simple and makes may life easier.

See more node cli tools at: [https://github.com/sindresorhus/awesome-
nodejs#command-line-...](https://github.com/sindresorhus/awesome-
nodejs#command-line-utilities)

~~~
nextlevelwizard
Just few questions checking the repo.

Why are you using meow? It seems like you are just using it to grab args and
print help. Does it do something that is not immediately apparent? It has a
lot of dependencies that might be completely useless for you.

log-symbols seems also completely useless dependency, you could just add the
two symbols you are using by hand. Is it doing something special?

As for nodejs making things easier. Maybe it's just what you are used to.
There isn't much code here, but I'm guessing node_modules is going to be
pretty large. I think you could make this work just as well using any
language. I guess the bonus here is that this is portable (compared to
implementing with bash), but since youtube-dl (as far as I know) is made with
Python, maybe it would have been better to make this TUI using Python as well
since at least the user will have it installed.

~~~
Mister_Snuggles
On a side-note, can you recommend any good TUI libraries for Python?

I've got a mini project that a decent TUI would potentially work very well
for.

~~~
nextlevelwizard
Sorry, I don't have any ready recommendations up my sleeve. Pretty much only
CLI library I use is argparse.

------
pdkl95
I recently wrote[1] a track-selector front end script for youtube-dl that uses
yad[2] as a simple GUI[3]. It's not finished (it needs better error handling
anbd the gui layout is kind of ugly), but it mostly works.

[1]
[https://gist.github.com/pdkl95/0f963eae3612ecb104f233ca9eed4...](https://gist.github.com/pdkl95/0f963eae3612ecb104f233ca9eed435d)

[2] [https://github.com/v1cont/yad](https://github.com/v1cont/yad) (yad is
similar to zenity/{g,}dialog)

[3] [https://i.imgur.com/B5uf0PB.png](https://i.imgur.com/B5uf0PB.png)

------
soulofmischief
I just uploaded a batch script I use almost daily to grab music videos, live
videos, sessions, etc. if anyone finds it useful:
[https://github.com/soulofmischief/Batch-
Utilities/blob/maste...](https://github.com/soulofmischief/Batch-
Utilities/blob/master/src/dl.bat)

It automatically places videos in the configured folder based on type. Just
type in an artist name, and select the type of video. Saves me a ton of time.

It's easy to extend and I plan to generalize it and translate it to bash
sometime soon. I just do all of my media consumption in Windows currently.

------
loeg
It's impressive how little code is needed with 7 npm dependencies for a little
CLI program.

------
paol
I just have an alias with the format codes I want in order of preference
(youtube-dl allows that)

That's a very nice interactive ui though

~~~
StavrosK
Can you post the alias?

~~~
aepiepaey
It's well-documented in youtube-dl's readme: [https://github.com/ytdl-
org/youtube-dl#format-selection](https://github.com/ytdl-org/youtube-
dl#format-selection)

It has examples as well: [https://github.com/ytdl-org/youtube-dl#format-
selection-exam...](https://github.com/ytdl-org/youtube-dl#format-selection-
examples)

~~~
StavrosK
Oh nice, thank you, I never saw the examples page.

------
mixmastamyk
Cool, here's my simple script to select format called vdl, and can be
extended:

    
    
        #!/bin/bash
        OPTS="-o %(title)s.%(ext)s --console-title --restrict-filenames"
    
        if [ "$#" -eq 2 ]; then
    
            if [ "$2" -eq "251" ]; then
                OPTS="$OPTS -x"
            fi
            echo youtube-dl $OPTS -f $2 $1
            youtube-dl $OPTS -f $2 $1
    
        else
            echo youtube-dl -F $*
            youtube-dl -F $*
    
            echo
            echo -n "Enter number: "
            read fmt
    
            youtube-dl $OPTS -f $fmt $*
        fi
    

To explain, if you know the format number off the top of your head you can
pass it after the video id, otherwise it will prompt. Might upgrade it one day
to use "set -x" instead of echo and exec.

~~~
JetSpiegel
\- Quote "$2" and "$1" \- Use "$@" instead of $* \- Use: OPTS=(-o
"%(title)s.%(ext)s" \--console-title --restrict-filenames)

    
    
        "${OPTS[@]}"
    

This is what shellcheck reports.

~~~
mixmastamyk
Cool, love those kind of tools.

However, the youtube (and other sites id) and the format number will never
contain spaces, so quoting isn't really needed here. If it gives peace of
mind, sure.

------
acassara
Looooooove this package! Use `youtube-dl` regularly and always forget the
params. It's a nightmare.

Opened a PR to remove Lodash, emojis welcomed:
[https://github.com/synox/youtube-dl-
interactive/pull/3](https://github.com/synox/youtube-dl-interactive/pull/3)

------
z92
I always download with "-f 18".

------
peter_retief
FYI it works with Debian Buster, interesting switches I didn't know

------
Rolpa
'Because remembering CLI flags is hard.'

Indeed. :)

------
modzu
i don't know either project but on the surface doesn't this seem like it would
be a welcome PR?

~~~
monsieurbanana
I'm generally against adding interactive features to CLI programs if there
isn't a good reason for that. I don't want to remember which options I
can/can't use in a non-interactive script.

Plus youtube-dl already has multiple GUI/wrappers, so there's already a
separation for interactive features.

------
exabrial
Youtube-dl is one those things I wish could stay under the radar.

~~~
xwdv
Don’t see why, if anything more people should know about it so shared content
can become more redundant as people download it across the world. YouTube is a
fairly brittle hub sometimes with all the takedowns.

~~~
Wowfunhappy
I suspect the GP is concerned Youtube will take steps to block it.

This scares me a bit too, I watch basically all Youtube content via Youtube-
dl. I have a script that runs every night on Mac, so that new content
automagically appears in my Movies folder.

~~~
sadris
They do block it. Which is why it doesn't work if you install from your OS
repo. You need to get it directly from GitHub.

~~~
koolba
And you need to update it every now and then as the game of cat and mouse
plays on.

~~~
miaosqueeker
Glad you welcomed him to the real world. With things as they are now. I will
let you continue to teach him.

------
founderling
Jesus .. the package.json alone is probably longer then a shellscript would be
that implements the same functionality.

~~~
synox
I would love to see the shellscript equivalent! :))

~~~
natch
For videos, this should work... added to your .bashrc file, which then needs
to be reloaded (only once) by typing source .bashrc in your home directory
from the command line:

    
    
        alias yt='youtube-dl --recode-video mp4'
    

On my system I have a funky python setup so I need to use this instead:

    
    
        alias yt='unset PYTHONPATH; youtube-dl --recode-video mp4'
    

I don't see the need for interactivity because the only format I ever want is
mp4.

For audio, I would just do a separate alias with a different name. For example
(edit: tested):

    
    
        alias yta='youtube-dl --extract-audio --audio-format mp3'
    

Invoke each with the URL. For example:

Video:

    
    
        yt https://www.youtube.com/watch?v=IFe9wiDfb0E
    

Audio:

    
    
        yta https://www.youtube.com/watch?v=qKS8KsTC4IU
    

If a youtube URL has extra parameters separated by &, delete those before
invoking. For example the URL below, which has extra parameters because it
came from a playlist:

    
    
        https://www.youtube.com/watch?v=7uQuX1sOYk4&list=PLYq_mcte9NvDA2Xi5Qjl1DrH5LuDKDlAI
    

should be changed to this before using it to attempt a download:

    
    
        https://www.youtube.com/watch?v=7uQuX1sOYk4
    

Or you can use the full original URL but you need to protect it from
interpretation by UNIX by surrounding it with single quotes when invoking.

    
    
        yta 'https://www.youtube.com/watch?v=7uQuX1sOYk4&list=PLYq_mcte9NvDA2Xi5Qjl1DrH5LuDKDlAI'

~~~
why-oh-why
> I don't see the need for interactivity because the only format I ever want
> is mp4.

Then this tool isn't for you. If you're gonna skip the whole point of the
tool, you can't claim your code suggestions are equivalent.

~~~
natch
True! I should have made it more clear my examples weren't providing
interactivity, I guess you're saying. OK.

------
howiroll
380 dependencies for like 30 lines of bash script.

Javascript became the cancer of the Internet.

------
klntsky
This is too trivial to share, IMO.

Anyway, shell is more suitable for this kind of programs: you could write a
bash script that ties together youtube-dl and dmenu or fzf or whatever within
an hour.

~~~
onion2k
_This is too trivial to share, IMO._

How do you define complexity threshold for something being worth sharing?

More to the point, _why_ do you define that threshold? What benefit is there
to saying someone's work that they're sharing has to be sufficiently
complicated? Simple things can be immensely useful and well worth sharing.

------
w56rjrtyu6ru
People gotta realize that Node.js is actually excellent for this sort of task.
It hits quite a few sweet spots as an all-round Unix scripting language:

* Familiar syntax and semantics (Bash/Zsh/Fish/Csh/Ksh/Ash/Wtfsh are all way weirder than JS - and they are _only_ scripting languages, while JS is already everywhere)

* Standard library ([https://nodejs.org/dist/latest-v12.x/docs/api/fs.html](https://nodejs.org/dist/latest-v12.x/docs/api/fs.html)) gives you access to POSIX APIs ("batteries included" \- but not bloated)

* Sane packaging, package management, and ecosystem (overreliance on third-party module is a thing _exactly_ because NPM works with much less friction than e.g. the Python situation)

* Asynchronous event model lets you safely do multiple things in parallel without worrying about low-level memory management, or which concurrency boilerplate library to use, etc.

All in all, it's the perfect Unix glue. All it misses is a mature
S-expression-based syntax.

For example, take the problem of locking your encrypted partitions before
suspending your Linux machine. Since distro developers are too "busy" to
provide what one might say is basic functionality, power users took matters in
their own hands and wrote this 100-ish line Bash script
([https://github.com/vianney/arch-luks-
suspend](https://github.com/vianney/arch-luks-suspend)), which evolved into
this 1500-ish line Go monstrosity ([https://github.com/guns/go-luks-
suspend](https://github.com/guns/go-luks-suspend))... as well as these ~75
lines of Node.js ([https://github.com/egasimus/node-luks-
suspend](https://github.com/egasimus/node-luks-suspend)).

But yeah, sure, hurr durr JaavaaScriipt baad, 0.1+0.2!==0.3, 'true'==true,
etc... The horror!

~~~
chaosite
Look, I'm generally with you, there isn't anything particularly bad about
modern JavaSscript, and it's a perfectly fine language to write your tools in
if that's what you like.

But your points are... Weird.

1\. Familiar to people who know JavaScript, sure. But shell is the language
you interact with the CLI with, so more people who use the CLI are familiar
with a shell.

2\. Most languages have a standard library.

3\. I know many people who would disagree with you. Anyway, pip works fine in
a Unix environment, which is what we're discussing here.

4\. We're talking about glue code, right? Glue doesn't tend to be very
parallel.

5\. So, perfect Unix glue? Sure, you like it, and that's great for you! Keep
on doing you. It's obviously capable of making nice tools, but so are most
languages...

6\. You luks-suspend example is weird because the Node.js code obviously does
so much less than the other versions. I have no idea what the Go version is
doing, but the shell version does things like remount the filesystem, handle
udev, etc... A bash version of the JavaScript code would be shorter!

7\. 0.1+0.2!=0.3 is a result of floating point arithmetic being floating point
arithmetic. It's not specific to JavaScript.

~~~
w56rjrtyu6ru
1\. Most people who interact with a shell know how to make it run one command
with arguments; some eventually learn about IO redirection. Many such people
who use Bash as a "command prompt" would find the way it does even simple
things like variables and conditionals exceedingly arcane. Readability is
important, and, for better or worse, a compact curly bracket syntax is seen as
"the norm".

2\. Different languages' standard libraries have different scopes. Node's is
just right for the task at hand.

3\. I know many people who disagree with me, too. That doesn't make me wrong
(or right ;-)).

4\. Why not? Doing a task and displaying a rich progress indicator is doing
two tasks. Glue is a continuum - for me, the concept includes orchestration of
external "heavy lifting" tasks according to the desired logic, as well as
processing intermediary outputs in simple ways so the whole pipeline fits
together.

5\. Well, I've evaluated it and found it to my liking. I guess you grow to
like the tools you use to accomplish things, and if everyone who went out of
their way to publicly dismiss Node.js instead went out of their way to use it
in place of Bash scripting, they might find it to their liking as well.

6\. Yet ironically, it has been the most reliable in achieving its purpose of
locking my encrypted partitions when my computer goes to sleep, not to mention
unlocking them when I wake it up.

7\. Exactly - but people keep pulling this and other quirks out of their ass
as "proof" JavaScript is some horrible language. Show me a shell scripting
language that even has floating point arithmetic! But maybe glue code can't
ever need that, either?

~~~
hnlmorg
> _Readability is important, and, for better or worse, a compact curly bracket
> syntax is seen as "the norm"._

Python seems pretty popular.

> _I know many people who disagree with me, too. That doesn 't make me wrong_

The problem isn't that you're saying node is well suited. The problem was your
suggestion that node was _uniquely_ well suited when actually the CLI is a
solved problem in most languages.

> _Well, I 've evaluated it and found it to my liking._

That's all that really matters when it comes to your own personal usage. Just
don't expect everyone to have those same preferences nor argue with other
developers that your preferences are any kind of "fact".

> _I guess you grow to like the tools you use to accomplish things, and if
> everyone who went out of their way to publicly dismiss Node.js instead went
> out of their way to use it in place of Bash scripting, they might find it to
> their liking as well._

Personally I don't like node and find Bash easier however it's thankfully not
an "either/or" argument where your only options are Javascript or Bash.
There's a whole plethora of options out there.

> _Yet ironically, it has been the most reliable in achieving its purpose of
> locking my encrypted partitions when my computer goes to sleep, not to
> mention unlocking them when I wake it up._

That's a pretty meaningless anecdote because it could be the result of a whole
plethora of reasons outside of the language's control (including but not
limited to user error) or even completely made up (like your point about
floating point arithmetic (see below) or your other comment about one liners
being more readable than multi-lined code).

> _Show me a shell scripting language that even has floating point
> arithmetic!_

Quite a few do: ksh93, yash, zsh and murex (disclaimer: I wrote that shell)
are all interactive shells which support floating point arithmetic.

In terms of shell scripting languages, you can add the following to the above
group: awk, bc, dc and perl.

Even those shells that don't support floating point arithmetic can still do
pseudo floating point maths by using powers of 10 multipliers and printf to
place the decimal point:

    
    
        printf %.10f\\n "$((1000000000 * 365/7))e-9"
    

Ok, I'll grant you that is rather ugly. Thankfully you can call other shell
scripting languages from within your POSIX/C shell:

    
    
        bc <<< "scale=10; 365/7"
    

This isn't a hard thing to research either; which suggests to me you haven't
done your homework before making your arguments.

~~~
w56rjrtyu6ru
> Python seems pretty popular.

One reason it's so popular: even though it skips the actual curly brackets
(thus making itself more accessible), it doesn't stray too far from the
general syntactic paradigm of "curly-bracket languages'" \- even though I've
also seen people being alienated by the idea of "significant whitespace",
again for no other reason but that it "seems wrong" to them.

> The problem was your suggestion that node was uniquely well suited

No, just _much better suited than people give it credit for_. And this
ecosystem brings new things to the table, too.

> when actually the CLI is a solved problem in most languages.

Being able to build a CLI at all? I guess, sure. Being able to quickly build
an accessible CLI? Hardly so. Everything in the area of HCI is in flux, and
gatekeeping the CLI domain for does more harm than good. Btw do you know
anyone doing this sort of interface before Yeoman?
[https://github.com/synox/youtube-dl-
interactive/raw/master/d...](https://github.com/synox/youtube-dl-
interactive/raw/master/d..). before JS.

> There's a whole plethora of options out there.

Which is why you've got to take into account opportunity cost, choice
paralysis, etc. All of the options out there are positively fascinating, but
if I have the options to solve problems in multiple contexts with the same
familiar tool, I tend to usually go for it.

> Quite a few do: ksh93, yash, zsh and murex (disclaimer: I wrote that shell)
> are all interactive shells which support floating point arithmetic.

None of which are POSIX, or common defaults?

> In terms of shell scripting languages, you can add the following to the
> above group: awk, bc, dc

None of which are shells - they're DSLs you can call into from the shell.

> perl

Again, not really a shell. Though I wouldn't be surprised if anyone's using it
as one.

> bc <<< "scale=10; 365/7" > 365/7

Even though these tools have a good reason to be like this, having to
_research_ how to _call out to an external executable_ to do something as
trivial as floating point division (in the sense of "cmon man I can do this in
my head, why does is it have to be so hard to tell a computer to do it") is
hardly on anyone's list of priorities.

At this point, nearly anyone would rather reach for the scripting language
they're already familiar with, rather than learn an unfamiliar one just
because it has historically dominated the problem domain.

> one liners being more readable than multi-lined code

Admittedly, that was a pretty bullshit argument. Not any less nuanced than
"[l]ine counts mean jack shit", either - I take it as a general rule that one
would prefer to write less code.

And I'm not weighing any of the examples against "[c]ode golfing, minifified
code, shell 1 liners, Perl, etc. I didn't really take into account the extra
functionality of the Go version - it was just as unreliable as the Bash one so
I quickly discarded it when I found something that worked.

There's a story behind this comparison. It was likely user error, in the sense
I failed to prepare my initramfs correctly using mkinitcpio or dracut
(incidentally, both of those being shell scripts - insufficiently documented
and not very readable to my untrained eye, either) But the JavaScript version
worked for me because it didn't even try to chroot into the initramfs - it
just moves a tiny handful of required binaries into a ramdisk, and works from
that.

Since that solution _works_, I am hard pressed not to commend its minimalism.
Is it inconceivable that that the author was not more clever, but the tools
that they used enabled them to come up with a simpler solution in the time
that would've otherwise been spent googling `bc` or poring over the sources of
initramfs builders?

~~~
hnlmorg
> _One reason it 's so popular: even though it skips the actual curly brackets
> (thus making itself more accessible), it doesn't stray too far from the
> general syntactic paradigm of "curly-bracket languages'" \- even though I've
> also seen people being alienated by the idea of "significant whitespace",
> again for no other reason but that it "seems wrong" to them._

All you're describing there is structured programming languages. Of course
people like structured languages, that's why nearly every single programming
language developed in the last 40 years (that isn't designed to interface
directly with hardware) is structured. Even languages of entirely different
paradigms such as Common Lisp, LOGO, Prolog, MATLAB and Forth all support
structured control flows. Even BASIC - for all it's warts - supported
structured logic (even if many implementations lacked proper functions).

So you're not making a convincing argument about curly braces now you've
redefined the argument as structured control flows.

> _No, just much better suited than people give it credit for. And this
> ecosystem brings new things to the table, too._

Maybe. My personal opinion is the unmanageable nest of unvetted dependencies
makes it a worse solution than people give it credit for. As a pure dev tool
for personal use, go for it. But I don't want to read 10k+ lines of code in
the dependencies of a tool that's ostensibly just an interactive alias.

I get the whole "standing on the shoulders of giants" thing but it's gotten
out of hand with node. Half the time even people writing code in node don't
know what dependencies their dependencies are pulling in. All that trust
placed in an ecosystem that is very easy to abuse (and has been abused too).
So no thanks, I don't think that's the right tool for serious CLI work which
often needs to be run on trusted machines.

> _Being able to build a CLI at all? I guess, sure. Being able to quickly
> build an accessible CLI? Hardly so._

Actually yes. I've been writing software for 30 year in well over a dozen
different languages. Much, not all but a reasonable amount of that, was
writing software for servers.

> _Everything in the area of HCI is in flux_

Not in terms of the CLI. We're using the same standards that were defined in
the 60s. If anything, the problem with the CLI is that it's engineered around
design principles which are no longer relevant to modern terminals. For
example:

    
    
      * we no longer need to inline formatting with escape sequences - we have better markups for that.
      * ASCII is no longer relevant in our international community with different writing languages and character sets.
      * Terminals are no longer teletypes - there's no reason why we shouldn't be able to inline multimedia content
      * Terminals are no longer teletypes - we shouldn't need to be defining TTYs/PTYs as an OS abstraction
      * Defining TTYs is OS specific and a fucking mess on even some of the better designed UNIXes
      * Capturing and sending signals can often be OS specific and a fucking mess to work with on even some of the better designed UNIXes
      * Not all OSs even support the same suite of signals
      * Signal hotkeys can't even be redefined - which means you can't always compensate for one OS missing a signal that another might have. The best you can do is enable or disable the capture of that hotkey on the TTY. Which again requires OS specific syscalls
      * POSIX pipes are just byte streams. Which makes working with structured data a fucking nightmare (hence why Powershell, jq and murex all exist)
      * stderr is a lousy way of capturing errors
      * in fact error handling on the whole is just terrible on POSIX shells (hence why murex exists)
      * POSIX shells don't support any kind of unit testing (again, hence why murex exists)
      * exit numbers are a half arsed solution
      * named pipes are a file system kludge
      * TTY modes can get broken if a fork()ed process changes the mode and crashes for forgets to reset it on exit. Meaning your shell then becomes non-functional without manually fork()ing `reset`
      * ANSI escape sequences are anything but standardised. With different terminal emulators often doing significantly different things
    

This is all just off the top of my head so I could likely think of more if I
spent any time thinking about it. All of those problems are a result of the
command line interface being largely the exact same design as it was in the
60s.

So no, the CLI definitely is not in a state of flux. The exact opposite of
that in fact.

More likely is the Javascript libraries you're using for CLI work is in a
constant state of flux. This was a problem I had when I used to write software
in node and it's one of many personal reasons I decided against using it for
anything I really cared about.

> _Which is why you 've got to take into account opportunity cost, choice
> paralysis, etc. All of the options out there are positively fascinating, but
> if I have the options to solve problems in multiple contexts with the same
> familiar tool, I tend to usually go for it._

That makes no sense. Last week you were saying it couldn't be done and now
you're saying the problem is too much choice. Make your mind up.

> _[ksh93, yash, zsh and murex] None of which are POSIX, or common defaults?_

You didn't say "POSIX shells", you said "shell scripting languages"

Also node isn't a common default either.

> _[Perl] Again, not really a shell. Though I wouldn 't be surprised if
> anyone's using it as one._

Again you didn't say "POSIX shells", you said "shell scripting languages". You
can very much use Perl as a shell scripting language (and that is in fact
still a common use case for it).

> _Even though these tools have a good reason to be like this, having to
> _research_ how to _call out to an external executable_ to do something as
> trivial as floating point division (in the sense of "cmon man I can do this
> in my head, why does is it have to be so hard to tell a computer to do it")
> is hardly on anyone's list of priorities._

Actually computers can't do proper floating point arithmetic (in the sense
that humans do) either. That's why a lot of languages (and spreadsheets too)
demonstrate seemingly broken logic when comparing floating point numbers.

> _Admittedly, that was a pretty bullshit argument. Not any less nuanced than
> "[l]ine counts mean jack shit", either - I take it as a general rule that
> one would prefer to write less code._

Line counts literally do mean jack shit. There are plenty of examples of where
more lines equal better code. As a developer you should already know this.

------
cm-t
please, need a snap to install it!

------
chapium
Remembering flags is hard? Are shell scripts no longer a thing?

~~~
onion2k
Remembering flags _is_ hard, yes. If you use a lot of different apps
remembering the flags for something you use infrequently is a pain. I don't
think I've _ever_ used ffmpeg without looking at the docs first.

As for shell scripts, they are a thing, and this thing is one (just written in
node rather than bash.)

~~~
mixmastamyk
It's not that bad. Captain Obvious example:

    
    
      command -h  # or --help
    

For ffmpeg (and other huge cli) I use my shell history, man page, and Super
User site. Then edit the params.

