37

I wrote a program that gets youtube video URL and downloads it
Up today I did this:
1. get video "token" from "/get_video_info?video_id=ID" like:

http://www.youtube.com/get_video_info?video_id=jN0nWjvzeNc  

2. Download Video by requesting it from "/get_video?video_id=ID&t=TOKEN&fmt=FORMAT_ID" like:

http://www.youtube.com/get_video?video_id=jN0nWjvzeNc&t=vjVQa1PpcFMgAK0HB1VRbinpVOwm29eGugPh3fBi6Dg%3D&fmt=18  

But this doesn't work anymore!
What is the new download URL?

Thanks

Ariyan
  • 14,760
  • 31
  • 112
  • 175
  • I'm having this problem too, it seems like it doesn't affect mobile youtube, but I don't know what's the URL to download from mobile youtube. – Leg10n Jul 23 '10 at 06:42
  • You might want to check this API: https://weibomiaopai.com/download-video-parser.php – justyy Jan 30 '17 at 17:22
  • [urldecode](https://www.urldecoder.org/) the entire response from `get_video_info` and then look for the `url=https%3A%2F%2F...` keys and values. urldecode the values and pick one of these - the `type` key will tell you what kind of video it is. thanks to https://www.tyrrrz.me/Blog/Reverse-engineering-YouTube – mulllhausen Jul 31 '18 at 03:40

5 Answers5

15

Actually I'm working on the similar project that downloading the video file from youtube. I find that the get_video might be blocked by Youtube. so instead of using get_video., I use the video info retrieved from get_video_info and extract it to get the video file url.

Within the get_video_info, there are url_encoded_fmt_stream_map. After encoding it, you can find url and signature value of every video with different format. So the file url is like [url value]+'&signature='+[sig value].

Additionally I find the following topic that using same method with mine. Hope it can help you.

Can't Download from youtube

If you are interested about how to downloading youtube video file, there is a small program written by me to demonstrate the process. You are free to use it.

https://github.com/johnny0614/YoutubeVideoDownload

Community
  • 1
  • 1
yujohnnyzhou
  • 330
  • 3
  • 7
  • Your demo on github doesn't work anymore...? I was trying it with YoutubeVideoDownload.py [http://www.youtube.com/watch?v=U3VdT3HEzKE](http://www.youtube.com/watch?v=U3VdT3HEzKE) mp4 – hwhm Jul 30 '13 at 19:44
  • @yujohnnyzhou I've added an interactive download mode for selection of different video types along with a single line download progress bar instead of displaying it with multiple lines. Please see your github page. – Searock Aug 09 '13 at 21:13
  • Thanks for this - I just started using it, however it appears not to work for Vevo uploaded videos. – The Bearded Templar Jul 10 '14 at 18:16
  • @TheBeardedTemplar Can you give me a sample link ? So I can fix it. – yujohnnyzhou Jul 11 '14 at 02:23
  • 1
    @TheBeardedTemplar one more thing, I think this program works for vevo https://github.com/rg3/youtube-dl – yujohnnyzhou Jul 11 '14 at 02:33
  • @yujohnnyzhou Thanks! I didn't expect a reply on this. Here's a video that didn't work for me: https://www.youtube.com/watch?v=_DboMAghWcA – The Bearded Templar Jul 11 '14 at 04:54
  • 1
    @TheBeardedTemplar I've already found where the issue is. when the program retrieve the video_info file, it send request to get_video_info with parameter video_id=/*video_id*/ . however, it doesn't work for vevo video. You have to append another parameter el=vevo. So the request url will look like www.youtube.com/get_video_info?video_id=/*video_id*/&el=vevo . currently, it is the only way ( I found ) to retrieve vevo video info file. If you have any other ideas, please tell me. :) – yujohnnyzhou Jul 11 '14 at 05:01
  • Hmm, did you manage to get a video to download that way? I've found that appending "&el=vevo" works fine for getting the video info (and in fact for non-vevo videos the parameter is just ignored, so you can just append it in all cases). However, once I reach the downloader step I'm getting a 403 error on this line: `link=urllib2.urlopen(request) ` – The Bearded Templar Jul 14 '14 at 16:45
  • @TheBeardedTemplar , YES you are right ! this only can successfully retrieve video_info. but the info is lack of signature value. which is the reason that fail downloading the file. :( I am trying to find a way to resolve that problem. – yujohnnyzhou Jul 28 '14 at 00:30
11

Add &asv=2 to the end of the URL.

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
rossy
  • 134
  • 1
  • 2
  • Hi, Thank you very much, it works , But: I tried "asv=3" (as I fetched from reversed actionscript code of youtube player) but it didn't work! but your's works. thanks – Ariyan Jul 24 '10 at 13:16
  • &asv=2 was reverse engineered from the embed player. I have no idea why it works, but it works :D – rossy Jul 24 '10 at 14:43
  • by adding "asv=3" download link got generated because of copyrighted content. if you have copyrighted content then you must need to use "asv=3" . – Code Cooker May 06 '17 at 04:19
10

You can get the stream directly by using only

http://www.youtube.com/get_video_info?video_id=jN0nWjvzeNc

I made a little script to stream youtube videos in PHP. See how the script get the video file.

<?php 
@set_time_limit(0); 
$id = $_GET['id']; //The youtube video ID
$type = $_GET['type']; //the MIME type of the video

parse_str(file_get_contents('http://www.youtube.com/get_video_info?video_id='.$id),$info); 
$streams = explode(',',$info['url_encoded_fmt_stream_map']); 

foreach($streams as $stream){ 
    parse_str($stream,$real_stream); 
    $stype = $real_stream['type']; 
    if(strpos($real_stream['type'],';') !== false){ 
        $tmp = explode(';',$real_stream['type']); 
        $stype = $tmp[0]; 
        unset($tmp); 
    } 
    if($stype == $type && ($real_stream['quality'] == 'large' || $real_stream['quality'] == 'medium' || $real_stream['quality'] == 'small')){ 
        header('Content-type: '.$stype); 
        header('Transfer-encoding: chunked'); 
        @readfile($real_stream['url'].'&signature='.$real_stream['sig']); //Change here to do other things such as save the file to the filesystem etc.
        ob_flush(); 
        flush(); 
        break; 
    } 
}
?>

See the working demo here. I hope this can help you.

Licson
  • 2,231
  • 18
  • 26
  • @opengrid That's about my web host. I'll try another web host later. – Licson Jul 03 '13 at 22:57
  • The demo is working perfectly on my localhost.. thanks :) – Code Cooker May 06 '17 at 05:07
  • @Licson It's working perfectly on localhost. But when i'm trying to deploy it to server like shared hosting it's encoutering issue with Cipher encrypted key and because of that url doesn't containing any signature and value and for that the url isn't working.. If you know how to overcome from this please tell us – Code Cooker May 07 '17 at 12:16
  • it's works but sometime not work like copyright video not download https://www.youtube.com/watch?v=rs-T3zSoFgQ I have checked other website https://y2mate.com/youtube/Ye9T5eD258k same video download option available here. – Kishan Chauhan Mar 30 '18 at 13:24
