YouTube 播放器 API:如何在不播放的情况下获取已加载/提示视频的持续时间?

发布于 2024-08-18 09:35:09 字数 2625 浏览 6 评论 0原文

我无法通过 YouTube Player API 的 getDuration() 方法获取已加载/提示视频的正确视频持续时间/长度(以秒为单位);然而,一旦视频开始播放,相同的方法就会返回一个有效值!想知道 YouTube 如何显示已加载/提示视频的有效持续时间。

当我加载包含 15 秒视频剪辑的 HTML 页面时,我得到以下调试输出:

state = 5uration = -0.000025

当我点击“播放”按钮时,我得到以下调试输出:

>状态= 3持续时间= 15,

非常感谢解决方案或解决方法。加载、立即播放和暂停播放器不是我最喜欢的方法。

<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>

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&enablejsapi=1&playerapiid=" + 'player', 'player', 425, 344, "8", null, null, params, atts);
    </script>
    </td></tr>
  </table>
  <div id="out"></div>
  <div id="err"></div>
</body>
</html>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

凉风有信 2024-08-25 09:35:09

解决方案 1

您可以使用 YouTube 数据 API 访问有关视频的大部分信息,包括时长:

<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>

此处演示

使用 jQuery 时,您可以使用 $.getJSON() 让事情变得更容易。

解决方案 2

YouTube JavaScript API v3 似乎允许您在 onYouTubePlayerReady() 事件中获取正确的持续时间。您所需要做的就是在调用 swfobject.embedSWF() 方法时传递 &version=3

此处演示

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

我是男神闪亮亮 2024-08-25 09:35:09

按照以下步骤操作:

  1. 获取 youtube 视频 ID
  2. 使用 youtube API 获取持续时间(ISO 8601 持续时间)
  3. 将 ISO 8601 持续时间转换为时间:

使用 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);
              }
            }
        });
    }
});

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);
              }
            }
        });
    }
});
绝情姑娘 2024-08-25 09:35:09

“加载、立即播放和暂停播放器不是我最喜欢的方法。”

我认为没有其他方法。

就我而言,它效果很好,即使对于卫星互联网用户也是如此。

这是我的代码:

// I set youtube player-ready event to a variable for irrelevant reasons
function onYouTubePlayerReady(playerid) { 
    youtube_player_ready;
}
youtube_player_ready = function(playerid) {

    // load video
    document.getElementById(playerid).cueVideoById(yt_video_id);
    // mute video
    document.getElementById(playerid).mute();
    // play video to get meta data
    document.getElementById(playerid).playVideo();

    yt_get_duration[index] = function(){
        // if duration is available
        if (document.getElementById(playerid).getDuration() > 0) {
            // pause video
            document.getElementById(playerid).pauseVideo();
            // unmute
            document.getElementById(playerid).unMute();
            // save duration
            video_duration = document.getElementById(playerid).getDuration();

        }
        // else keep trying
        else {
            setTimeout(yt_get_duration[index], 150)
        }
    }
    // get duration
    yt_get_duration[index]();

}

"Loading, and immediately playing and pausing the player would be not my favorite method."

I don't think there is any other method.

In my case it works well, even for a satellite internet user.

Here is my code :

// I set youtube player-ready event to a variable for irrelevant reasons
function onYouTubePlayerReady(playerid) { 
    youtube_player_ready;
}
youtube_player_ready = function(playerid) {

    // load video
    document.getElementById(playerid).cueVideoById(yt_video_id);
    // mute video
    document.getElementById(playerid).mute();
    // play video to get meta data
    document.getElementById(playerid).playVideo();

    yt_get_duration[index] = function(){
        // if duration is available
        if (document.getElementById(playerid).getDuration() > 0) {
            // pause video
            document.getElementById(playerid).pauseVideo();
            // unmute
            document.getElementById(playerid).unMute();
            // save duration
            video_duration = document.getElementById(playerid).getDuration();

        }
        // else keep trying
        else {
            setTimeout(yt_get_duration[index], 150)
        }
    }
    // get duration
    yt_get_duration[index]();

}
半衾梦 2024-08-25 09:35:09

这里有一个可以为您转换时间的工具。

    <script type="text/javascript">
function youtubeFeedCallback(json){

var totalSec = json["data"]["duration"];
var hours = parseInt( totalSec / 3600 ) % 24;
var minutes = parseInt( totalSec / 60 ) % 60;
var seconds = totalSec % 60;

var result = (hours < 1 ? "" : hours + ":") + (minutes < 1 ? "0" : minutes) + ":" + (seconds  < 10 ? "0" + seconds : seconds);

document.write(result);
}
</script>
<script type="text/javascript" src="http://gdata.youtube.com/feeds/api/videos/LzPWWpKlvqQ?v=2&alt=jsonc&callback=youtubeFeedCallback&prettyprint=true"></script>

Here one that converts the time over for you.

    <script type="text/javascript">
function youtubeFeedCallback(json){

var totalSec = json["data"]["duration"];
var hours = parseInt( totalSec / 3600 ) % 24;
var minutes = parseInt( totalSec / 60 ) % 60;
var seconds = totalSec % 60;

var result = (hours < 1 ? "" : hours + ":") + (minutes < 1 ? "0" : minutes) + ":" + (seconds  < 10 ? "0" + seconds : seconds);

document.write(result);
}
</script>
<script type="text/javascript" src="http://gdata.youtube.com/feeds/api/videos/LzPWWpKlvqQ?v=2&alt=jsonc&callback=youtubeFeedCallback&prettyprint=true"></script>
一抹淡然 2024-08-25 09:35:09

使用 jQuery

var youTubeURL = 'http://gdata.youtube.com/feeds/api/videos/oHg5SJYRHA0?v=2&alt=json';
var json = (function () {
    $.ajax({
        'async': false,
        'global': false,
        'url': youTubeURL,
        'dataType': "jsonp", // necessary for IE9
        crossDomain: true,
        'success': function (data) {
            var duration = data.entry.media$group.yt$duration.seconds;
        }
    });
})();

Using jQuery

var youTubeURL = 'http://gdata.youtube.com/feeds/api/videos/oHg5SJYRHA0?v=2&alt=json';
var json = (function () {
    $.ajax({
        'async': false,
        'global': false,
        'url': youTubeURL,
        'dataType': "jsonp", // necessary for IE9
        crossDomain: true,
        'success': function (data) {
            var duration = data.entry.media$group.yt$duration.seconds;
        }
    });
})();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文