Ответ 1
Ваш проект интересен, поэтому я решил помочь вам. Я никогда не использовал API-интерфейс youtube, но я пробовал кодирование, и это может быть началом для вас.
Итак, вот код, который я пробовал, и, похоже, он работает неплохо, он, безусловно, нуждается в некоторых улучшениях (я не пытался рассчитать смещение между двумя воспроизведенными видео, но позволяя им включать звук, показывает несоответствие, и это звучит законно )
Здесь мы идем:
Начнем с некоторых 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>
iframe > (и видеоплееры) заменят эти <div> .
<div id="player1"></div> <!-- Background video player -->
<div id="player2"></div> <!-- Foreground video player -->
<script>
Этот код загружает код API IFrame Player асинхронно.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
Эта функция создает <iframes> (и игроков YouTube) после загрузки кода API. Обратите внимание на функции обратного вызова: 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
); - Показать игрока.
Вам нужно предварительно загрузить два видео.
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() {
Вот часть кода, который действует странно. Разоружение строки ниже сделает синхронизацию довольно плохим, но если вы ее прокомментируете, вам нужно нажать дважды на кнопке PLAY НО, синхронизация будет выглядеть лучше.
//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 Live Preview
Надеюсь, что это поможет.