mengubah sumber pada tag video html5


144

Saya mencoba membuat pemutar video, yang berfungsi di mana saja. sejauh ini saya akan pergi dengan:

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

(seperti yang terlihat di beberapa situs, misalnya video untuk semua orang ) sejauh ini, sangat bagus.

tetapi sekarang saya juga ingin semacam playlist / menu bersama dengan pemutar video, dari mana saya dapat memilih video lain. itu harus segera dibuka di dalam pemutar saya. jadi saya harus "mengubah sumber video secara dinamis" (seperti yang terlihat di dev.opera.com/articles/everything-you-need-to-know-html5-video-audio/ - bagian "Mari kita lihat film lain ") dengan javascript. mari kita lupakan tentang bagian flashplayer (dan juga IE) untuk saat ini, saya akan mencoba mengatasinya nanti.

jadi JS saya untuk mengubah <source>tag harus seperti ini:

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

Masalahnya, ini tidak berfungsi di semua browser. yaitu, firefox = O ada halaman yang bagus, di mana Anda dapat mengamati masalah yang saya alami: http://www.w3.org/2010/05/video/mediaevents.html

segera setelah saya memicu metode load () (di firefox, ingatlah), pemutar video mati.

sekarang saya telah menemukan bahwa ketika saya tidak menggunakan beberapa <source>tag, tetapi hanya satu atribut src di dalam <video>tag, semuanya TIDAK berfungsi di firefox.

jadi rencana saya adalah hanya menggunakan atribut src itu dan menentukan file yang sesuai menggunakan fungsi canPlayType () .

Apakah saya salah melakukannya atau memperumit hal-hal ??


Kedengarannya bagus untukku. Bagaimana cara "menyulitkan" untuk menyederhanakan markup?
Matt Ball

masalahnya adalah saya melihat diri saya mengalami banyak javascript dan perbedaan kasus. jika mungkin saya melewatkan sesuatu, seperti ada cara untuk membuatnya berfungsi di firefox DENGAN banyak <source>tag. maka saya kira itu akan lebih mudah
sashn

apakah Anda pernah mengetahui tentang bagian flash di ie8?
Neeraj

@Neeraj solusi terakhir melibatkan plugin video.js yang menggunakan flash player sebagai cadangan untuk IE8 dan sejenisnya. mungkin ada plugin yang lebih baik hari ini. Menggunakan plugin juga tidak membantu dengan masalah firefox terkait metode load (), yang merupakan motivasi awal untuk posting ini. hari ini, tampaknya masalah itu telah lama diperbaiki.
sashn

Jawaban:


173

Saya benci semua jawaban ini karena terlalu pendek atau bergantung pada kerangka kerja lain.

Berikut adalah cara "satu" vanilla JS untuk melakukan ini, bekerja di Chrome, harap uji di browser lain:

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

11
Ini adalah yang terbersih dan paling efisien bagi saya.
Phil McCarty

Saya tidak bisa mendapatkan Chrome untuk bermain bola dengan ini. HANYA jika saya menyetel atribut video src ke jalur webm
Adam Hey

2
The bermain Metode hanya diperbolehkan oleh pengguna gerakan di beberapa kebijakan browser.
Anson

Saya sangat menghargai ini karena alasan lain! Saya telah mencoba membuat halaman video yang tidak menampilkan video APA PUN sampai pengunjung memilihnya. Saya dapat menyiapkan tag video dengan tag sumber kosong, tetapi itu akan selalu menghasilkan kegagalan pada konsol debug javascript. Sekarang saya tahu saya dapat menunda menambahkan 'sumber' sampai pengguna memilihnya. Sampai sekarang, saya tidak mengerti bahwa saya perlu menggunakan CreateElement () untuk membuat sumber, dan kemudian menggunakan appendChild () untuk menambahkannya ke elemen video! Untuk pemilihan selanjutnya, saya dapat memeriksa terlebih dahulu untuk melihat apakah elemen sumber ada jadi saya tidak mengulangi langkah itu.
Randy

Solusi ini berfungsi dengan baik jika ada yang menghadapi masalah dengan jenis konten dari respons muatan meskipun jenis konten yang ditentukan benar tetapi masih berperilaku aneh.
sayaDeepakJain

