html5ビデオタグのソースの変更


138

私はどこでも動作するビデオプレーヤーを構築しようとしています。これまでのところ私は行くでしょう:

<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/articles/everything-you-need-to-know-html5-video-audio/セクション「他の映画で見てみましょう- ")javascriptを使用。とりあえずflashplayer(つまりIE)の部分については忘れましょう。後でそれについて説明します。

<source>タグを変更する私のJS は次のようなものでなければなりません:

<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>タグを使用せず、<video>タグ内のsrc属性を1つだけ使用すると、Firefoxですべてが機能することがわかりました。

したがって、私の計画は、そのsrc属性を使用し、canPlayType()関数を使用して適切なファイルを決定することです。

どういうわけかそれを間違っているのか、それとも複雑なのか


それは私には問題なく聞こえます。マークアップを簡略化するのはどのように「複雑」ですか?
マットボール

問題は、私が多くのJavaScriptとケースの区別に遭遇しているのを見ていることです。複数の<source>タグを付けてFirefoxで機能させる方法があったように、私が何かを見逃した場合 それなら私はそれがより簡単になると思います
sashn

ie8のフラッシュ部分について理解したことはありますか?
Neeraj 2015

@Neerajの最終的なソリューションには、IE8などのフォールバックとしてフラッシュプレーヤーを使用するプラグインvideo.jsが含まれていました。今日も優れたプラグインがあるかもしれません。プラグインを使用しても、この投稿の最初の動機となったload()メソッドに関するfirefoxの問題は解決しませんでした。今日、その問題は長い間修正されているようです。
sashn 2015年

回答:


169

答えが短すぎるか、他のフレームワークに依存しているため、私はこれらすべての答えを嫌っていました。

これは、これを行う「1つの」バニラ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);

11
これは私にとって最もクリーンで効率的でした。
Phil McCarty 14

これでChromeでボールをプレーすることができませんでした。video src属性をwebmパスに設定した場合のみ
Adam Hey

2
プレイ方法は、唯一のいくつかのブラウザポリシーでユーザのジェスチャによって許可されています。
アンソン

別の理由でこれに感謝します!訪問者が1つを選択するまで、どのビデオも表示しないビデオページを設定しようとしています。空のソースタグを使用して動画タグを設定することもできましたが、JavaScriptデバッグコンソールで常にエラーが発生しました。これで、ユーザーが選択するまで「ソース」の追加を保留できることがわかりました。これまでは、CreateElement()を使用してソースを作成し、appendChild()を使用してそれをビデオ要素に追加する必要があることを理解していませんでした。その後の選択では、最初にソース要素が存在するかどうかを確認して、その手順を繰り返さないようにすることができます。
ランディ、

このソリューションは、指定されたコンテンツタイプが正しくても変な動作をする場合でも、ペイロード応答からのコンテンツタイプの問題に直面している場合に適切に機能します。
meDeepakJain

63

Modernizrは私にとって魅力のように機能しました。

私がしたことは、私が使用しなかったこと<source>です。ビデオは初めてload()が呼び出されたときにのみ機能したため、どういうわけかこれは物事を台無しにしました。代わりに、videoタグ内のsource属性-> <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()を使用できます。


(Modernizr.video && Modernizr.video.ogg)がtrueの場合、秒のv [n] [1]を意味するのではないですか?
bergie3000 2013

1
他の方法を試した後、このModernizrアプローチを試したところ、うまくいきました。Chromeは(何らかの理由で)mp4をロードしませんが、webmをロードします。ありがとう@MariusEngenHaugen
Adam Hey


32

あなたの元の計画は私にはうまく聞こえます。<source>W3仕様の注記で示されているように、要素を動的に管理することを処理するブラウザーの癖がさらに見つかるはずです。

要素が既にビデオまたはオーディオ要素に挿入されている場合、ソース要素とその属性を動的に変更しても効果はありません。再生しているものを変更するには、メディア要素のsrc属性を直接使用します。おそらくcanPlayType()メソッドを使用して、利用可能なリソースの中から選択します。一般に、ドキュメントが解析された後にソース要素を手動で操作することは、不必要に複雑なアプローチです。

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


19

私はこの簡単な方法でこれを解決しました

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

10

