Thursday, October 18, 2012

How to play a video on HTML5 canvas tag


How to play a video on HTML5 canvas tag

Step-by-step tutorial on how to play a video on HTML5 canvas tag



First you need a video file. Actually, two. One video file in ogg format (for Chrome and Firefox) and the other one in mp4 format (for Safari). To get any video in these file formats you can use a website like www.online-convert.com or www.mediaconverter.org.

Once you have the video files, the next step is to create a simple HTML page with one canvas tag, and one video tag. Just like the code below.

 <!DOCTYPE html>  
 <head>  
 <title>Playing YouTube video on HTML5 canvas</title>  
 </head>  
 <body>  
  <video id="video" autoplay="true" loop="true">  
   <source src="./video/BigBuckBunny_640x360.ogv" type="video/ogg" />  
   <source src="./video/BigBuckBunny_640x360.mp4" type="video/mp4" />  
  </video>  
  <canvas id="canvas"></canvas>  
 </body>  
 </html>  

Right now, you should be able to test the video and check if it is playing well on Chrome Safari and Firefox.

Next, we add some CSS and a new hidden div wrapping the video tag.

 <!DOCTYPE html>  
 <head>  
 <title>Playing YouTube video on HTML5 canvas</title>  
 </head>  
 <body>  
  <video id="video" autoplay="true" loop="true">  
   <source src="./video/BigBuckBunny_640x360.ogv" type="video/ogg" />  
   <source src="./video/BigBuckBunny_640x360.mp4" type="video/mp4" />  
  </video>  
  <canvas id="canvas"></canvas>  
 </body>  
 </html>  

Since we will be rendering the video on canvas, we need to make the video hidden. But we will be using the audio from the video tag.

Now the only missing piece is the javascript that renders the video on canvas. To do this we need to grab a image from the video and then paint this image on canvas. If we repeat this process every X milliseconds... TA-DA! We have the video playing on canvas.

Here is the full source code:

 <!DOCTYPE html>  
 <head>  
 <title>Playing YouTube video on HTML5 canvas</title>  
 <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width" />  
 <style type="text/css">  
  html, body {  
   width: 100%;  
   height: 100%;  
   padding: 0px;  
   margin: 0px;  
  }  
  #canvas {  
   padding: 0px;  
   margin: 0px;  
   top:0;  
   left:0;  
   z-index: 30;  
   position: absolute;  
   width: 100%;  
   height: 100%;  
  }  
 </style>  
 </head>  
 <body>  
  <div style="display: none;">  
   <video id="video" autoplay="true" loop="true">  
    <source src="./video/BigBuckBunny_640x360.ogv" type="video/ogg" />  
    <source src="./video/BigBuckBunny_640x360.mp4" type="video/mp4" />  
   </video>  
  </div>  
  <canvas id="canvas"></canvas>  
  <script>  
  document.addEventListener('DOMContentLoaded', function(){  
   var v = document.getElementById('video');  
   var canvas = document.getElementById('canvas');  
   var context = canvas.getContext('2d');  
   //var cw = Math.floor(canvas.clientWidth / 100);  
   //var ch = Math.floor(canvas.clientHeight / 100);  
   var cw = Math.floor(canvas.clientWidth);  
   var ch = Math.floor(canvas.clientHeight);  
   canvas.width = cw;  
   canvas.height = ch;  
   v.addEventListener('play', function(){  
    draw(this,context,cw,ch);  
   },false);  
  },false);  
  function draw(v,c,w,h) {  
   if(v.paused || v.ended) return false;  
   c.drawImage(v,0,0,w,h);  
   setTimeout(draw,20,v,c,w,h);  
  }  
  </script>  
 </body>  
 </html>  


If you want to play a video from YouTube, check this tutorial: Playing YouTube videos on HTML5 canvas with Javascript.

If you want to download a video from YouTube, check this one: Download YouTube video files with Javascript

Next, I'll show you how to make a simple HTML5 game puzzle. Stay tuned!


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!


Playing YouTube videos on HTML5 canvas with Javascript

