4

私の問題で非常に混乱しているので、前もってお詫び申し上げます。これが私の本番サイトで問題を引き起こしているので、私は本当に困っています。

私のサイトには、youtube、soundcloud、または vimeo でホストできる曲リストを再生する JavaScript プレーヤーがあります。昨日、プレーヤー ボタンで「スキップ」して新しい曲をロードしようとすると、通常このエラーが発生することに気付きました。このエラーは、ここ 1 日か 2 日で始まったばかりです。YouTube API のリリース ノートに新しい情報は見当たりません。このエラーは Chrome、Firefox、および Safari を使用して発生するため、ブラウザの変更とは関係ない可能性が高いです。ただし、18 日間新しいコードをプッシュしていないため、使用しているものは変更されています。

プレイリストの例はこちら: http://www.muusical.com/playlists/programming-music

エラーを再現する方法を分離したと思います。手順は次のとおりです。

  1. YouTube でホストされている曲を再生します。
  2. リスト内の他の曲にスキップします (スキップ ボタンを押すか、曲の行項目の再生ボタンを直接押します)。

*プレイリストの最初の曲が YouTube の曲の場合、最初に読み込まれた YouTube の曲を再生せずに別の曲にスキップすると、エラーが発生することに注意してください。

基本的に、YouTube の曲を読み込んだり再生したりして、別の曲にスキップしようとすると、エラーが発生するようです。

この動作の例外を見つけた場合はお知らせください。

コンソールに次のエラーが表示されます。

Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://www.muusical.com') does not match the recipient window's origin ('http://www.muusical.com').

YouTube JavaScript API を使用してプレーヤーをロードします。

new YT.Player('playlist-player', {
      playerVars: { 'autoplay': 1, 'fs': 0 },
      videoId: "gJ6APKIjFQY",
      events: {
        'onReady': @initPlayerControls,
        'onStateChange': @onPlayerStateChange
      }
    })

この iframe を生成するもの:

<iframe id="playlist-player" frameborder="0" allowfullscreen="1" title="YouTube video player" width="640" height="360" src="https://www.youtube.com/embed/gJ6APKIjFQY?autoplay=1&amp;enablejsapi=1&amp;origin=http%3A%2F%2Fwww.muusical.com"></iframe>

上記の YouTube の曲からスキップすると、iframe に次のように読み込まれます。

<iframe id="playlist-player" frameborder="0" allowfullscreen="1" title="YouTube video player" width="640" height="360" src=""></iframe>

YouTube、soundcloud、vimeo の曲をサポートしています。YouTube の曲が読み込まれると、「オリジン」が http から https に変わるようです。プレイリスト全体が youtube のみの場合でもこのエラーが発生し、soundcloud と vimeo の曲のみで構成されるプレイリストでは発生しないため、他のホストの埋め込み方法を含める必要はないと思います。

また、これはYouTubeのjavascriptをロードする方法です:

// Load the IFrame Player API code asynchronously.
  var tag = document.createElement('script');
  tag.src = "https://www.youtube.com/player_api";
  var firstScriptTag = document.getElementsByTagName('script')[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

何か明確にする必要がある場合はお知らせください。ご覧いただきありがとうございます。

4

4 に答える 4

3

@sodawillowの答えは部分的に正しいですが、解決策の詳細と、コードが.destroy()YouTubeプレーヤーを削除するメソッドの呼び出しを停止した原因を教えてください。

私のサイトには、さまざまなサイトの曲を入れ替えるプレーヤーがあり、そのうちの 1 つが Youtube です。プレーヤーの種類によって、プレーヤーを削除する方法が異なります。私のコードはYouTubeプレーヤーの存在をチェックし、チェックに合格した場合.destroy()、YouTubeプレーヤーのみが持つメソッドを使用します。問題は、YouTube がプレーヤー オブジェクトのいくつかの静的変数の名前を変更したことです。たとえば、次の方法でプレーヤーを作成したとします。

var player = new YT.Player('playlist-player', {
      playerVars: { 'autoplay': 1, 'fs': 0 },
      videoId: "gJ6APKIjFQY",
      events: {
      }
    })

player.L次に、文字列を保持する変数があります"player"。したがって、現在のプレーヤーが YouTube プレーヤーであるかどうかを確認して削除するには、次のようにしました。

if (player.L == "player") {
  player.destroy();
} else {
//handle the removal of the Soundcloud or Vimeo player.
}

最近、Youtube が文字列の場所を に変更し"player"ましたplayer.Mplayer.M上記のコードを代わりにチェックするように変更できますがplayer.L、それは機能しますが、将来この問題を回避するために、代わりに実装しました:

if (player.destroy) {
  player.destroy();
} else {
//handle the removal of the Soundcloud or Vimeo player.
}

YouTube が.destroy()未発表のメソッドを削除しない限り、問題は発生しません。

要約すると、問題は@sodawillowが推測したとおりで.destroy()、Youtubeプレーヤーを削除する方法を使用していませんでした。その理由は、Youtube が API に未発表の変更を加え、いくつかの静的変数の場所を変更したためです。

于 2015-01-14T01:17:41.110 に答える
0

私の解決策は、すべての Youtube プレーヤー ロジックを別のページ (できるだけ空白) に記述し、そのページをIFRAMEタグで参照することです。

<iframe src="/youtube_frame/?data=SOME_DATA -%>" height="400px" width="100%" frameborder="0" border="0" scrolling="no"></iframe>

次に、あなたのyoutube_frame.html意志は次のようになります。

<!DOCTYPE html>
<html>
  <body>
    <!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
    <div id="player"></div>

    <script>
      // 2. This code loads 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);

      // 3. This function creates an <iframe> (and YouTube player)
      //    after the API code downloads.
      var player;
      function onYouTubeIframeAPIReady() {
        player = new YT.Player('player', {
          height: '390',
          width: '640',
          videoId: 'M7lc1UVf-VE',
          events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
          }
        });
      }

      // 4. The API will call this function when the video player is ready.
      function onPlayerReady(event) {
        // event.target.playVideo();
      }

      // 5. The API calls this function when the player's state changes.
      //    The function indicates that when playing a video (state=1),
      //    the player should play for six seconds and then stop.
      var done = false;
      function onPlayerStateChange(event) {
        console.log("OnplayerStateChange");
        if (event.data == YT.PlayerState.PLAYING && !done) {
          console.log("OnplayerStateChange - If statement");
          setTimeout(stopVideo, 6000);
          done = true;
        }
      }
      function stopVideo() {
        player.stopVideo();
      }
    </script>
  </body>
</html>

(余談ですが、Prototype.js は「OnStateChange」イベントに干渉し、この依存関係を削除することはできません。依存関係がほとんどないため、jsfiddle を使用しても問題を再現することはできません。私のアプリは次のとおりです。 Railsに組み込まれ、このプラグインを使用してビデオプレイリストを表示します: https://github.com/Giorgio003/Youtube-TV/ )

于 2016-08-18T00:38:39.497 に答える