189 votes

changer la source de la balise vidéo html5

J'essaie de créer un lecteur vidéo qui fonctionne partout. Pour l'instant, j'ai opté pour :

<video>
    <source src="video.mp4"></source>
    <source src="video.ogv"></source>
    <object data="flowplayer.swf" type="application/x-shockwave-flash">
        <param name="movie" value="flowplayer.swf" />
        <param name="flashvars" value='config={"clip":"video.mp4"}' />
    </object>
</video>

(comme on le voit sur plusieurs sites, par exemple vidéo pour tous ) jusqu'à présent, tout va bien.

Mais maintenant, je veux aussi une sorte de liste de lecture/menu avec le lecteur vidéo, à partir duquel je peux sélectionner d'autres vidéos. Celles-ci doivent s'ouvrir immédiatement dans mon lecteur. Je vais donc devoir "changer dynamiquement la source de la vidéo" (comme vu sur dev.opera.com/articles/tout ce dont vous avez besoin pour savoir-html5-video-audio/ - section "Regardons un autre film") avec Javascript. Oublions la partie Flash player (et donc IE) pour l'instant, j'essaierai de m'en occuper plus tard.

Donc mon JS pour changer le <source> devrait être quelque chose comme :

<script>
function loadAnotherVideo() {
    var video = document.getElementsByTagName('video')[0];
    var sources = video.getElementsByTagName('source');
    sources[0].src = 'video2.mp4';
    sources[1].src = 'video2.ogv';
    video.load();
}
</script>

Le problème est que cela ne fonctionne pas dans tous les navigateurs. En particulier, dans Firefox, il y a une belle page où vous pouvez observer le problème que je rencontre : http://www.w3.org/2010/05/video/mediaevents.html

Dès que je déclenche la load() (dans Firefox, attention), le lecteur vidéo meurt.

Maintenant j'ai découvert que lorsque je n'utilise pas de multiples <source> mais une seule src au sein de l'élément <video> tag, le tout fait fonctionnent dans Firefox.

Donc mon plan est de juste utiliser ça src et déterminer le fichier approprié en utilisant l'attribut canPlayType() fonction.

Est-ce que je m'y prends mal ou est-ce que je complique les choses ?

0 votes

Ça me semble très bien. En quoi le fait de simplifier le balisage est-il "compliqué" ?

0 votes

Le problème est que je me retrouve avec beaucoup de javascript et de distinction de cas. si j'ai raté quelque chose, par exemple s'il y avait un moyen de le faire fonctionner dans firefox AVEC de multiples <source> tags. alors je suppose que ce serait plus facile

0 votes

Avez-vous trouvé la solution pour la partie flash sur ie8 ?

241voto

mattdlockyer Points 2098

J'ai détesté toutes ces réponses car elles étaient trop courtes ou s'appuyaient sur d'autres cadres.

Voici "une" façon vanille JS de le faire, fonctionnant dans Chrome, veuillez tester dans d'autres navigateurs :

http://jsfiddle.net/mattdlockyer/5eCEu/2/

HTML :

<video id="video" width="320" height="240"></video>

JS :

var video = document.getElementById('video');
var source = document.createElement('source');

source.setAttribute('src', 'http://www.tools4movies.com/trailers/1012/Kill%20Bill%20Vol.3.mp4');

video.appendChild(source);
video.play();

setTimeout(function() {  
    video.pause();

    source.setAttribute('src', 'http://www.tools4movies.com/trailers/1012/Despicable%20Me%202.mp4'); 

    video.load();
    video.play();
}, 3000);

13 votes

C'était le plus propre et le plus efficace pour moi.

0 votes

Je n'ai pas réussi à faire en sorte que Chrome joue le jeu avec ça. UNIQUEMENT si je règle l'attribut src de la vidéo sur le chemin d'accès au webm.

4 votes

Le site jouer n'est autorisée que par un geste de l'utilisateur dans certaines politiques de navigateur.

65voto

Modernizr a fonctionné comme un charme pour moi.

Ce que j'ai fait, c'est que je n'ai pas utilisé <source> . D'une manière ou d'une autre, cela a fait foirer les choses, puisque la vidéo n'a fonctionné que la première fois que load() a été appelé. À la place, j'ai utilisé l'attribut source à l'intérieur de la balise vidéo -> <video src="blabla.webm" /> et utilisé Modernizr pour déterminer le format supporté par le navigateur.

<script>
var v = new Array();

v[0] = [
        "videos/video1.webmvp8.webm",
        "videos/video1.theora.ogv",
        "videos/video1.mp4video.mp4"
        ];
