Youtube player.destroy();即使在验证玩家

时间:2017-09-06 23:14:29

标签: javascript jquery video youtube

所以我有一个带有两个面板的小应用程序。使用iframe API。单击一个面板将全屏展开面板,并显示带有一些附加信息的“播放视频”按钮。单击左上角的按钮可将UI返回到标准状态,关闭视频并将面板收缩至50/50。

现在我们有两个视频,我已经定义了视频,#vidPlayer2是第二个触发器。

$('#vidPlayer1').on('click', function(){
  player = new YT.Player('player', {
    height: '100%',
    width: '100%',
    videoId: '(video id here)',
    controls: 0,
    showinfo: 0,
    autoplay: 0,
    rel: 0,
    events: {
      'onReady': onPlayerReady,
      'onStateChange': onPlayerStateChange
    }
  });

同样,我们有一个默认的演示代码,只做了一些小修改:

function onPlayerReady(event) {
  event.target.playVideo();
}

var done = false;
function onPlayerStateChange(event) {
  if (event.data == YT.PlayerState.PLAYING && !done) {
    done = true;
  }
  if (event.data == YT.PlayerState.ENDED) {
    resetView();
  }
}
function stopVideo() {
  player.stopVideo();
}

然后,我们试图让按钮工作。在某些情况下,没有点击其中一个vidPlayer按钮,没有定义任何播放器,所以我在if语句中进行了一些验证。

var resetView = function() {
  // If a Youtube player is active, make sure we stop it.
  if (player === undefined || !player || null) {
    console.log("Player could not be found.");
  } else {
    player.stopVideo();
    player.destroy();
  }
  // Additional code to reset the UI removed below. Works no matter what if the above code is removed.
};

现在大部分事情都很顺利直到我尝试进入面板,播放视频,重置UI,然后尝试进入和离开下一个面板而不播放视频。当我按照这一系列步骤进行操作时,无论首先启动哪个面板,我都会在控制台中获得TypeError: this.a is null。我会假设验证会完成这个技巧,但显然不是。

所以我能与之区分的是它在初始化时工作正常 - 即var player被初始化。返回按钮可以在不播放视频的情况下来回切换。当视频正在播放时,返回按钮会起作用,但如果我们尝试在播放器停止和销毁后直接使用返回,则该功能会失败。但是,如果我们只是弹出另一个视频,它确实有用。

当我尝试重置视图时,是否有一些我遗漏的东西? youtube播放器是否必须重新初始化?任何帮助或想法将不胜感激。谢谢!

编辑:这是控制台抛出的注释。需要注意的是main.js:44:5是player.stopVideo(); call和main.js:70:3是resetView();按下按钮调用。

TypeError: this.a is null
www-widgetapi.js:120:73
f.C
https://s.ytimg.com/yts/jsbin/www-widgetapi-vflWgX7t4/www-widgetapi.js:120:73
V
https://s.ytimg.com/yts/jsbin/www-widgetapi-vflWgX7t4/www-widgetapi.js:112:97
Nb/</this[a]
https://s.ytimg.com/yts/jsbin/www-widgetapi-vflWgX7t4/www-widgetapi.js:130:124
resetView
file:///Users/cipher/Desktop/ERHS_video/js/main.js:44:5
<anonymous>
file:///Users/cipher/Desktop/ERHS_video/js/main.js:70:3
dispatch
file:///Users/cipher/Desktop/ERHS_video/js/jquery-3.2.1.min.js:3:10264
add/q.handle
file:///Users/cipher/Desktop/ERHS_video/js/jquery-3.2.1.min.js:3:8326

2 个答案:

答案 0 :(得分:3)

这里的问题是玩家未定义。发生了什么事情,你有一个全球玩家参考,你正在做以下事情:

  1. 在第一个面板中创建一个播放器
  2. 第一个面板关闭时销毁它
  3. 第二个面板关闭时,在已经销毁的播放器(从第一个面板)上调用player.stopVideo()
  4. 目前,player代表您使用的最后一个YouTube播放器,即使该播放器已被销毁。

    你应该做的是在你摧毁它时清除你对玩家的引用。毁灭不会(也不可能)这样做。您还可以简化if条件,因为!player将自行检查null和undefined:

    var resetView = function() {
      // If a Youtube player is active, make sure we stop it.
      if (!player) {
        console.log("Player could not be found.");
      } else {
        player.stopVideo();
        player.destroy();
        player = null;  // Clear out the reference to the destroyed player
      }
    

答案 1 :(得分:0)

一年后,IkeDoud的上述答案和其他类似this one的灵感得到了很大的启发,这是我避免在嵌入式API播放器中播放其他视频建议的方法:

<div id="player"></div>

<style>
#player{
  min-width:auto;
  min-height:auto;
}
</style>
<script>
// Load the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

// Initialise the player with options
var player;
var playerOptions = {
  videoId: 'ViDeOiD_HeRe',
  events: {
    'onStateChange': onPlayerStateChange
  }
};

// Load the video whern player ready
function onYouTubeIframeAPIReady() {
  player = new YT.Player('player', playerOptions);
}

// On video end, reset the player back to poster image
function onPlayerStateChange(event) {
  if(event.data === 0) {
    $(PaReNt_sElEcToR).find("#player").replaceWith('<div id="player"></div>');
    player = null;
    player = new YT.Player('player', playerOptions);
  }
}

</script>

嵌入式视频容器中不再显示不相关的建议。
而且没有自动播放功能(无论如何,手机都禁止这样做)具有海报(缩略图)图像。

event.data === 0(视频端)上……销毁并重新加载iframe。