How to extract video URLs from YouTube

I know there are many tools out there that allow you to download videos from YouTube, like the Video Download Helper for Firefox, even online tools that convert the audio to mp3. The reasons I’m writing this article are a) because sometimes you just need the URL, for example to watch a video with a much less ressource consuming player like VLC or ffplay, b) because sometimes you just want to listen to the audio and save up even more ressources by not decoding the video and c) because I can 😉

The method I will introduce involves some filtering and editing operations on the source code of the according YouTube video page, so it might not work as soon as YouTube changes the structure of their video pages. Nevertheless it explains the basic steps to be taken to get to the actual video URLs. I will also make use of ffprobe, a part of the ffmpeg distibution, to obtain information about the video, e.g. audio and video resolution, bitrate etc.

The following code block contains a bash script that extracts all video URLs from a YouTube video page and outputs them to standard output. You can copy the code and paste it into your favourite editor. Save the file as “youtubeurlextractor”, make it executable and put it somewhere in your $PATH.


# Backup field separator

# obtain parameters for construction of video URLs
# get Youtube page source code
#    wget -q -O - "$1"
# find parameter containing video URLs
#    grep "videoplayback"
# replace ", " with newline so we can find encoded URLs
#    sed 's/","/"\n"/g'
# find encoded URLs
#    grep "url_encoded_fmt_stream_map"
# cut off parameter name, e.g. "url_encoded_fmt_stream_map"
# remove "
# replace "," with newline so we can filter for parameters
# replace unicode character \u0026 with newline to separate parameters
#    sed 's/\".*\"://g; s/\"//g; s/,/\n/g; s/\\u0026/\n/g'
# filter for parameters of interest
#    grep -E "quality|url|sig|s="
# decode html encoded characters
#    echo -e $(sed 's/%/\\x/g')
# separate parameters of interest
# prepare "sig" parameter for video URL
#    sed 's/ /\n/g'
#    sed 's/^s\=/\&signature\=/g'
videos=($(wget -q -O - "$1" |\
          grep "videoplayback" |\
          sed 's/","/"\n"/g' |\ 
          grep "url_encoded_fmt_stream_map" |\
          sed 's/\".*\"://g; s/\"//g; s/,/\n/g; s/\\u0026/\n/g' |\
          grep -E "quality|url|sig|s=" |\
          echo -e $(sed 's/%/\\x/g') |\
          sed 's/ /\n/g' | sed 's/^s\=/\&signature\=/g'));

# variables to store parameters

# sort parameters
for i in ${videos[@]}; do
	if [ "${i:0:3}" == "qua" ]; then
		quali=("${quali[@]}" "$i");
	elif [ "${i:0:3}" == "url" ]; then
		urls=("${urls[@]}" "$i");
	elif [ "${i:0:3}" == "&si" ]; then
		sigs=("${sigs[@]}" "$i");