v[1] = [
        "videos/video2.webmvp8.webm",
        "videos/video2.theora.ogv",
        "videos/video2.mp4video.mp4"
        ];
v[2] = [
        "videos/video3.webmvp8.webm",
        "videos/video3.theora.ogv",
        "videos/video3.mp4video.mp4"
        ];

function changeVid(n){
    var video = document.getElementById('video');

    if(Modernizr.video && Modernizr.video.webm) {
        video.setAttribute("src", v[n][0]);
    } else if(Modernizr.video && Modernizr.video.ogg) {
        video.setAttribute("src", v[n][1]);
    } else if(Modernizr.video && Modernizr.video.h264) {
        video.setAttribute("src", v[n][2]);
    }

    video.load();
}
</script>

J'espère que cela vous aidera :)

Si vous ne voulez pas utiliser Modernizr vous pouvez toujours utiliser CanPlayType() .

0 votes

Ne voulez-vous pas dire v[n][1] pour le deuxième if (Modernizr.video && Modernizr.video.ogg) est vrai ?

1 votes

Après avoir essayé d'autres méthodes, j'ai essayé cette approche Modernizr et cela a bien fonctionné. Chrome (pour une raison quelconque) n'a pas voulu charger un mp4 dans mon cas, mais a pu charger un webm. Merci @MariusEngenHaugen

0 votes

Heureux d'avoir pu être utile @AdamHey

34voto

greg.kindel Points 978

Votre plan initial me semble parfait. Vous trouverez probablement d'autres bizarreries de navigateur traitant de la gestion dynamique de l'élément <source> comme indiqué ici par la note de spécification W3 :

Modifier dynamiquement un élément source et son attribut lorsque l'élément est déjà inséré dans un élément vidéo ou audio n'aura aucun effet. Pour modifier ce qui est lu, il suffit d'utiliser directement l'attribut src de l'élément multimédia, en faisant éventuellement appel à la méthode canPlayType() pour choisir parmi les ressources disponibles. En général, la manipulation manuelle des éléments sources après l'analyse du document est une approche inutilement [sic] compliquée.

http://dev.w3.org/html5/spec/Overview.html#the-source-element

10voto

Stephen Walcher Points 2066

Au lieu de faire en sorte que le même lecteur vidéo charge de nouveaux fichiers, pourquoi ne pas effacer l'ensemble de la <video> et le recréer. La plupart des navigateurs le chargeront automatiquement si les src sont correctes.

Exemple (avec Prototype ) :

var vid = new Element('video', { 'autoplay': 'autoplay', 'controls': 'controls' });
var src = new Element('source', { 'src': 'video.ogg', 'type': 'video/ogg' });

vid.update(src);
src.insert({ before: new Element('source', { 'src': 'video.mp4', 'type': 'video/mp4' }) });

$('container_div').update(vid);

9 votes

Cela ralentit considérablement le navigateur dans son ensemble, car même après la suppression de la balise vidéo, le navigateur continue de charger les vidéos supprimées jusqu'à la fin.

3 votes

Certains navigateurs (mobiles) ne permettent pas la lecture programmée de médias sans interaction avec l'utilisateur. Comme vous avez déjà eu une interaction avec l'élément, le remplacer par un nouveau vous fera perdre cette capacité.

8voto

Yaur Points 4362

Selon la spécification

Modification dynamique d'un élément source et de son attribut lorsque l'élément élément est déjà inséré dans un élément vidéo ou audio n'aura aucun effet. Pour modifier ce qui est lu, il suffit d'utiliser directement l'attribut src de l'élément media l'élément multimédia, en utilisant éventuellement la méthode canPlayType() pour choisir parmi les ressources disponibles. En général, la manipulation manuelle des éléments sources après que le document a été document a été analysé est une approche inutilement compliquée.

Donc ce que vous essayez de faire n'est apparemment pas censé fonctionner.

0 votes

@greg.kindel J'ai remarqué après avoir posté... mais la raison pour laquelle je n'ai pas remarqué en premier lieu est que votre texte d'introduction est confus. De quel plan original parlons-nous ? Le plan original qui ne fonctionnera pas ou le plan original mis à jour qui suit les conseils que nous avons tous deux publiés ?

0 votes

C'est juste, j'aurais dû citer. Je voulais dire que son plan consistait à "utiliser simplement l'attribut src et déterminer le fichier approprié en utilisant la fonction canPlayType()", ce qui fonctionne.

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