Showing posts with label video formats. Show all posts
Showing posts with label video formats. Show all posts

Sunday, March 3, 2013

How to grab YouTube playback video files

How to grab YouTube playback video files

Step-by-step tutorial showing how to get all available video source files from a video on YouTube using only Javascript. No plugins and/or server side scripts are required.

First of all I want to list here a few benefits from being able to do that.

  1. You can download any video from YouTube without plugins or server-side scripts. You just need a browser.
  2. You can use YouTube as an encoder. Let's say you have to convert a FLV video to MP4 or
    WebM.
  3. You can set a cron job to run once a week to download all available video files from any channel.
  4. You can play any YouTube video out of the YouTube player (not recommend).
  5. You can play YouTube videos on HTML5 canvas and go crazy! Check this out at: http://videopuzzle.possum-cms.com

How to do it



Step 1: Extract YouTube video ID from URL

  var url = 'http://www.youtube.com/watch?v=yntfUjenls0';  
  var video_id = '';  
  var regExp = /.*(?:youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=)([^#\&\?]*).*/;  
  var match = url.match(regExp);  
  if(match){  
   video_id = match[1];  
  }  

Step 2: Request YouTube playback files information

Easy as pie. Just make an Ajax request to: http://www.youtube.com/get_video_info sending the desired video ID...
  $.ajax({  
   url: "http://www.youtube.com/get_video_info?video_id="+video_id,  
   dataType: "text"  
  }).done(function(data) {  
   ...  
  });  


Step 3: Parse the response data information from YouTube

The information that we are looking for is "url_encoded_fmt_stream_map". This variable contains all streams available for the requested movie.

 function(data) {  
  var info = {};  
  parse_str(data, info);  
  var streams = explode(',', info['url_encoded_fmt_stream_map']);  
  ...  


Step 4: Trick. Parse again each one of the streams

YouTube encode the information twice, so you have to parse it again.
There is other trick here, You also have to add a signature value on each stream url, otherwise it won't work.

  var results = [];  
  for(var i=0; i<streams.length; i++){  
   var real_stream = {};  
   parse_str(streams[i], real_stream);  
   real_stream['url'] += '&signature=' + real_stream['sig'];  
   results.push(real_stream);  
  }  



Step 5: Have fun!


By now you should have a variable "results" with all YouTube video files available for the requested movie.

You can do whatever you want with the files. For example: display a link, play the video, grab snap shots of the video... Have fun!

To display the a link for each video file available...

   if(results.length > 0){  
    $.each(results, function(index, value) {  
     $('#results').append('<a href="'+value.url+'">'+value.quality+' - '+value.type</a>');  
    });  
   }  

Wednesday, October 17, 2012

Download YouTube video files with Javascript

UPDATED! 

Download YouTube video files with Javascript

How to download YouTube videos files with Javascript only! Is it possible?

YES! It is possible! And without relying in any kind of server side scripts!






Libraries needed to do this:
  • jQuery

Step-by-step: Downloading YouTube videos with Javascript.

  • Part 1: Get the YouTube video URL from an input and validate the URL using regular expression. 
  var url = $('#url').val();  
  var regExp = /.*(?:youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=)([^#\&\?]*).*/;  
  var match = url.match(regExp);  
  if(match){  
   $('#download-btn').fadeOut('fast');  
   $('#loading').fadeIn('slow');  
   setTimeout("getVideo('"+match[1]+"')",2000);  
  }  
  else{  
   alert('Invalid URL!');  
   $('#url').val("");  
   $('#url').focus();  
  }  

  • Part 2: Retrive raw video information from YouTube
    • Make an Ajax call to http://www.youtube.com/get_video_info?video_id=XXX

       $.ajax({  
        url: "http://www.youtube.com/get_video_info?video_id="+id,  
        dataType: "text"  
       }).done(function(data) {
        ...  


  • Part 3: Prepare information to be parsed. We need to do 3 things:
    • a) Replace all occurrences of the character "\" to "%20"

       data = (data+'').replace(/\+/g, '%20');  
      

    • b) Replace all occurrences of the string "url%3D" to "\n\r<break>"

       data = data.replace(/url%3D/g, '\n\r\n\r<break>');  
      

    • c) Replace all occurrences of the string "sig%3D" to "signature%3D"

       data = data.replace(/sig%3D/g, 'signature%3D');  
      


  • Part 4: Grab all files URLs from this YouTube video
  var urls = data.split('<break>');   
  for(var u = 0; u < urls.length; u++){   
  var result = {};   
  ...   
  }   

  • Part 5: Prepare each URL to be parsed
    • a) Decode the URL

       decodeURIComponent((urls[u]+'')  
      
    • b) Replace all occurrences of the character "\" to "%20"

       url = url.replace(/\+/g, '%20');  
      
    • c) Unescape the result twice

       url = unescape(unescape(url));  
      
    • d) Replace all occurrences of the string '="' to '%3D%22'

       url = url.replace(/="/g, '%3D%22');  
      
    • e) Replace all occurrences of the character '"' to "%22"

       url = url.replace(/"/g, '%22');  


  • Part 6: Return a list for the videos URLs present in the YouTube results.
    • a) Parse all variables present in each URL

       var vars = [], hash;  
       var hashes = d.slice(d.indexOf('?') + 1).split('&');  
       for(var i = 0; i < hashes.length; i++){  
        hash = hashes[i].split('=');  
        vars.push(hash[0]);  
        vars[hash[0]] = unescape(hash[1]);  
       }  
      
    • b) Grab the video type and codecs from the URL parameters

       if(vars['type']!=undefined){  
        result.type = vars['type'];  
        if(vars['type'].indexOf("codecs")>0){  
         var cs = vars['type'].split(';+codecs="');  
         result.type = cs[0];  
         result.codecs = cs[1].replace('"','').replace('+',' ');  
        }  
       }  
      
    • c) Grab the video quality from the URL parameters

       //quality  
       if(vars['quality']!=undefined){  
        result.quality = vars['quality'];  
        if(vars['quality'].indexOf(",")>0){  
         var cs = vars['quality'].split(',');  
         result.quality = cs[0];  
        }  
       }  

