_\~ /\ |\| |) /? () |\/| /\ /= /= | () |) ()
/homepage /list +normal

Contact: yt tw fb in mail git

Tags: [all] obfuscated rubik arduino vgax terminal ebook epub esp8266 espvgax game javascript php scifi ioccc piano music book youtube curl

YouTube from Terminal (Part 1)

Sometimes a NERD watch Youtube without a browser opened. NERDS use text browsers like LYNX or W3M :-D

In the past years i've tryed mps-youtube and youtube-viewer, both are terminal apps that allow you to search, view and download videos from Youtube, but this time i want something more customizable, also based on youtube-dl.

Solution 1: play video from URL

You need only these two tools: youtube-dl and mpv. I think that these are the same tools used by mps-youtube. This solution is quick and dirty.

Installation on Mac (via brew) is easy:

brew install youtube-dl mpv

On Linux, Debian based distros, you can use apt:

apt-get install youtube-dl mpv

After that you can open your video with this command (replace VIDEO_URL with your Youtube video URL):

mpv $(youtube-dl -g -f 18 VIDEO_URL)

The magic number 18 is to select MP4 360p videos. If you want to select others format you can choose from one of these:

171 webm audio only vorbis
140 m4a audio only mp4a
133 mp4 426x240 avc1 video only
134 mp4 640x360 avc1 video only
135 mp4 854x480 avc1 video only
247 webm 1280x720 vp9 video only
136 mp4 1280x720 avc1 video only
248 webm 1920x1080 vp9 video only
137 mp4 1920x1080 avc1 video only
43 webm 640x360 vp8 + vorbis
18 mp4 640x360 avc1 + mp4a
22 mp4 1280x720 avc1 + mp4a

If you want to be lazy in typing commands (like a real NERD needs to be), you can add this function to your .bashrc (or .bash_profile if you use Mac OS X) and use have this solution ready anytime you need to watch videos from terminal:

function yt {
    mpv $(youtube-dl -g -f 18 $1)   

To use this function you only need only to type


Download videos

If you want to download videos, instead of playing them, you only need to replace mpv with curl:

function dyt {
    curl $(youtube-dl -g -f 18 $1) -o video.mp4

Picture in Picture alike

When i work on my computer i like to have the video that i am watching on one corner of the screen, possibly on top of the others windows (this mode is normally called PIP: picture in picture). With mpv you can use two parameters to configure the position of the window and the stay-on-top mode:

mpv --ontop --geometry=WIDTHxHEIGHT+X+Y

Add these parameters to your scripts to have mpv play like a PIP!

Experiment without youtube-dl (little more complex)

You don't like to use existent tools. You are a NERD and you like to do everything with a bunch of curl, grep and sed commands. Supposing that you do not wont to rewrite curl or mpv (you dont?), you can use curl to extract the required video URL and play that with mpv:

function ytc {
    mpv $(echo -ne $(curl $1 | grep -o 'https[^\"]*' | grep videoplayback | grep itag%3D18 | sed -E "s/%/\\\\x/g"))

This is it. HTML scraping: the worst thing you should do, EVER. Let's break each command apart:

curl $1 | grep -o 'https[^\"]*'

curl youtube page and extract all HTTPS links contained in the page. If you look at the HTML page returned from Youtube, you will see that inside HTML there is a big JSON string that contains all HTTPS URLs for the final video playback. These links contains the videoplayback substring. see screenshot-1

grep videoplayback

select only lines that contains videoplayback substring

grep itag%3D18

select only lines with itag=18 (my preferred format is 18, you can choose others format from the table above). %3D is the character = escaped inside the HTTP URL

sed -E "s/%/\\\\x/g"

convert each HTTP encoded characters from %NN to \xNN. This is the standard C/bash escape for characters expressed as hexadecimal two digit number

echo -ne

echo results converting all \xNN sequences to its ASCII equivalents. After that you obtain the final URL. Something like this: r11---sn-hpa7zn7r.googlevideo.com/videoplayback?initcwndbps=472500&sparams=clen%2Cdur%2Cei%2Cgir%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cnh%2Cpl%2Cratebypass%2Crequiressl%2Csource%2Cupn%2Cexpire&ip=


run mpv, finally

PLEASE NOTE that this solution do not work for all Youtube videos. Use youtube-dl instead, it works better and it is less insane.

Full code

#play Youtube video using youtube-dl
function yt {
    mpv --ontop --geometry=320x200+0+0 $(youtube-dl -g -f 18 $1)    
#download Youtube video using youtube-dl
function dyt {
    curl $(youtube-dl -g -f 18 $1) -o video.mp4
#play Youtube video without youtube-dl (do not work for all videos) 
function ytc {
    mpv $(echo -ne $(curl $1 | grep -o 'https[^\"]*' | grep videoplayback | grep itag%3D18 | sed -E "s/%/\\\\x/g"))
#download Youtube video without youtube-dl (do not work for all videos) 
function ytc {
    curl $(echo -ne $(curl $1 | grep -o 'https[^\"]*' | grep videoplayback | grep itag%3D18 | sed -E "s/%/\\\\x/g")) -o video.mp4

Have FUN (or use a normal, more easy, soft clickable, quite adorable WebBrowser like everyone do)