77 votes

La vidéo HTML5 ne tourne pas en boucle

J'ai une vidéo en arrière-plan d'une page Web, et j'essaie de la faire tourner en boucle. Voici le code :

<video autoplay='true' loop='true' muted='true'>
  <source src='/admin/wallpapers/linked/4ebc66e899727777b400003c' type='video/mp4'></source>
</video>

Bien que j'aie demandé à la vidéo de tourner en boucle, elle ne le fait pas. J'ai également essayé de la faire tourner en boucle avec la fonction onended (conformément à ce fil de discussion sur l'assistance Mozilla J'ai également essayé ce bout de jQuery). Rien n'a fonctionné jusqu'à présent. Est-ce un problème avec Chrome, ou avec mon code ?

Edita:

J'ai vérifié les événements du réseau et le HEAD d'une copie de travail ( http://fhsclock-labs.heroku.com/no-violence ) par rapport à l'application que j'essaie de faire fonctionner. La différence est que la copie de travail sert la vidéo à partir d'un actif statique sur Heroku (via Varnish, apparemment), tandis que la mienne sert à partir de GridFS (MongoDB).

L'onglet Réseau de l'inspecteur de Chrome montre que dans mon application, la vidéo est demandée trois fois. La première fois, l'état est "en attente", la deuxième est "annulée" et la dernière est 200 OK. La copie de travail ne montre que deux demandes, l'une avec un statut "en attente" et l'autre avec un contenu partiel de 206. Cependant, une fois que la vidéo a été lue, la demande devient "annulée" et une autre demande est faite pour cette vidéo. Dans mon application, cela ne se produit pas.

En ce qui concerne le type, dans mon application, deux sont "indéfinis" et l'autre "vidéo/mp4" (ce qu'il est censé être). Dans l'application fonctionnelle, toutes les demandes sont "video/mp4".

De plus, je reçois Resource interpreted as Other but transferred with MIME type undefined. des avertissements dans la Console.

Je ne sais pas vraiment par où commencer. Je pense que le problème se situe du côté du serveur, car le fait de servir le fichier en tant que ressource statique fonctionne bien. Il se peut que le serveur n'envoie pas le bon type de contenu. Cela pourrait être un problème avec GridFS. Je n'en sais rien.

En tout cas, la source est aquí . Nous apprécions tout ce que vous pouvez nous dire à ce sujet.

140voto

afri Points 538

Ah, je viens de tomber sur ce problème exact.

Il s'avère que le bouclage (ou tout de recherche, d'ailleurs) dans <video> sur Chrome ne fonctionne que si le fichier vidéo a été servi par un serveur qui comprend les éléments suivants demandes de contenu partiel . c'est-à-dire que le serveur doit honorer les requêtes qui contiennent un en-tête "Range" avec une réponse 206 "Partial Content". C'est même le cas si la vidéo est suffisamment petite pour être entièrement mise en mémoire tampon par Chrome, et qu'il n'y a plus d'allers-retours entre les serveurs : si votre serveur n'a pas honoré la demande Range de Chrome la première fois, la vidéo ne pourra pas être mise en boucle ou recherchée.

Donc oui, un problème avec GridFS, bien que l'on puisse dire que Chrome devrait être plus indulgent.

3 votes

J'ai eu le même problème. J'utilise nginx, j'ai donc dû purger nginx, installer à partir des sources avec nginx.org/fr/docs/http/ngx_http_mp4_module.html et redémarrez tout.

0 votes

La même chose se produit avec le serveur php intégré (dans mon environnement de développement).

3 votes

Même problème avec le serveur d'exécution Django 1.7.10.

23voto

d2vid Points 585

La solution de contournement la plus simple :

$('video').on('ended', function () {
  this.load();
  this.play();
});

El 'ended' L'événement se déclenche lorsque la vidéo atteint la fin, video.load() réinitialise la vidéo au début, et video.play() lance la lecture immédiatement après le chargement.

Cela fonctionne bien avec Amazon S3 où vous n'avez pas autant de contrôle sur les réponses du serveur, et permet également de contourner les problèmes de Firefox liés à video.currentTime ne peut pas être réglé si une vidéo n'a pas ses métadonnées de longueur.