7

After a lot of failed tries, this github repositories help me:

https://github.com/rg3/youtube-dl

Get the url only like:

youtube-dl 'https://www.youtube.com/watch?v=bo_efYhYU2A' --get-url

download an mp4 and save as a.mp4 like:

youtube-dl 'https://www.youtube.com/watch?v=bo_efYhYU2A' -f mp4 -o a.mp4

Good luck.

rongdong.bai
  • 471
  • 1
  • 6
  • 16
2

Last time I was working on fixing one of the broken Chrome extensions to download YouTube video. I fixed it by altering the script part.

(Javascript)

var links = new String();
var downlink = new String();
var has22 = new Boolean();
has22 = false;
var Marked = false;

var FMT_DATA = fmt_url_map;//This is html text that you have to grab. In case of extension it was readily available through:document.getElementsByTagName('script');

var StrSplitter1 = '%2C', StrSplitter2 = '%26', StrSplitter3 = '%3D';
if (FMT_DATA.indexOf(',') > -1) { //Found ,
    StrSplitter1 = ',';
    StrSplitter2 = (FMT_DATA.indexOf('&') > -1) ? '&' : '\\u0026';
    StrSplitter3 = '=';
}

var videoURL = new Array();
var FMT_DATA_PACKET = new Array();
var FMT_DATA_PACKET = FMT_DATA.split(StrSplitter1);

for (var i = 0; i < FMT_DATA_PACKET.length; i++) {
    var FMT_DATA_FRAME = FMT_DATA_PACKET[i].split(StrSplitter2);
    var FMT_DATA_DUEO = new Array();

    for (var j = 0; j < FMT_DATA_FRAME.length; j++) {
        var pair = FMT_DATA_FRAME[j].split(StrSplitter3);
        if (pair.length == 2) {
            FMT_DATA_DUEO[pair[0]] = pair[1];
        }
    }

    var url = (FMT_DATA_DUEO['url']) ? FMT_DATA_DUEO['url'] : null;

    if (url == null) continue;
    url = unescape(unescape(url)).replace(/\\\//g, '/').replace(/\\u0026/g, '&');
    var itag = (FMT_DATA_DUEO['itag']) ? FMT_DATA_DUEO['itag'] : null;
    var itag = (FMT_DATA_DUEO['itag']) ? FMT_DATA_DUEO['itag'] : null;
    if (itag == null) continue;
    var signature = (FMT_DATA_DUEO['sig']) ? FMT_DATA_DUEO['sig'] : null;
    if (signature != null) {
        url = url + "&signature=" + signature;
    }
    if (url.toLowerCase().indexOf('http') == 0) { // validate URL 

        if (itag == '5') {
            links += '<a href="' + url + '&title=' + username + title + quality240 + '"style="text-decoration:none"><span class="yt-uix-button-menu-item" id="v240p">FLV (240p)</span></a>';
        }
        if (itag == '18') {
            links += '<a href="' + url + '&title=' + username + title + quality360 + '"style="text-decoration:none"><span class="yt-uix-button-menu-item" id="v360p">MP4 (360p)</span></a>';
        }
        if (itag == '35') {
            links += '<a href="' + url + '&title=' + username + title + quality480 + '"style="text-decoration:none"><span class="yt-uix-button-menu-item" id="v480p">FLV (480p)</span></a>';
        }
        if (itag == '22') {
            links += '<a href="' + url + '&title=' + username + title + quality720 + '"style="text-decoration:none"><span class="yt-uix-button-menu-item" id="v720p">MP4 HD (720p)</span></a>';
        }
        if (itag == '37') {
            links += ' <a href="' + url + '&title=' + username + title + quality1080 + '"style="text-decoration:none"><span class="yt-uix-button-menu-item" id="v1080p">MP4 HD (1080p)</span></a>';
        }
        if (itag == '38') {
            links += '<a href="' + url + '&title=' + username + title + quality4k + '"style="text-decoration:none"><span class="yt-uix-button-menu-item"  id="v4k">MP4 HD (4K)</span></a>';
        }

        FavVideo();
        videoURL[itag] = url;
        console.log(itag);
    }
}

You can get separate video link from videoURL[itag] array.

The extension can be downloaded from here.

I hope this would help someone. This is working solution (as of 06-Apr-2013)

Vivek Jain
  • 3,811
  • 6
  • 30
  • 47
Rajendra
  • 93
  • 7