63

Modernizr bekerja seperti pesona bagi saya.

Apa yang saya lakukan adalah yang tidak saya gunakan <source>. Entah bagaimana ini mengacaukan segalanya, karena video hanya berfungsi saat pertama kali load () dipanggil. Sebagai gantinya saya menggunakan atribut sumber di dalam tag video -> <video src="blabla.webm" />dan menggunakan Modernizr untuk menentukan format apa yang didukung browser.

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

Semoga ini bisa membantu Anda :)

Jika Anda tidak ingin menggunakan Modernizr , Anda selalu dapat menggunakan CanPlayType () .


Tidakkah Anda bermaksud v [n] [1] untuk yang kedua jika (Modernizr.video && Modernizr.video.ogg) benar?
bergie3000

1
Setelah mencoba metode lain, saya mencoba pendekatan Modernizr ini dan berhasil dengan baik. Chrome (untuk beberapa alasan) tidak akan memuat mp4 dalam kasus saya, tetapi akan memuat webm. Terima kasih @MariusEngenHaugen
Adam Hai

Senang saya bisa melayani @AdamHey
Marius Engen Haugen

33

Rencana awal Anda terdengar bagus bagi saya. Anda mungkin akan menemukan lebih banyak kebiasaan browser yang berurusan dengan pengelolaan <source>elemen secara dinamis , seperti yang ditunjukkan di sini oleh catatan spesifikasi W3:

Mengubah elemen sumber dan atributnya secara dinamis saat elemen tersebut sudah dimasukkan ke dalam elemen video atau audio tidak akan berpengaruh. Untuk mengubah apa yang sedang diputar, cukup gunakan atribut src pada elemen media secara langsung, kemungkinan memanfaatkan metode canPlayType () untuk memilih dari antara sumber daya yang tersedia. Umumnya, memanipulasi elemen sumber secara manual setelah dokumen diurai adalah pendekatan yang rumit dan tidak perlu.

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


21

Saya menyelesaikan ini dengan metode sederhana ini

function changeSource(url) {
   var video = document.getElementById('video');
   video.src = url;
   video.play();
}

10

Alih-alih mendapatkan pemutar video yang sama untuk memuat file baru, mengapa tidak menghapus seluruh <video>elemen dan membuatnya kembali. Kebanyakan browser akan secara otomatis memuatnya jika src benar.

Contoh (menggunakan Prototipe ):

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
Itu secara signifikan memperlambat browser secara keseluruhan karena bahkan setelah tag video dihapus, browser masih memuat video yang dihapus sampai akhir.
Moe Sweet

1
Beberapa browser (seluler) tidak mengizinkan Anda memutar media secara terprogram tanpa interaksi pengguna, dan karena Anda sudah memiliki interaksi pada elemen, menggantinya dengan yang baru akan kehilangan kemampuan itu.
Max Waterman

6

Menurut spesifikasi

Memodifikasi elemen sumber dan atributnya secara dinamis saat elemen tersebut telah dimasukkan ke dalam elemen video atau audio tidak akan berpengaruh. Untuk mengubah apa yang sedang diputar, cukup gunakan atribut src pada elemen media secara langsung, kemungkinan memanfaatkan metode canPlayType () untuk memilih dari antara sumber daya yang tersedia. Umumnya, memanipulasi elemen sumber secara manual setelah dokumen diurai adalah pendekatan yang terlalu rumit.

Jadi apa yang Anda coba lakukan ternyata tidak seharusnya berhasil.


@ greg.kindel Saya perhatikan setelah saya memposting ... tetapi alasan pertama saya tidak memperhatikan adalah karena teks intro Anda membingungkan. Rencana awal mana yang sedang kita bicarakan? Paket asli asli yang tidak berfungsi atau paket asli yang diperbarui yang mengikuti panduan yang kami posting berdua?
Yaur

cukup adil, saya seharusnya mengutip. Maksud saya rencananya untuk "hanya menggunakan atribut src itu dan menentukan file yang sesuai menggunakan fungsi canPlayType ()" yang berfungsi.
greg.kindel