Un javascript similaire sans jQuery :

document.getElementsByTagName('video')[0].onended = function () {
  this.load();
  this.play();
};

6voto

John Points 1484

Il semble que ce problème ait existé dans le passé, il y a au moins deux bugs fermés à ce sujet, mais les deux indiquent qu'il a été corrigé :

http://code.google.com/p/chromium/issues/detail?id=39683

http://code.google.com/p/chromium/issues/detail?id=18846

Étant donné que Chrome et Safari utilisent tous deux des navigateurs basés sur webkit, vous pourriez être en mesure d'utiliser certaines de ces solutions de contournement : http://blog.millermedeiros.com/2011/03/html5-video-issues-on-the-ipad-and-how-to-solve-them/

function restartVideo(){
vid.currentTime = 0.1; //setting to zero breaks iOS 3.2, the value won't update, values smaller than 0.1 was causing bug as well.
vid.play();
}

//loop video
vid.addEventListener('ended', restartVideo, false);

0 votes

@Ramesh, pourriez-vous jeter un coup d'œil à cette question également ? stackoverflow.com/questions/31634678/ Concerne les données vidéo

5voto

srussking Points 297

Au cas où aucune des réponses ci-dessus ne vous aiderait, assurez-vous que votre inspecteur ne fonctionne pas avec l'option Désactiver le cache cochée. Comme Chrome récupère la vidéo dans le cache, elle ne fonctionnera qu'une fois. J'ai débogué cela pendant 20 minutes avant de réaliser que c'était la cause. Pour référence et pour savoir que je ne suis pas le seul à le faire le rapport de bogue de chromium de quelqu'un d'autre .

3voto

WhoKnows Points 90

Ma situation :

J'ai exactement le même problème, cependant changer l'en-tête du message de réponse seul n'a pas fonctionné. Pas de boucle, de relecture ou de recherche. De même, un arrêt pur et simple ne fonctionne pas, mais cela pourrait être dû à ma configuration.

Réponse :

Selon certains sites (je ne les trouve plus), il est également possible de déclencher la méthode load() juste après la fin de la vidéo, et avant que la suivante ne soit censée commencer. Cela devrait recharger la source et permettre à l'élément vidéo/audio de fonctionner à nouveau.

@john

Veuillez noter que vos réponses/liens sont des bogues normaux, et ne sont pas axés sur ce problème. L'utilisation d'un serveur/webserver est à l'origine de ce problème. Alors que les bogues que ces liens décrivent sont d'un autre type. C'est aussi pourquoi la réponse ne fonctionne pas.

J'espère que cela vous aidera, je suis toujours à la recherche d'une solution.

0 votes

En fait, j'ai fini par le servir à partir d'une source différente : avant, j'utilisais GridFS de MongoDB. Je pense que le problème provenait du fait que le fichier n'était pas correctement servi. J'utilise maintenant Amazon S3 sans problème.

0 votes

Ohh nous l'avons résolu aussi, mais je ne peux pas vraiment l'expliquer. Il semble que les demandes de plage ne fonctionnaient pas pour le service, donc nous avons ajouté ces lignes à notre méthode qui télécharge les fichiers. response.Headers.Add("Accept-Ranges", "bytes") ; response.Headers.Add("Content-Range", rangeValue.Replace("=", " ") + (resource. Value.Length - 1).ToString() + "/" + resource.Value.Length.ToString()) ; response.StatusCode = HttpStatusCode.PartialContent ; Ceci active les requêtes de plage, et manipule l'en-tête pour faire savoir au serveur etc. qu'il s'agit d'une requête de plage. code 206 au lieu de 200.

0 votes

Response.Headers.Add("Accept-Ranges", "bytes") ; response.Headers.Add("Content-Range", rangeValue.Replace("=", " ") + (resource.Value.Length - 1).ToString() + "/" + resource.Value.Length.ToString()) ; response.StatusCode = HttpStatusCode.PartialContent ;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X