Playing YouTube videos on HTML5 canvas with Javascript

How to play YouTube videos on HTML5 canvas tag

This blog post is coming soon. Stay tuned!

Saturday, October 13, 2012

Step-by-step creating a HTML5 image puzzle game

Step-by-step creating a HTML5 image puzzle game

How to create a HTML5 image puzzle game with images, canvas, audio and fullscreen support.

Tutorial coming soon 

Adsense - Responsive Ads using a Javascript interface

Adsense - Responsive Ads with a Javascript interface

How to make responsive ads using Javascript

So, the idea is check the user screen size and then based on that value show up the ads.

In my case I have the following set:
  • Desktop
    • Leaderboard (728x90)

  • Portrait tablet to landscape and desktop
    • Banner (468x60)

  • Landscape phone to portrait tablet
    • Banner (468x60)

  • Landscape phones and down
    • Half Banner (234x60)


See the source code example:

 <script type="text/javascript">  
       google_ad_client = "ca-pub-XXXXXX";  
       google_ad_slot = "";  
       if(window.innerWidth >= 800) {  
        //visible-desktop  
        //Medium Rectangle  
        google_ad_slot = "xxxxxxx";  
        google_ad_width = 300;  
        google_ad_height = 250;  
       }  
       else if((window.innerWidth > 480)&&(window.innerWidth < 800)) {  
        //visible-tablet  
        //Square  
        google_ad_slot = "xxxxxxx";  
        google_ad_width = 250;  
        google_ad_height = 250;  
       }  
       else if(window.innerWidth <= 480) {  
        //visible-phone  
        //Large Rectangle  
        google_ad_slot = "xxxxxxx";  
        google_ad_width = 336;  
        google_ad_height = 280;  
       }  
       if(google_ad_slot != "")  
        document.write('1: <scr'+'ipt type=\"text/javascript\" src=\"http://pagead2.googlesyndication.com/pagead/show_ads.js\"></scri'+'pt>');  
       </script>  

Are you using Twitter Bootstrap? If so, you can make the same thing quite easier. Take a look!

Friday, October 12, 2012

Adsense - Responsive Ads with CSS @media queries from Bootstrap responsive utility classes

Adsense - Responsive Ads with Bootstrap and CSS @media queries


Twitter Bootstrap is built with Responsive utility classes that help us to implement different sizes of ads   for different devices.

ClassPhones767px and belowTablets979px to 768pxDesktopsDefault
.visible-phoneVisible
.visible-tabletVisible
.visible-desktopVisible
.hidden-phoneVisibleVisible
.hidden-tabletVisibleVisible
.hidden-desktopVisibleVisible
So, the idea is to use these classes to show the right ads. In my case I have the following set:

  • Desktop
    • Leaderboard (728x90)


  • Portrait tablet to landscape and desktop
    • Banner (468x60)

  • Landscape phone to portrait tablet
    • Banner (468x60)

  • Landscape phones and down
    • Half Banner (234x60)


It is really simple to achieve this using the Bootstrap built-in responsive utility classes. See the example bellow:


 <div class="visible-desktop">  
        <script type="text/javascript">  
             google_ad_client = "ca-pub-XXXXXX";  
             google_ad_slot = "XXXXXXX";  
             google_ad_width = 728;  
             google_ad_height = 90;  
        </script>  
        <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>   
 </div>  

 <div class="visible-tablet">  
        <script type="text/javascript">  
             google_ad_client = "ca-pub-XXXXXX";  
             google_ad_slot = "XXXXXXX";  
             google_ad_width = 468;  
             google_ad_height = 60;  
        </script>  
        <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
 </div>  

 <div class="visible-phone">  
        <script type="text/javascript">  
             google_ad_client = "ca-pub-XXXXXX";  
             google_ad_slot = "XXXXXXX";  
             google_ad_width = 234;  
             google_ad_height = 60;  
        </script>  
        <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
 </div>  

Easy uh?!

Here is a example showing how we can make the same thing using Javascript only.