5

Cukup letakkan div dan perbarui konten ...

<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

Yaur: Meskipun apa yang telah Anda salin dan tempel adalah saran yang bagus, ini tidak berarti bahwa tidak mungkin mengubah elemen sumber elemen video HTML5 dengan elegan, bahkan di IE9 (atau IE8 dalam hal ini). (Solusi ini TIDAK melibatkan mengganti seluruh elemen video, karena ini adalah praktik pengkodean yang buruk).

Solusi lengkap untuk mengubah / mengganti video dalam tag video HTML5 melalui javascript dapat ditemukan di sini dan diuji di semua browser HTML5 (Firefox, Chrome, Safari, IE9, dll).

Jika ini membantu, atau jika Anda mengalami masalah, beri tahu saya.


Cemerlang! Inilah cara melakukannya. Anda bahkan tidak membutuhkan jQuery; dalam kode yang ditautkan, gantikan: mp4Vid.setAttribute ('src', "/pathTo/newVideo.mp4");
Velojet

3

Saya datang dengan ini untuk mengubah sumber video secara dinamis. Acara "canplay" terkadang tidak aktif di Firefox, jadi saya telah menambahkan "metadata yang dimuat". Juga saya jeda video sebelumnya jika ada ...

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();
};

Perbaikannya, pasti berhasil untuk saya, firefox tidak menangani properti canplayjuga canplaythroughdan tidak lodedmetadataperlu ditambahkan (dan dihapus nanti) ke penangan video :-(
Lord of freaks

3

Ini solusi saya:

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

2

Menggunakan <source />tag terbukti sulit bagi saya khususnya di Chrome 14.0.835.202, meskipun berfungsi dengan baik untuk saya di FireFox. (Ini mungkin karena kurangnya pengetahuan saya, tetapi saya pikir solusi alternatif mungkin berguna.) Jadi, saya akhirnya hanya menggunakan <video />tag dan menyetel atribut src tepat di tag video itu sendiri. The canPlayVideo('<mime type>')Fungsi digunakan untuk menentukan apakah atau tidak browser tertentu bisa memutar video masukan. Berikut ini bekerja di FireFox dan Chrome.

Kebetulan, baik FireFox dan Chrome memainkan format "ogg", meskipun Chrome merekomendasikan "webm". Saya memberikan centang untuk dukungan browser "ogg" terlebih dahulu hanya karena posting lain telah menyebutkan bahwa FireFox lebih memilih sumber ogg terlebih dahulu (yaitu <source src="..." type="video/ogg"/>). Namun, saya belum menguji (dan sangat meragukan) apakah urutan kode membuat perbedaan sama sekali saat menyetel "src" pada tag video.

HTML

<body onload="setupVideo();">
    <video id="media" controls="true" preload="auto" src="">
    </video>
</body>

JavaScript

function setupVideo() {
       // You will probably get your video name differently
       var videoName = "http://video-js.zencoder.com/oceans-clip.mp4";

       // Get all of the uri's we support
       var indexOfExtension = videoName.lastIndexOf(".");
       //window.alert("found index of extension " + indexOfExtension);
       var extension = videoName.substr(indexOfExtension, videoName.length - indexOfExtension);
       //window.alert("extension is " + extension);
       var ogguri = encodeURI(videoName.replace(extension, ".ogv"));
       var webmuri = encodeURI(videoName.replace(extension, ".webm"));
       var mp4uri = encodeURI(videoName.replace(extension, ".mp4"));
       //window.alert(" URI is " + webmuri);


       // Get the video element
       var v = document.getElementById("media");
       window.alert(" media is " + v);

       // Test for support
       if (v.canPlayType("video/ogg")) {
            v.setAttribute("src", ogguri);
           //window.alert("can play ogg");
       }
       else if (v.canPlayType("video/webm")) {
           v.setAttribute("src", webmuri);
           //window.alert("can play webm");
       }
       else if (v.canPlayType("video/mp4")) {
           v.setAttribute("src", mp4uri);
           //window.alert("can play mp4");
       }
       else {
           window.alert("Can't play anything");
       }

      v.load();
      v.play();
  }

2

Saya telah meneliti ini cukup lama dan saya mencoba melakukan hal yang sama, jadi semoga ini akan membantu orang lain. Saya telah menggunakan crossbrowsertesting.com dan benar-benar menguji ini di hampir setiap browser yang dikenal manusia. Solusi yang saya dapatkan saat ini berfungsi di Opera, Chrome, Firefox 3.5+, IE8 +, iPhone 3GS, iPhone 4, iPhone 4s, iPhone 5, iPhone 5s, iPad 1+, Android 2.3+, Windows Phone 8.

Mengubah Sumber Secara Dinamis

Mengubah video secara dinamis sangat sulit, dan jika Anda menginginkan penggantian Flash, Anda harus menghapus video dari DOM / laman dan menambahkannya kembali sehingga Flash akan diperbarui karena Flash tidak akan mengenali pembaruan dinamis untuk Flash vars. Jika Anda akan menggunakan JavaScript untuk mengubahnya secara dinamis, saya akan menghapus semua <source>elemen sepenuhnya dan hanya menggunakan canPlayTypeuntuk mengatur srcdi JavaScript dan breakatau returnsetelah jenis video pertama yang didukung dan jangan lupa untuk memperbarui flash var mp4 secara dinamis. Selain itu, beberapa browser tidak akan mendaftar bahwa Anda mengubah sumber kecuali Anda memanggil video.load(). Saya yakin masalah dengan.load() Anda alami dapat diperbaiki dengan menelepon terlebih dahuluvideo.pause(). Menghapus dan menambahkan elemen video dapat memperlambat browser karena terus menyangga video yang dihapus, tetapi ada solusinya .

Dukungan Lintas Browser

Sejauh bagian lintas-browser yang sebenarnya, saya juga sampai di Video For Everybody . Saya sudah mencoba plugin MediaelementJS Wordpress, yang ternyata menyebabkan lebih banyak masalah daripada yang diselesaikan. Saya menduga masalahnya adalah karena plugin Wordpress dan bukan perpustakaan yang sebenarnya. Saya mencoba menemukan sesuatu yang berfungsi tanpa JavaScript, jika memungkinkan. Sejauh ini, yang saya dapatkan adalah HTML biasa ini:

<video width="300" height="150" controls="controls" poster="http://sandbox.thewikies.com/vfe-generator/images/big-buck-bunny_poster.jpg" class="responsive">
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.ogv" type="video/ogg" />
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" type="video/mp4" />
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.webm" type="video/webm" />
<source src="http://alex-watson.net/wp-content/uploads/2014/07/big_buck_bunny.iphone.mp4" type="video/mp4" />
<source src="http://alex-watson.net/wp-content/uploads/2014/07/big_buck_bunny.iphone3g.mp4" type="video/mp4" />
<object type="application/x-shockwave-flash" data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" width="561" height="297">
    <param name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" />
    <param name="allowFullScreen" value="true" />
    <param name="wmode" value="transparent" />
    <param name="flashVars" value="config={'playlist':['http://sandbox.thewikies.com/vfe-generator/images/big-buck-bunny_poster.jpg',{'url':'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4','autoPlay':false}]}" />
    <img alt="No Video" src="http://sandbox.thewikies.com/vfe-generator/images/big-buck-bunny_poster.jpg" width="561" height="297" title="No video playback capabilities, please download the video below" />
</object>
<strong>Download video:</strong>  <a href="video.mp4">MP4 format</a> | <a href="video.ogv">Ogg format</a> | <a href="video.webm">WebM format</a>
</video>

Catatan penting :

  • Akhirnya menempatkan ogg sebagai yang pertama <source>karena Mac OS Firefox berhenti mencoba memutar video jika menemukan MP4 sebagai yang pertama <source>.
  • Jenis MIME yang benar adalah file .ogv yang penting video/ogg, bukan video/ogv
  • Jika Anda memiliki video HD, transcoder terbaik yang pernah saya temukan untuk file OGG kualitas HD adalah Firefogg
  • The .iphone.mp4file untuk iPhone 4 + yang akan hanya memutar video yang MPEG-4 dengan H.264 Baseline 3 Video dan audio AAC. Transcoder terbaik yang saya temukan untuk format itu adalah Handbrake, menggunakan preset iPhone & iPod Touch akan berfungsi di iPhone 4+, tetapi agar iPhone 3GS berfungsi, Anda perlu menggunakan preset iPod yang memiliki resolusi jauh lebih rendah yang saya tambahkan sebagai video.iphone3g.mp4.
  • Di masa mendatang kami akan dapat menggunakan mediaatribut pada <source>elemen untuk menargetkan perangkat seluler dengan kueri media, tetapi saat ini perangkat Apple dan Android yang lebih lama tidak mendukungnya dengan cukup baik.

Edit :

  • Saya masih menggunakan Video For Everybody tetapi sekarang saya telah beralih menggunakan FlowPlayer, untuk mengontrol fallback Flash, yang memiliki API JavaScript mengagumkan yang dapat digunakan untuk mengontrolnya.

Tampaknya ini adalah jawaban untuk pertanyaan "Bagaimana cara memutar video lintas browser?" dan bukan pertanyaan ini, yaitu "Bagaimana cara menyiapkan playlist untuk video saya?".
Quentin

@Quentin Awalnya, karena itulah cara saya menemukan pertanyaan ini melalui Google dan OP mengatakan dia mencoba membuat pemutar video yang berfungsi di mana saja. Saya memperbarui jawaban untuk menjawab pertanyaan dinamisnya juga.
Alex W

2

Saya memiliki aplikasi web yang serupa dan sama sekali tidak menghadapi masalah seperti itu. Apa yang saya lakukan adalah seperti ini:

var sources = new Array();

sources[0] = /path/to/file.mp4
sources[1] = /path/to/another/file.ogg
etc..

kemudian ketika saya ingin mengubah sumber saya memiliki fungsi yang melakukan sesuatu seperti ini:

this.loadTrack = function(track){
var mediaSource = document.getElementsByTagName('source')[0];
mediaSource.src = sources[track];

    var player = document.getElementsByTagName('video')[0];
    player.load();

}

Saya melakukan ini agar pengguna dapat menelusuri daftar putar, tetapi Anda dapat memeriksa userAgent dan kemudian memuat file yang sesuai dengan cara itu. Saya mencoba menggunakan beberapa tag sumber seperti yang disarankan semua orang di internet, tetapi saya merasa jauh lebih bersih, dan jauh lebih dapat diandalkan untuk memanipulasi atribut src dari satu tag sumber. Kode di atas ditulis dari memori, jadi saya mungkin telah mengabaikan beberapa detail hte, tetapi ide umumnya adalah mengubah atribut src secara dinamis dari tag sumber menggunakan javascript, jika sesuai.


1

Coba pindahkan sumber OGG ke atas. Saya perhatikan Firefox terkadang menjadi bingung dan menghentikan pemutar ketika yang ingin dimainkannya, OGG, bukan yang pertama.

Patut dicoba.


1

Cara lain yang bisa Anda lakukan di Jquery.

HTML

<video id="videoclip" controls="controls" poster="" title="Video title">
    <source id="mp4video" src="video/bigbunny.mp4" type="video/mp4"  />
</video>

<div class="list-item">
     <ul>
         <li class="item" data-video = "video/bigbunny.mp4"><a href="javascript:void(0)">Big Bunny.</a></li>
     </ul>
</div>

Jquery

$(".list-item").find(".item").on("click", function() {
        let videoData = $(this).data("video");
        let videoSource = $("#videoclip").find("#mp4video");
        videoSource.attr("src", videoData);
        let autoplayVideo = $("#videoclip").get(0);
        autoplayVideo.load();
        autoplayVideo.play();
    });

0

Menggunakan JavaScript dan jQuery:

<script src="js/jquery.js"></script>
...
<video id="vid" width="1280" height="720" src="v/myvideo01.mp4" controls autoplay></video>
...
function chVid(vid) {
    $("#vid").attr("src",vid);
}
...
<div onclick="chVid('v/myvideo02.mp4')">See my video #2!</div>
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.