更改 html5 视频标签上的源

IT技术 javascript html video load
2021-02-06 02:35:35

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

<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。让我们暂时忘记 Flash 播放器(以及 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 中有一个不错的页面,您可以在其中观察我遇到的问题:http : //www.w3.org/2010/05/video/mediaevents.html

一旦我触发该load()方法(请注意,在 Firefox 中),视频播放器就会死亡。

现在我发现当我不使用多个<source>标签,而是只使用标签中的一个src属性时<video>,整个事情在 Firefox 中确实有效。

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

我是否以某种方式做错了或使事情复杂化了?

6个回答

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

这是执行此操作的“一种”香草 JS 方式,可在 Chrome 中使用,请在其他浏览器中测试:

var video = document.getElementById('video');
var source = document.createElement('source');

source.setAttribute('src', 'http://techslides.com/demos/sample-videos/small.mp4');
source.setAttribute('type', 'video/mp4');

video.appendChild(source);
video.play();
console.log({
  src: source.getAttribute('src'),
  type: source.getAttribute('type'),
});

setTimeout(function() {
  video.pause();

  source.setAttribute('src', 'http://techslides.com/demos/sample-videos/small.webm');
  source.setAttribute('type', 'video/webm');

  video.load();
  video.play();
  console.log({
    src: source.getAttribute('src'),
    type: source.getAttribute('type'),
  });
}, 3000);
<video id="video" width="320" height="240"></video>

外部链接

如果任何人都面临来自有效负载响应的内容类型问题,即使指定的内容类型是正确的,但仍然表现得很奇怪,此解决方案非常有效。
2021-03-24 02:35:35
这对我来说是最干净和最有效的。
2021-03-28 02:35:35
我无法让 Chrome 玩这个。仅当我将视频 src 属性设置为 webm 路径时
2021-03-28 02:35:35
在某些浏览器策略中播放方法仅允许由用户手势使用。
2021-03-30 02:35:35
我非常欣赏这一点还有另一个原因!我一直在尝试设置一个视频页面,该页面在访问者选择之前不显示任何视频。我可以设置一个带有空源标签的视频标签,但它总是会在 javascript 调试控制台上产生一个失败。现在我知道我可以推迟添加“来源”,直到用户选择一个。直到现在,我都不明白我需要使用 CreateElement() 制作源,然后使用 appendChild() 将其添加到视频元素!对于后续选择,我可以先检查源元素是否存在,这样我就不再重复该步骤。
2021-04-08 02:35:35

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 方法并且效果很好。在我的情况下,Chrome(出于某种原因)不会加载 mp4,但会加载 webm。谢谢@MariusEngenHaugen
2021-03-14 02:35:35
如果 (Modernizr.video && Modernizr.video.ogg) 是真的,你不是说第二个是 v[n][1] 吗?
2021-04-04 02:35:35
很高兴我能为@AdamHey 服务
2021-04-07 02:35:35

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

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

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

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

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

与其让相同的视频播放器加载新文件,不如擦除整个<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);
某些浏览器(移动)不允许您在没有用户交互的情况下以编程方式播放媒体,并且由于您已经对元素进行了交互,将其替换为新元素将失去这种能力。
2021-03-20 02:35:35
这会显着降低整个浏览器的速度,因为即使删除了视频标签,浏览器仍然会加载删除的视频直到最后。
2021-03-24 02:35:35