同じビデオプレーヤーで新しいファイルを読み込む代わりに、<video>要素全体を消去して再作成してみませんか。ほとんどのブラウザは、srcが正しい場合、自動的にロードします。

例(プロトタイプを使用):

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
ビデオタグが削除された後でも、ブラウザーは削除されたビデオを最後までロードするため、ブラウザー全体の速度が大幅に低下します。
Moe Sweet

一部のブラウザー(モバイル)では、ユーザーの操作なしでメディアをプログラムで再生することはできません。また、要素に対して既に操作を行っているため、要素を新しいものに置き換えると、その機能が失われます。
マックスウォーターマン

6

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

6

仕様によると

要素が既にビデオまたはオーディオ要素に挿入されている場合、ソース要素とその属性を動的に変更しても効果はありません。再生しているものを変更するには、メディア要素のsrc属性を直接使用します。おそらくcanPlayType()メソッドを使用して、利用可能なリソースの中から選択します。一般に、ドキュメントが解析された後でソース要素を手動で操作することは、必要以上に複雑なアプローチです。

ですから、あなたがやろうとしていることは明らかに機能するはずではありません。


@ greg.kindel投稿後に気づ​​きましたが、そもそも気付かなかったのは、紹介文がわかりにくいからです。私たちが話している最初の計画は何ですか?機能しない元の元の計画、または両方が投稿したガイダンスに従う更新された元の計画?
Yaur 2013

十分に公正な、私は引用したはずです。私は彼の計画が「機能するsrc属性を使用し、canPlayType()関数を使用して適切なファイルを決定する」ことを意味しました。
greg.kindel 2013年

4

Yaur:あなたがコピーして貼り付けたものは良いアドバイスですが、これはIE9(またはそのことについてはIE8)でさえ、HTML5ビデオ要素のソース要素をエレガントに変更することが不可能であることを意味しません(このソリューションは関係しません)コーディングの習慣が悪いため、video要素全体を置き換える。

JavaScriptを介してHTML5ビデオタグのビデオを変更/切り替える完全なソリューションはここにあり、すべてのHTML5ブラウザー(Firefox、Chrome、Safari、IE9など)でテストされています。

これで問題が解決しない場合、または問題が発生した場合は、お知らせください。


鮮やかさ!これがその方法です。jQueryも必要ありません。リンクされたコードで、次のように置き換えます:mp4Vid.setAttribute( 'src'、 "/pathTo/newVideo.mp4");
Velojet 2016年

3

ビデオソースを動的に変更するためにこれが付属しています。Firefoxで「canplay」イベントが発生しないことがあるので、「loadedmetadata」を追加しました。また、前の動画がある場合は一時停止します...

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