That is it. Now you have all information needed in the result object. Here is the full source-code:

 /* Author: Emerson Estrella */  
 $('#again').click(function() {  
  $('#hero2').fadeOut('fast');$('#hero1').fadeIn('slow');  
 });  
 $('#form').submit(function() {  
  var url = $('#url').val();  
  var regExp = /.*(?:youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=)([^#\&\?]*).*/;  
  var match = url.match(regExp);  
  if(match){  
   $('#download-btn').fadeOut('fast');  
   $('#loading').fadeIn('slow');  
   setTimeout("getVideo('"+match[1]+"')",2000);  
  }  
  else{  
   alert('Invalid URL!');  
   $('#url').val("");  
   $('#url').focus();  
  }  
  return false;  
 });  
 function getVideo(youtube_video_id){  
  var id = "b4VsluhWVh8";  
  id = youtube_video_id;  
  $.ajax({  
   url: "http://www.youtube.com/get_video_info?video_id="+id,  
   dataType: "text"  
  }).done(function(data) {  
   var results = [];  
   var r = 0;  
   data = (data+'').replace(/\+/g, '%20');  
   data = data.replace(/url%3D/g, '\n\r\n\r<break>');  
   data = data.replace(/sig%3D/g, 'signature%3D');  
   var urls = data.split('<break>');  
   for(var u = 0; u < urls.length; u++){  
    var result = {};  
    var d = unescape(unescape(decodeURIComponent((urls[u]+'').replace(/\+/g, '%20'))));  
    d = d.replace(/="/g, '%3D%22');  
    d = d.replace(/"/g, '%22');  
    var url = d;  
    //console.log(d);  
    //console.log(d.length);  
    if(d.length > 1500){  
     aux = d.split('&has_cc');  
     d = aux[0];  
    }  
    var vars = [], hash;  
    var hashes = d.slice(d.indexOf('?') + 1).split('&');  
    for(var i = 0; i < hashes.length; i++){  
     hash = hashes[i].split('=');  
     vars.push(hash[0]);  
     vars[hash[0]] = unescape(hash[1]);  
    }  
    if(vars['type']!=undefined){  
     result.type = vars['type'];  
     if(vars['type'].indexOf("codecs")>0){  
      var cs = vars['type'].split(';+codecs="');  
      result.type = cs[0];  
      result.codecs = cs[1].replace('"','').replace('+',' ');  
     }  
    }  
    //quality  
    if(vars['quality']!=undefined){  
     result.quality = vars['quality'];  
     if(vars['quality'].indexOf(",")>0){  
      var cs = vars['quality'].split(',');  
      result.quality = cs[0];  
     }  
    }  
    if(result.type && result.quality){  
     result.url = url;  
     results[r] = result;  
     r++;  
    }  
   }  
   //console.log(results);  
   //print results  
   var html = '';  
   html += '<h4 class="alert-heading" style="margin-top: 25px;">All video files found for your request</h4>';  
   html += '<a id="again" style="margin-top: 25px;" class="btn btn-small btn-danger" href="#main" onclick="$(\'#hero2\').fadeOut(\'fast\');$(\'#hero1\').fadeIn(\'slow\');"><i class="icon-repeat icon-white"></i> Make Another Request</a>';  
   html += '<table class="table table-striped musica" style="background: rgba(255,255,255,0.7); margin-top:25px;"><thead><tr><th>Quality</th><th>Format</th><th>Codecs</th><th style="text-align: right;"></th></tr></thead><tbody>';  
   $.each(results, function(index, value) {  
    html += '\n\r<tr>';  
    html += '<td>'+value.quality+'</td>';  
    html += '<td>'+value.type+'</td>';  
    if(value.codecs!=undefined)  
     html += '<td>'+value.codecs+'</td>';  
    else  
     html += '<td>N/A</td>';  
    html += '<td><a class="btn btn-success pull-left" href="'+value.url+'" style="margin-right: 15px;"><i class="icon-download-alt icon-white"></i> Download this video format file</a></td>';  
    html += '</tr>\n\r';  
   });  
   html += '</tbody></table><a style="margin-top: 10px; margin-bottom: 25px;" class="btn btn-small btn-danger" href="#main" onclick="$(\'#hero2\').fadeOut(\'fast\');$(\'#hero1\').fadeIn(\'slow\');"><i class="icon-repeat icon-white"></i> Make Another Request</a>';  
   $('#vid').html(html);  
   $('#vid').fadeIn('slow');  
   $('#loading').hide();  
   $('#hero1').hide();  
   $('#hero2').fadeIn('slow');  
   $('#download-btn').show();  
  });  
 }  





In the next post I'll explain how to Download YouTube video files from a server side script like PHP. Stay tuned!