Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

YouTube Player API: How to get duration of a loaded/cued video without playing it?

I'm not able to get the correct video duration/length (in seconds) of a loaded/cued video via the getDuration() method of the YouTube Player API; the same method, however, returns a valid value once the video starts playing! Wondering how YouTube is able to show the valid duration of a loaded/cued video.

When I load this HTML page with a 15 second video clip, I get the following debug output:

state = 5 duration = -0.000025

When I hit the Play button, I get the following debug output:

state = 3 duration = 15,

Would greatly appreciate a solution or a workaround. Loading, and immediately playing and pausing the player would be not my favorite method.

<html>
<head>
  <script type="text/javascript">
   var videoId;
   videoId = 'http://www.youtube.com/v/4TSJhIZmL0A';    // bbc
   // videoId = 'http://www.youtube.com/v/ezwyHNs_W_A'; // physics

    function $(id) {
      return document.getElementById(id);
    }
  </script>

  <script src="http://www.google.com/jsapi"></script>
  <script>
    google.load("swfobject", "2.1");
  </script>

</head>

<body>


  <table>
    <tr><td>
      <div id="player">
        You need Flash player 8+ and JavaScript enabled to view this video.
      </div>

    <script>
        var ytplayer;

        function myOnPlayerStateChange(state) {
          switch(state) {
            case 1:  // playing
              $("out").innerHTML += " playing";
              break;
            case 2:  // paused
              $("out").innerHTML += " paused";
              break;
            case 0:  // ended
              $("out").innerHTML += " ended";
              break;      

            case -1: // unstarted
            case 3:  // buffering
            case 5:  // cued
              $("out").innerHTML += " state = " + state;
              break;
            default: // unknown
              $("out").innerHTML += " state = " + state;
              break;
          }

          $("out").innerHTML += " duration = " + ytplayer.getDuration() + ",";
        }

        function myOnPlayerError(errorCode) {
          $("out").innerHTML += " Error occurred: " + errorCode;
        }

        function onYouTubePlayerReady(playerId) {
          ytplayer = ytplayer || $(playerId);
          ytplayer.addEventListener("onStateChange", "myOnPlayerStateChange");
          ytplayer.addEventListener("onError", "myOnPlayerError");
        }

        var params = { allowScriptAccess: "always", bgcolor: "#cccccc" };
        var atts = { };

        swfobject.embedSWF(videoId + "?border=0&amp;enablejsapi=1&amp;playerapiid=" + 'player', 'player', 425, 344, "8", null, null, params, atts);
    </script>
    </td></tr>
  </table>
  <div id="out"></div>
  <div id="err"></div>
</body>
</html>
like image 351
Harry Avatar asked Jan 18 '10 13:01

Harry


People also ask

How to get duration of YouTube video in JavaScript?

Solution 2. Seems like YouTube JavaScript API v3 allows you to get the correct duration inside the onYouTubePlayerReady() event. All you need to do is pass &version=3 when calling swfobject. embedSWF() method.

Can you play videos with YouTube API?

The IFrame player API lets you embed a YouTube video player on your website and control the player using JavaScript. Using the API's JavaScript functions, you can queue videos for playback; play, pause, or stop those videos; adjust the player volume; or retrieve information about the video being played.

What is iFrame API?

Developers can use the iFrame API to programmatically create and interact with an Embed or with multiple Embeds in the same web app. The iFrame API includes methods that you can use to start playback, change the content rendering in an Embed, or stop playback.


2 Answers

Solution 1

You can use YouTube Data API to access most of the information about the video, including duration:

<script type="text/javascript">
    function youtubeFeedCallback(json){
        document.write(json["data"]["duration"] + " second(s)");
    }
</script>
<script type="text/javascript" src="http://gdata.youtube.com/feeds/api/videos/4TSJhIZmL0A?v=2&alt=jsonc&callback=youtubeFeedCallback&prettyprint=true"></script>

Demo here

When using jQuery you can use $.getJSON() to make things easier.

Solution 2

Seems like YouTube JavaScript API v3 allows you to get the correct duration inside the onYouTubePlayerReady() event. All you need to do is pass &version=3 when calling swfobject.embedSWF() method.

Demo here

like image 191
Salman A Avatar answered Sep 18 '22 08:09

Salman A


Following these steps:

  1. Get youtube video id
  2. Use youtube API to get duration (ISO 8601 duration)
  3. Convert ISO 8601 duration to time

Using Jquery:

// convert ISO 8601 duration
function formatISODate(youtube_time){
  array = youtube_time.match(/(\d+)(?=[MHS])/ig)||[]; 
    var formatted = array.map(function(item){
        if(item.length<2) return '0'+item;
        return item;
    }).join(':');
    return formatted;
}

// print video duration
$('iframe').each(function(i) {
    var ifr = $(this);
    var regExp = /^.*(youtu\.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
    var match = ifr.attr('src').match(regExp);  // get youtube video id
    if (match && match[2].length == 11) {
        var youtubeUrl = "https://www.googleapis.com/youtube/v3/videos?id=" + match[2] 
        + "&key=AIzaSyDYwPzLevXauI-kTSVXTLroLyHEONuF9Rw&part=snippet,contentDetails";
        $.ajax({
            async: false,
            type: 'GET',
            url: youtubeUrl,
            success: function(data) {
              var youtube_time = data.items[0].contentDetails.duration;
              var duration = formatISODate(youtube_time); 
              if(ifr.next().is('.time')) {
                ifr.next().html(duration);
              }
            }
        });
    }
});
like image 42
Mr.Zon Avatar answered Sep 18 '22 08:09

Mr.Zon