web-dev-qa-db-ja.com

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

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

<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には、私が抱えている問題を観察できるNiceページがあります。 http://www.w3.org/2010/05/video/mediaevents.html

load()メソッドをトリガーすると(Firefoxでは気になります)、ビデオプレーヤーは停止します。

今、複数の<source>タグを使用せず、代わりに<video>タグ内のsrc属性を1つだけ使用すると、すべてがFirefoxで機能することがわかりました。

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

どうにかして間違っているのですか、それとも複雑なのですか?

118
sashn

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

これを行う「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);
137
mattdlockyer

Modernizr は私にとって魅力的でした。

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

63

あなたの元の計画は私には問題ないようです。 W3仕様ノートで示されているように、おそらく<source>要素を動的に管理するブラウザーの癖がもっと見つかるでしょう。

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

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

32
greg.kindel

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

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

同じ動画プレーヤーで新しいファイルを読み込む代わりに、<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);
10
Stephen Walcher

仕様

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

だからあなたがやろうとしていることは、明らかに動作するはずではない。

6
Yaur

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>

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

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

これが役立つ場合、または問題が発生した場合は、お知らせください。

4
mkralla11

これは私の解決策です:

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

これは、ビデオソースを動的に変更するためのものです。 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();
};
3
molokoloco

私は同様のWebアプリを使用しており、そのような問題にまったく直面していません。私がやることは次のようなものです:

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属性を動的に変更することです。

2
aamiri

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

ちなみに、FireFoxとChromeは両方とも「ogg」形式を再生していますが、Chromeは「webm」を推奨しています。 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
ItsAllABadJoke

私はこれをかなり長い間研究してきましたが、同じことをしようとしているので、これが誰かの助けになることを願っています。私は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>要素を完全に削除し、 canPlayType を使用してJavaScriptでsrcを設定し、最初にサポートされているビデオタイプの後にbreakまたはreturnを設定しますフラッシュ変数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>

重要な注意事項

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

編集

  • 私はまだVideo For Everybodyを使用していますが、Flash Playerを制御するために使用できる素晴らしい JavaScript API を備えたFlashフォールバックを制御するために、FlowPlayerを使用するようになりました。
2
Alex W

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

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

1
Ian Devlin

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
青木 Japan

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