изменение источника на видео тег HTML5 - PullRequest
119 голосов
/ 08 марта 2011

Я пытаюсь создать видеоплеер, который работает везде.пока я буду идти с:

<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>

(как видно на нескольких сайтах, например видео для всех ), пока все хорошо.

нотеперь я также хочу какой-нибудь плейлист / меню вместе с видеоплеером, из которого я могу выбирать другие видео.они должны быть сразу открыты в моем плеере.так что мне придется «динамически менять источник видео» (как видно на dev.opera.com / article / все, что вам нужно знать html5-video-audio / - раздел«Давайте посмотрим на другой фильм») с javascript.давайте пока что забудем о flashplayer (и, следовательно, IE), я попытаюсь разобраться с этим позже.

, поэтому мой JS для изменения тегов <source> должен выглядеть примерно так:

<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>

Проблема в том, что это работает не во всех браузерах.а именно, firefox = O, есть хорошая страница, где вы можете наблюдать за проблемой, с которой я сталкиваюсь: http://www.w3.org/2010/05/video/mediaevents.html

, как только я запускаю метод load () (заметьте, в firefox),видео проигрыватель умирает.

Теперь я обнаружил, что когда я не использую несколько тегов <source>, а вместо одного атрибута src внутри тега <video>, все это работает в Firefox.

поэтому я планирую просто использовать этот атрибут src и определить соответствующий файл с помощью функции canPlayType () .

я что-то делаю неправильно или усложняю вещи ??

Ответы [ 15 ]

137 голосов
/ 27 августа 2013

Я ненавидел все эти ответы, потому что они были слишком короткими или полагались на другие структуры.

Вот "один" ванильный JS способ сделать это, работая в Chrome, пожалуйста, проверьте в других браузерах:

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);
63 голосов
/ 21 марта 2011

Modernizr работал для меня как шарм.

Что я сделал, так это то, что не использовал <source>.Каким-то образом это все испортило, так как видео работало только при первом вызове load ().Вместо этого я использовал атрибут источника внутри тега video -> <video src="blabla.webm" /> и использовал Modernizr , чтобы определить, какой формат поддерживает браузер.

<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>

Надеюсь, это поможет вам:)

Если вы не хотите использовать Modernizr , вы всегда можете использовать CanPlayType () .

32 голосов
/ 05 декабря 2011

Ваш оригинальный план звучит хорошо для меня. Вы, вероятно, найдете больше особенностей браузера, связанных с динамическим управлением элементами <source>, как указано здесь в примечании к спецификации W3:

Динамическое изменение элемента источника и его атрибута, когда элемент уже вставлен в элемент видео или аудио, не будет иметь никакого эффекта. Чтобы изменить то, что воспроизводится, просто используйте атрибут src на медиа-элементе напрямую, возможно, используя метод canPlayType () для выбора среди доступных ресурсов. Как правило, манипулирование исходными элементами вручную после разбора документа является излишне сложным подходом.

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

16 голосов
/ 18 февраля 2015

Я решил это с помощью этого простого метода

function changeSource(url) {
   var video = document.getElementById('video');
   video.src = url;
   video.play();
}
10 голосов
/ 21 марта 2011

Вместо того чтобы заставить тот же видеоплеер загружать новые файлы, почему бы не стереть весь элемент <video> и воссоздать его. Большинство браузеров автоматически загрузят его, если src верны.

Пример (с использованием 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);
6 голосов
/ 05 июня 2012

Согласно спецификации

Динамическое изменение исходного элемента и его атрибута, когда элемент уже вставлен в видео или аудио элемент не будет иметь эффект. Чтобы изменить то, что играет, просто используйте атрибут src на медиа-элемент напрямую, возможно используя canPlayType () метод, чтобы выбрать из доступных ресурсов. В общем-то, манипулирование исходными элементами вручную после того, как документ был анализ - это неоправданно сложный подход.

Так что то, что вы пытаетесь сделать, явно не должно работать.

5 голосов
/ 25 ноября 2014

Просто поставьте div и обновите содержимое ...

<script>
function setvideo(src) {
    document.getElementById('div_video').innerHTML = '<video autoplay controls id="video_ctrl" style="height: 100px; width: 100px;"><source src="'+src+'" type="video/mp4"></video>';
    document.getElementById('video_ctrl').play();
}
</script>
<button onClick="setvideo('video1.mp4');">Video1</button>
<div id="div_video"> </div>
4 голосов
/ 25 сентября 2012

Яур: Хотя то, что вы скопировали и вставили, является хорошим советом, это не означает, что невозможно элегантно изменить исходный элемент видеоэлемента HTML5, даже в IE9 (или IE8 в этом отношении). (Это решениеНЕ включает в себя замену всего видеоэлемента, так как это плохая практика кодирования).

Полное решение для изменения / переключения видео в тегах HTML5 с помощью javascript можно найти здесь и протестированово всех браузерах HTML5 (Firefox, Chrome, Safari, IE9 и т. д.).

Если это поможет, или если у вас возникли проблемы, пожалуйста, дайте мне знать.

3 голосов
/ 02 декабря 2017

Это мое решение:

<video id="playVideo" width="680" height="400" controls="controls">
    <source id="sourceVideo" src="{{video.videoHigh}}" type="video/mp4">
</video>
    <br />
<button class="btn btn-warning" id="{{video.videoHigh}}" onclick="changeSource(this)">HD</button>
<button class="btn btn-warning" id="{{video.videoLow}}" onclick="changeSource(this)">Regular</button>

<script type="text/javascript">
    var getVideo = document.getElementById("playVideo");
    var getSource = document.getElementById("sourceVideo");
    function changeSource(vid) {
        var geturl = vid.id;
        getSource .setAttribute("src", geturl);
        getVideo .load()
        getVideo .play();
        getVideo .volume = 0.5;
    }
</script>
3 голосов
/ 19 февраля 2015

Я пришел с этим, чтобы динамически менять источник видео.Событие canplay иногда не запускается в Firefox, поэтому я добавил «Загруженные метаданные».Также я приостанавливаю предыдущее видео, если оно есть ...

var loadVideo = function(movieUrl) {
    console.log('loadVideo()');
    $videoLoading.show();
    var isReady = function (event) {
            console.log('video.isReady(event)', event.type);
            video.removeEventListener('canplay', isReady);
            video.removeEventListener('loadedmetadata', isReady);
            $videoLoading.hide();
            video.currentTime = 0;
            video.play();
        },
        whenPaused = function() {
            console.log('video.whenPaused()');
            video.removeEventListener('pause', whenPaused);
            video.addEventListener('canplay', isReady, false);
            video.addEventListener('loadedmetadata', isReady, false); // Sometimes Firefox don't trigger "canplay" event...
            video.src = movieUrl; // Change actual source
        };

    if (video.src && !video.paused) {
        video.addEventListener('pause', whenPaused, false);
        video.pause();
    }
    else whenPaused();
};
...