Votre projet est plutôt intéressant, c'est pourquoi j'ai décidé d'essayer de vous aider. Je n'ai jamais utilisé l'API youtube, mais j'ai essayé quelques-uns de codage et c'est peut être un début pour vous.
Voici donc le code que j'ai essayé et il semble fonctionner assez bien , il a certainement besoin de quelques améliorations ( je n'ai pas essayé de calculer le décalage entre les deux vidéos, mais de les laisser activer montre l'inadéquation et il semble légitime)
Ici, nous allons :
Nous allons commencer avec quelques bases du html
<!DOCTYPE html>
<html>
<head>
Nous ajoutons un positionnement absolu pour le premier plan de joueur donc il se superpose à la seule lecture de la vidéo d'arrière-plan (pour les tests)
<style>
#player2{position:absolute;left:195px;top:100px;}
</style>
</head>
<body>
jQuery est utilisé ici pour fade in/out, les joueurs (vous allez voir pourquoi ci-dessous), mais vous pouvez utiliser de base de JS
<script src="jquery-1.10.2.min.js"></script>
Les < iframe> (et les lecteurs vidéo) remplacera ces balises < div>.
<div id="player1"></div> <!-- Background video player -->
<div id="player2"></div> <!-- Foreground video player -->
<script>
Ce code charge de l'IFrame Lecteur de code API asynchrone.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
Cette fonction crée l' < iframe> (et YouTube joueurs), d'après le code de l'API de téléchargements. Remarque les fonctions de rappel : onPlayer1Ready et 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;
Alors c'est maintenant la partie intéressante du code. Le principal problème dans votre projet de synchronisation est lié au fait que les vidéos doivent être mis en mémoire tampon avant de les lancer. En fait l'API ne pas fournir tout type intuitionnal fonction pour charger les vidéos (en raison de problèmes de bande passante (côté client et serveur). Nous devons donc obtenir un peu délicate.
Les étapes pour le chargement d'une vidéo sont les suivants:
- Masquer les joueurs pour les prochaines étapes ne sont pas visibles pour l'utilisateur);
- Couper le joueur (
player.mute():Void
);
- Émuler un saut dans la timeline pour démarrer la mise en mémoire tampon (
player.seekTo(seconds:Number, allowSeekAhead:Boolean):Void
);
- Attendre un changement d'état d'événement égale à
YT.PlayerState.PLAYING
;
- Mettre la vidéo en Pause (
player.pauseVideo():Void
);
- Rembobiner la vidéo avec
player.seekTo(seconds:Number, allowSeekAhead:Boolean):Void
;
- Réactiver le joueur (
player.unMute():Void
);
- Montrer le joueur.
Vous avez pour précharger vos deux vidéos.
var preloading1 = false;
var preloading2 = false;
L'API va appeler ces fonctions lors de la vidéo, les joueurs sont prêts.
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
}
Les appels d'API de cette fonction lors de l'arrière-plan de la vidéo du joueur changements d'état.
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
}
}
Les appels d'API de cette fonction lors de l'avant-plan de la vidéo du joueur changements d'état.
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() {
Voici une partie du code qui agit étrangement. Décommentant la ligne ci-dessous feront l'sync assez mauvais,mais si vous en commentaire, vous devez cliquer deux fois sur le bouton de lecture , MAIS la synchronisation sera bien meilleur.
//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>
Notez que les points de vue peuvent ne pas être comptés avec ce code.
Si vous voulez le code sans les explications, vous pouvez aller ici : http://jsfiddle.net/QtBlueWaffle/r8gvX/1/
Espérons que cette aide.