# construct video URL and output information
for (( i=0; i<${#urls[@]}; i++ )); do	 	 
	# video index	 	 
	echo "Video $i";	 	 
	echo "=======";	 	 

	# video quality	 	 
	echo "${quali[$i]}" | sed 's/=/: /g';	 	 

	# video URL	 	 

	# if ffprobe is installed, show video and audio stream information	 	 
	if [ ! -z $(which ffprobe 2>/dev/null) ]; then
		streams=($(ffprobe "$url" 2>&1 | grep -i stream));
		for s in ${streams[@]}; do
			echo ${s#*: };
	# print video URL
	echo "url: \"$url\"";

# restore field separator

You can call the script with the URL of the YouTube video page, e.g.
$ youtubeurlextractor ""

The output should look something like this:
Video 0
quality: hd720
Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720, 942 kb/s, 29.97 fps, 29.97 tbr, 60k tbn, 59.94 tbc
Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, s16, 191 kb/s
url: ""

Video 1
quality: medium
Video: vp8, yuv420p, 640x360, SAR 1:1 DAR 16:9, 1k fps, 1k tbr, 1k tbn, 1k tbc (default)
Audio: vorbis, 44100 Hz, stereo, s16 (default)
url: ""

Video 2
quality: medium
Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 640x360, 245 kb/s, 29.97 fps, 29.97 tbr, 60k tbn, 59.94 tbc
Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, s16, 95 kb/s
url: ""

Video 3
quality: small
Video: flv1, yuv420p, 426x240, 144 kb/s, 29.97 tbr, 1k tbn, 1k tbc
Audio: mp3, 22050 Hz, stereo, s16, 64 kb/s
url: ""

Video 4
quality: small
Video: mpeg4 (Simple Profile) (mp4v / 0x7634706D), yuv420p, 320x180 [SAR 1:1 DAR 16:9], 169 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 30k tbc
Audio: aac (mp4a / 0x6134706D), 22050 Hz, mono, s16, 31 kb/s
url: ""

Video 5
quality: small
Video: mpeg4 (Simple Profile) (mp4v / 0x7634706D), yuv420p, 176x144 [SAR 1:1 DAR 11:9], 16 kb/s, 12 fps, 12 tbr, 12 tbn, 12 tbc
Audio: aac (mp4a / 0x6134706D), 22050 Hz, mono, s16, 23 kb/s
url: ""

Now you can copy the URL of the video with the desired quality and paste it to VLC, ffplay, mplayer or whatever media player you like that can play files via http. If you want to save the video to your harddrive, simply use wget to download it. If you want to save only the audio part you can use ffmpeg with ffmpeg -i <url> -vn -c:a copy <some_audio.m4a>

About h0nk3ym0nk3y

Yeah, whatever, never mind

Posted on October 30, 2013, in Audio / Video, Bash-Scripts, Command-Line and tagged , , , , , , , , , . Bookmark the permalink. 18 Comments.

  1. /usr/bin/youtubeurlextractor: line 37: : command not found

    • Forgot to mention that I did exactly everything as you said, the script is executable and supplied youtube video url and this is the output of the script.

      • Hi PuTTy,

        it sounds like you are missing one of the tools invoked in the script. Make sure you have wget, sed, echo and grep installed. If you want to get additional information about the video and audio stream from the YouTube video, you also need ffprobe as part of the FFmpeg distribution. Also I would recommend you put the script in /usr/local/bin/ instead of /usr/bin/.

        Best regards

      • That’s odd. Can you run the piped commands bit by bit, eg. $ wget -q -O - "", then $ wget -q -O - "" | grep "videoplayback" and so on to find out which command is causing the problems?

      • It works once I get all of the commands on a single line, but trying to fetch the audio with ffmpeg fails –

      • You have to add the &signature=SomeSignature to the URL parameter and put the whole URL in double quotes, otherwise bash will interpret the & as concurrent execution command. That’s why you get all those [proc number] PID console outputs. Your FFmpeg call should look like this:
        $ ffmpeg -i "" -vn -c:a copy someAudio.m4a
        In some cases ffmpeg might not be able to stream the file from YouTube, which results in choppy audio playback or even a corrupted file. In that case you can download the file with wget and extract the audio afterwards directly from the downloaded file.
        Be aware that the audio stream in an mp4 file is most likely aac compressed audio and therefore needs the m4a or mp4 file ending. If you use mp3 as file ending, FFmpeg will transcode the audio to mp3, which results in additional compression and further quality loss.

      • Thank you it worked out.

  2. Hi – this looks great … but does it still work? (As in did YT change it’s format and hence this script is no longer valid.) I am getting a “blank” output from the script.

    I am on a Mac so had to make two changes (no wget, and problems with line continuations). So I am using the script as is except:
    (i) changed the first command from:
    wget -q -O – “$1”
    curl -s -O “$1”
    (ii) put all of the commands on that line onto one single line instead of using the \ line continuation operator (not sure why I had to do this but comment above did the same)


    • h0nk3ym0nk3y

      Hi Jim,

      thanks for the hint. I’ve updated the script so the parsing should work again.

      Best regards

  3. There seems to be a problem with the construct section:
    ./youtubeurl: Zeile 57: Syntaxfehler beim unerwarteten Wort »]«
    ./youtubeurl: Zeile 57: `for (( i=0; i/dev/null) ]; then’

    • Dear textlastig,

      I’m sorry, it was a problem with WordPress and HTML escape characters. I fixed it in the post.

      Best regards,

  4. Hi

    Is thre a new update? This one gives links but gets 403 forbidden. New urls look almost the same but having vudeo title added at the end

    Thank you

    • Hi Trio,

      I have tried several YouTube links and they all worked for me. Could you supply a link that gives you the 403 error so I can have a look at that?

      Best regards,

      • Hi airsoft,

        I have stumbled upon some YouTube video URLs that are forbidden to access. I suppose it has something to do with the signature variable in the URL. I haven’t had the time to dig more into it yet, but I will post an update as soon as I figured out what the problem is. In the meantime I guess you will have to look for other instances of the video and try those.

        Best regards,

  5. my website is:
    i m using video js player and i want to get video url like


    tell me any solution??


    • Hello Umair,

      when you take a closer look at the embed URL of the video on your site, you will see that your URL and the youtube URL are using the same video ID, in this case “HfLsXiXoONo”. So if you use the script with ./youtubeurlextractor “”, it will produce the output mentioned in the post and you can copy the desired video URL.

      This is the output I got from the script:

      I pasted the video URLs into VLC and they all play just fine.

      Hope this helps.

      Best regards,

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: