同じページに2つの同一のYouTubeビデオが埋め込まれています。両方を同期させたいのですが、これが私の要件/メモです。
YouTube JS APIを使用してプレーヤーの状態の変化をリッスンし、両方のビデオの同期を維持しようとしましたが、期待したほど信頼性がありませんでした。このためのコードの一部を以下に掲載します。
注意点の1つは、一方のビデオがもう一方のビデオよりも大きく表示されるため、YouTubeがそのために高品質のビデオを提供する可能性があることです。
私はCSS3ぼかしを使用しているため、最近のWebkitブラウザーしか使用できないため、これらだけで(FF/IEではなく)機能するソリューションは問題ありません。
私の質問はこれです、上記の要件について、これら2つのビデオの同期を維持する方法はありますか? canvas APIを使用してビデオを「再描画」できるかどうかを検討しましたが、調査した結果、これは不可能でした。
buffering = false;
var buffer_control = function(buffering_video, sibling_video, state) {
switch ( state ) {
case 1: // play
if ( buffering === true ) {
console.error('restarting after buffer');
// pause both videos, we want to make sure they are both at the same time
buffering_video.pauseVideo();
sibling_video.pauseVideo();
// get the current time of the video being buffered...
var current_time = buffering_video.getCurrentTime();
// ... and pull the sibling video back to that time
sibling_video.seekTo(current_time, true);
// finally, play both videos
buffering_video.playVideo();
sibling_video.playVideo();
// unset the buffering flag
buffering = false;
}
break;
case 3: // buffering
console.error('buffering');
// set the buffering flag
buffering = true;
// pause the sibling video
sibling_video.pauseVideo();
break;
}
}
あなたのプロジェクトはちょっと面白いので、私はあなたを助けようと決心しました。私はyoutubeAPIを使用したことがありませんが、いくつかのコーディングを試しました。それはあなたにとっての始まりかもしれません。
だから私が試したコードはここにあり、それはかなりうまくいくようです、確かにいくつかの改善が必要です(私は2つの再生されたビデオ間のオフセットを計算しようとしませんでしたが、ミュートを解除するとミスマッチを示し、合法に聞こえます)
さあ行こう :
いくつかのhtmlの基本から始めましょう
_<!DOCTYPE html>
<html>
<head>
_
フォアグラウンドプレーヤーの絶対位置を追加して、バックグラウンドビデオを再生しているプレーヤーとオーバーレイするようにします(テスト用)
_ <style>
#player2{position:absolute;left:195px;top:100px;}
</style>
</head>
<body>
_
ここでは、jQueryを使用してプレーヤーをフェードイン/フェードアウトします(理由は以下で説明します)が、基本的なJSを使用できます
_ <script src="jquery-1.10.2.min.js"></script>
_
<iframes>(およびビデオプレーヤー)は、これらの<div>タグを置き換えます。
_ <div id="player1"></div> <!-- Background video player -->
<div id="player2"></div> <!-- Foreground video player -->
<script>
_
このコードは、IFrame PlayerAPIコードを非同期でロードします。
_ var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
_
この関数は、APIコードのダウンロード後に<iframes>(およびYouTubeプレーヤー)を作成します。コールバック関数に注意してください:onPlayer1ReadyおよびonPlayer1StateChange
_ var player1;
var player2;
function onYouTubeIframeAPIReady() {
player1 = new YT.Player('player1', {
height: '780',
width: '1280',
videoId: 'M7lc1UVf-VE',
playerVars: { 'autoplay': 0, 'controls': 0 },
events: {
'onReady': onPlayer1Ready,
'onStateChange': onPlayer1StateChange
}
});
player2 = new YT.Player('player2', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayer2Ready,
'onStateChange': onPlayer2StateChange
}
});
}
var player1Ready = false;
var player2Ready = false;
_
これがコードの興味深い部分です。同期プロジェクトの主な問題は、ビデオを起動する前にバッファリングする必要があるという事実に関連しています。実際、APIはビデオをプリロードするための直感的な機能を提供していません(帯域幅の問題(クライアント側とサーバー側)のため)。そのため、少し注意が必要です。
ビデオをプリロードする手順は次のとおりです。
player.mute():Void
);player.seekTo(seconds:Number, allowSeekAhead:Boolean):Void
);YT.PlayerState.PLAYING
_に等しい状態変更イベントを待ちます。player.pauseVideo():Void
);player.seekTo(seconds:Number, allowSeekAhead:Boolean):Void
;でビデオを巻き戻します。player.unMute():Void
);2つのビデオをプリロードする必要があります。
_ var preloading1 = false;
var preloading2 = false;
_
ビデオプレーヤーの準備ができると、APIはこれらの関数を呼び出します。
_ function onPlayer1Ready(event)
{
player1Ready = true;
preloading1 = true; // Flag the player 1 preloading
player1.mute(); // Mute the player 1
$( "#player1" ).hide(); // Hide it
player1.seekTo(1); // Start the preloading and wait a state change event
}
function onPlayer2Ready(event) {
player2Ready = true; // The foreground video player is not preloaded here
}
_
APIは、バックグラウンドビデオプレーヤーの状態が変化したときにこの関数を呼び出します。
_ function onPlayer1StateChange(event)
{
if (event.data == YT.PlayerState.PLAYING ) {
if(preloading1)
{
Prompt("Background ready"); // For testing
player1.pauseVideo(); // Pause the video
player1.seekTo(0); // Rewind
player1.unMute(); // Comment this after test
$( "#player1" ).show(); // Show the player
preloading1 = false;
player2Ready = true;
preloading2 = true; // Flag for foreground video preloading
player2.mute();
//$( "#player2" ).hide();
player2.seekTo(1); // Start buffering and wait the event
}
else
player2.playVideo(); // If not preloading link the 2 players PLAY events
}
else if (event.data == YT.PlayerState.PAUSED ) {
if(!preloading1)
player2.pauseVideo(); // If not preloading link the 2 players PAUSE events
}
else if (event.data == YT.PlayerState.BUFFERING ) {
if(!preloading1)
{
player2.pauseVideo(); // If not preloading link the 2 players BUFFERING events
}
}
else if (event.data == YT.PlayerState.CUED ) {
if(!preloading1)
player2.pauseVideo(); // If not preloading link the 2 players CUEING events
}
else if (event.data == YT.PlayerState.ENDED ) {
player2.stopVideo(); // If not preloading link the 2 players ENDING events
}
}
_
APIは、フォアグラウンドビデオプレーヤーの状態が変化したときにこの関数を呼び出します。
_ function onPlayer2StateChange(event) {
if (event.data == YT.PlayerState.PLAYING ) {
if(preloading2)
{
//Prompt("Foreground ready");
player2.pauseVideo(); // Pause the video
player2.seekTo(0); // Rewind
player2.unMute(); // Unmute
preloading2 = false;
$( "#player2" ).show(50, function() {
_
これは奇妙に動作するコードの一部です。以下の行のコメントを外すと同期がかなり悪くなりますが、コメントする場合は、[再生]ボタンの2回をクリックする必要があります[〜#〜]しかし[〜#〜]同期はずっと良く見えるでしょう。
_ //player2.playVideo();
});
}
else
player1.playVideo();
}
else if (event.data == YT.PlayerState.PAUSED ) {
if(/*!preloading1 &&*/ !preloading2)
player1.pauseVideo();
}
else if (event.data == YT.PlayerState.BUFFERING ) {
if(!preloading2)
{
player1.pauseVideo();
//player1.seekTo(... // Correct the offset here
}
}
else if (event.data == YT.PlayerState.CUED ) {
if(!preloading2)
player1.pauseVideo();
}
else if (event.data == YT.PlayerState.ENDED ) {
player1.stopVideo();
}
}
</script>
</body>
</html>
_
このコードではビューがカウントされない場合があることに注意してください。
説明なしでコードが必要な場合は、ここにアクセスできます: http://jsfiddle.net/QtBlueWaffle/r8gvX/1/
2016年更新ライブプレビュー
お役に立てれば。