間違いなく私のために働いた修正は、Firefoxはどちらのプロパティを処理していないcanplayにもcanplaythrough及びlodedmetadataニーズがビデオ・ハンドラ:-(に追加(および後で除去)するために
主フリークの

3

これは私の解決策です:

<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

<source />Chrome 14.0.835.202では特にタグを使用するのが難しいことがわかりましたが、FireFoxではうまくいきました。(これは私の知識の欠如かもしれませんが、とにかく別の解決策が役立つかもしれないと思いました。)したがって、私は<video />タグを使用し、ビデオタグ自体にsrc属性を設定するだけになりました。このcanPlayVideo('<mime type>')関数は、特定のブラウザーが入力ビデオを再生できるかどうかを判断するために使用されました。以下はFireFoxとChromeで動作します。

ちなみに、Chromeは「webm」を推奨していますが、FireFoxとChromeはどちらも「ogg」形式を再生しています。他の投稿がFireFoxが最初にoggソースを好むと述べている(つまり<source src="..." type="video/ogg"/>)ために、「ogg」のブラウザサポートのチェックを最初に置いています。しかし、ビデオタグに "src"を設定するときに、コード内の順序によって違いが生じるかどうかはテストしていません(非常に疑っています)。

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

私はこれについてかなり長い間研究しており、同じことをやろうとしているので、これが他の人の役に立つことを願っています。私はcrossbrowsertesting.comを使用していて、文字通りこれを人が知っているほとんどすべてのブラウザでテストしています。現在入手しているソリューションは、Opera、Chrome、Firefox 3.5以降、IE8以降、iPhone 3GS、iPhone 4、iPhone 4s、iPhone 5、iPhone 5s、iPad 1以降、Android 2.3以降、Windows Phone 8で動作します。

動的に変化するソース

ビデオを動的に変更することは非常に困難であり、Flashフォールバックが必要な場合、FlashがFlash変数の動的更新を認識しないため、Flashが更新されるように、DOM /ページからビデオを削除して再度追加する必要があります。JavaScriptを使用して動的に変更する場合は、すべての<source>要素を完全に削除canPlayTypesrc、JavaScriptで設定するbreakreturn、最初にサポートされている動画タイプの後に使用して、フラッシュ変数mp4を動的に更新することを忘れないでください。また、一部のブラウザは、を呼び出さない限り、ソースを変更したことを登録しませんvideo.load().load()あなたが経験していた問題は最初に電話することで修正できると思いますvideo.pause()。ビデオ要素を削除および追加すると、削除されたビデオのバッファリングが続行されるため、ブラウザの速度が低下する可能性がありますが、回避策あります。

クロスブラウザのサポート

実際のクロスブラウザー部分に関しては、Video For Everybodyにもたどり着きました。MediaelementJS Wordpressプラグインをすでに試しましたが、解決するよりもはるかに多くの問題が発生します。問題はWordpressプラグインによるもので、実際のライブラリによるものではないようです。できれば、JavaScriptがなくても機能するものを見つけようとしています。これまでのところ、私が思いついたのはこのプレーンHTMLです。

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

重要なメモ

  • <source>Mac OS Firefoxが最初にMP4を検出した場合、ビデオを再生しようとするのをやめるため、oggを最初に置くことになりました<source>
  • 正しいMIMEタイプは重要です。重要な.ogvファイルはでvideo/oggなく、 video/ogv
  • あなたがHDビデオを持っているなら、私がHD品質のOGGファイルのために見つけた最高のトランスコーダーはFirefoggです
  • この.iphone.mp4ファイルはiPhone 4+用で、H.264ベースライン3ビデオとAACオーディオでMPEG-4のビデオのみを再生します。私がそのフォーマットで見つけた最高のトランスコーダーはHandbrakeです。iPhone&iPod Touchプリセットを使用すると、iPhone 4+で機能しますが、iPhone 3GSを機能させるには、はるかに低い解像度のiPodプリセットを使用する必要がありますvideo.iphone3g.mp4
  • 将来的にはmedia<source>エレメントの属性を使用して、メディアクエリでモバイルデバイスをターゲットにできるようになりますが、現在のところ、古いAppleおよびAndroidデバイスでは十分にサポートされていません。

編集

  • 私はまだVideo For Everybodyを使用していますが、今はFlowPlayerを使用してFlashフォールバックを制御するように移行しました。Flashフォールバックには、制御に使用できる素晴らしいJavaScript APIがあります。

これは、「ビデオクロスブラウザを再生するにはどうすればよいですか?」という質問に対する回答のようです。「この動画の再生リストを設定するにはどうすればよいですか?」という質問ではありません。
クエンティン

@QuentinそもそもGoogleでこの質問を見つけたのはそのためでした。OPは、あらゆる場所で機能するビデオプレーヤーを構築しようとしていると述べました。私も彼の動的な質問に対処するために回答を更新しました。
Alex W

2

私は同様のウェブアプリを持っていますが、そのような問題にはまったく直面していません。私がすることはこのようなものです:

var sources = new Array();

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

次に、ソースを変更したいときに、次のような関数を使用します。

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

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

}

これを行うのは、ユーザーがプレイリストを通り抜けるようにするためですが、userAgentを確認して、適切なファイルをその方法で読み込むことができます。インターネット上の誰もが提案するように複数のソースタグを使用してみましたが、単一のソースタグのsrc属性を操作する方がはるかにクリーンで信頼性が高いことがわかりました。上記のコードはメモリから作成されたため、詳細の一部は見落としているかもしれませんが、一般的な考え方は、適切な場合、JavaScriptを使用してソースタグのsrc属性を動的に変更することです。


1

OGGソースを一番上に移動してみてください。私は、Firefoxがときどき混乱し、プレーヤーが再生したいOGGが最初でないとプレーヤーを停止することに気づきました。

試すだけの価値があります。


1

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

JavaScriptと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>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.