首页 文章

更改html5视频标记上的源代码

提问于
浏览
105

我正在尝试构建一个适用于任何地方的视频播放器 . 到目前为止,我会去:

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

(如在几个网站上看到的,例如video for everybody)到目前为止,非常好 .

但现在我还想要一些播放列表/菜单以及视频播放器,我可以从中选择其他视频 . 这些应该立即在我的播放器中打开 . 所以我必须使用javascript来"dynamically change the source of the video"(如dev.opera.com/articles/everything-you-need-to-know-html5-video-audio/上所示 - 第"Let's look at another movie"节) . 让我们暂时忘记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> 标签,而只是 <video> 标签中的一个src属性时,整个事情都可以在firefox中运行 .

所以我的计划是使用该src属性并使用canPlayType()函数确定适当的文件 .

我是以某种方式做错了还是让事情变得复杂?

14 回答

  • 3

    只需放一个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

    我来这里动态更改视频源 . “canplay”事件有时候不会在Firefox中触发,所以我添加了“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();
    };
    
  • 4

    尝试将OGG源移动到顶部 . 我注意到Firefox有时会感到困惑并且当玩家想要玩的时候停止播放,OGG不是第一个 .

    值得一试 .

  • 2

    这是我的解决方案:

    <video id="playVideo" width="680" height="400" controls="controls">
        <source id="sourceVideo" src="{{video.videoHigh}}" type="video/mp4">
    </video>
        
    <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

    我讨厌所有这些答案,因为它们太短或依赖于其他框架 .

    这是“一个”香草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);
    
  • 1

    我有一个类似的网络应用程序,并没有面临这样的问题 . 我做的是这样的:

    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属性更可靠 . 上面的代码是从内存中编写的,所以我可能已经掩盖了一些hte细节,但一般的想法是在适当的时候使用javascript动态更改源标记的src属性 .

  • 4

    根据the spec

    当元素已插入视频或音频元素时,动态修改源元素及其属性将不起作用 . 要更改正在播放的内容,只需直接在媒体元素上使用src属性,可能会使用canPlayType()方法从可用资源中进行选择 . 通常,在解析文档之后手动操作源元素是一种不经常复杂的方法 .

    所以你要做的事情显然不应该起作用 .

  • 9

    我已经研究了很长一段时间了,我正在努力做同样的事情,所以希望这会帮助其他人 . 我一直在使用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 .

    Dynamically Changing Sources

    动态更改视频非常困难,如果您想要Flash后备,则必须从DOM /页面中删除视频并重新添加,以便Flash更新,因为Flash无法识别Flash变量的动态更新 . 如果您要使用JavaScript动态更改它,我会完全删除所有 <source> 元素,只需使用canPlayType在JavaScript中设置 src ,在第一个支持的视频类型后设置 breakreturn ,并注册您更改了源代码除非你打电话给 video.load() . 我相信您遇到的 .load() 问题可以通过先调用 video.pause() 来解决 . 删除和添加视频元素会降低浏览器的速度,因为它会继续缓冲已删除的视频,但是there's a workaround .

    Cross-browser Support

    至于实际的跨浏览器部分,我也到了Video For Everybody . 我已经尝试过MediaelementJS Wordpress插件,结果导致了比解决更多的问题 . 我怀疑这些问题是由Wordpress插件引起的,而不是实际的库 . 我想出的是这个简单的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>
    

    Important notes

    • 结束将ogg作为第一个 <source> ,因为Mac OS Firefox如果遇到MP4作为第一个 <source> 则退出尝试播放视频 .

    • 正确的MIME类型是重要的.ogv文件应该是 video/oggnot video/ogv

    • 如果您有高清视频,我发现的高清质量OGG文件的最佳转码器是Firefogg

    • .iphone.mp4 文件适用于iPhone 4,它将 only 播放带有H.264 Baseline 3视频和AAC音频的MPEG-4视频 . 我找到的最好的转码器是Handbrake,使用iPhone和iPod Touch预设可以在iPhone 4上运行,但要让iPhone 3GS正常工作,你需要使用分辨率低得多的iPod预设,我添加为 video.iphone3g.mp4 .

    • 将来我们将能够在 <source> 元素上使用 media 属性来定位具有媒体查询的移动设备,但是现在较旧的Apple和Android设备不能很好地支持它 .

    Edit

    • 我'm still using Video For Everybody but now I'已转换为使用FlowPlayer来控制Flash后备,后者有一个可用于控制它的真棒JavaScript API .
  • 13

    我用这个简单的方法解决了这个问题

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

    Yaur:虽然您复制和粘贴的内容是很好的建议,但这并不意味着即使在IE9(或IE8)中也不可能优雅地更改HTML5视频元素的源元素 . (此解决方案不涉及替换整个视频元素,因为这是不好的编码实践) .

    通过javascript更改/切换HTML5视频标签中的视频的完整解决方案可以在here找到,并在所有HTML5浏览器(Firefox,Chrome,Safari,IE9等)中进行测试 .

    如果这有帮助,或者您遇到麻烦,请告诉我 .

  • 120

    Modernizr对我来说就像一个魅力 .

    我做的是我没有使用 <source> . 不知怎的,这搞砸了,因为视频只在第一次调用load()时工作 . 相反,我在视频标记中使用了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() .

  • 1

    你原来的计划听起来不错 . 您可能会发现更多浏览器怪癖处理动态管理 <source> 元素,如W3规范说明所示:

    当元素已插入视频或音频元素时,动态修改源元素及其属性将不起作用 . 要更改正在播放的内容,只需直接在媒体元素上使用src属性,可能会使用canPlayType()方法从可用资源中进行选择 . 通常,在解析文档之后手动操作源元素是一种不经常[sic]复杂的方法 .

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

  • 60

    而不是让相同的视频播放器加载新文件,为什么不擦除整个 <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);
    
  • 2

    在Chrome 14.0.835.202中使用 <source /> 标签对我来说非常困难,尽管它在FireFox中对我来说很好 . (这可能是我缺乏知识,但我认为替代解决方案无论如何都可能有用 . )因此,我最终只使用 <video /> 标记并在视频标记本身上设置src属性 . canPlayVideo('<mime type>') 函数用于确定特定浏览器是否可以播放输入视频 . 以下适用于FireFox和Chrome .

    很明显,FireFox和Chrome都在播放"ogg"格式,但Chrome推荐"webm" . 我首先检查了浏览器对"ogg"的支持,因为其他帖子已经提到FireFox首先更喜欢ogg源(即 <source src="..." type="video/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();
      }
    

相关问题