从 Javascript 播放 <audio> + <video> 的正确方法

Posted

技术标签:

【中文标题】从 Javascript 播放 <audio> + <video> 的正确方法【英文标题】:Correct way to play <audio> + <video> from Javascript 【发布时间】:2013-04-28 11:13:18 【问题描述】:

我在使用 和

假设我使用的是 preload="auto" 或 preload="metadata" :

audio.src = "filename";
audio.play();

这似乎在 Firefox 和 Chrome 中都可以正常工作,但我想使用 preload="none" 然后 Chrome dossent 播放。

所以我正在尝试使用 preload="none" 的代码:

audio.src = url;

audio.load();

audio.addEventListener('canplay', function(e) 
   audio.play(); // For some reason this dossent work in Firefox
, false);

audio.play(); // Added this so Firefox would play

我不知道这样做是否正确。

我正在使用: 火狐 20.0.1 铬 25.0.1364.172 米

我做了一个演示:http://netkoder.dk/test/test0217.html

编辑:

在第二个音频播放器(在演示页面上)似乎使用 preload="none" 时必须使用 load()。 但是在 load() 之后立即使用 play() 是正确的,还是在播放之前使用事件等待文件加载的正确方法?

在第三个音频播放器中,似乎 Firefox 20.0.1 dossent 在与 addEventListener() 一起使用时正确支持 canplay 事件,因为它在 load() 之后触发,它在 play() 之后触发,并且在擦洗声音时也会触发dossent 似乎是 canplay 应该工作的方式。 使用 .oncanplay 确实有效。

所以下面的代码似乎可以工作:

  function afspil2(url) 

     afspiller2.src = url;
     afspiller2.load(); // use load() when <audio> has preload="none"
     afspiller2.play();

  

  function afspil3(url) 

     afspiller3.src = url;
     afspiller3.load(); // use load() when <audio> has preload="none"

     //afspiller3.addEventListener('canplay', function()  // For some reason this dossent work correctly in Firefox 20.0.1, its triggers after load() and when scrubbing
     //   afspiller3.play();
     //, false);

     afspiller3.oncanplay = afspiller3.play(); // Works in Firefox 20.0.1

  

我更新了演示以包含更改:http://netkoder.dk/test/test0217.html

我在 afspil3() 函数中添加 addEventListener 的方法看起来不错,因为第一次调用该函数时,addEventListener 中的代码被调用了 1 次。第二次调用函数,addEventListener里面的代码被调用了2次,然后是3次,以此类推。

【问题讨论】:

你能提供一个完整的例子来说明你在哪里设置 preload="none" 并且它不起作用吗? 演示:netkoder.dk/test/test0217.html 【参考方案1】:

这是因为您的audio 标记缺少必需的src 属性或&lt;source&gt; 标记。当我将它们添加到您的演示中时,所有 3 名玩家都立即开始在 Chrome 和 FF 中工作。

另外,我最近发现src不能是空字符串,后来用JS改了。如果有一个原因你不能在 HTML 中设置 src,你最好的选择,IMO,是用 Javascript 创建 audio 元素:

var audio = new Audio();
audio.src = url;
audio.controls = true;
audio.preload = false;
// and so on

编辑:好的。似乎在Chrome中,当HTML为preload="none"时,当src改变时,需要在播放前调用load()。你的第二个audio 没有预加载,所以你的函数需要是这样的:

  function afspil2(url) 
     afspiller2.src = url;
     afspiller2.load(); // add load call
     afspiller2.play();
  

那么,在 Firefox 中,似乎需要在将事件附加到 canplay 事件时设置 preload="auto";,就像在第 3 个函数中一样。

  function afspil3(url) 
     afspiller3.src = url;
     afspiller3.preload = "auto";
     afspiller3.load();
     afspiller3.addEventListener('canplay', function(e) 
        this.play(); // For some reason this dossent work in Firefox
     , false);
  

这看起来很奇怪,但是我测试了很多次,每次调用preload="auto"时它都会播放,但如果不调用它就不会播放。请注意,第二个播放器不是必需的,它也是 HTML 标记中的 preload="none"

最后,如果页面上有多个&lt;audio&gt; 元素,Chrome 会出现一些奇怪的行为。对于所有三个玩家,重新加载页面并单击“大电子”链接将正常播放。

重新加载然后在第 2 位或第 3 位玩家上单击“Yoda”不会做任何事情,但它会为第一个玩家播放。但是,如果以任何方式首先播放***玩家 - 播放按钮或任一链接 - 然后其他两个“尤达”链接将突然起作用。

另外,如果您在重新加载后先点击第 2 或第 3 个“Yoda”链接,然后点击顶部玩家,则之前点击的“Yoda”(之前未播放)将在***玩家停止。

只要说他们有一些错误需要解决就足够了。

【讨论】:

如果启动音频播放器,添加 src 会播放该文件,但如果您尝试通过播放器上方的链接更改音频源,我的 Javascript 代码仍然无法正常工作。 @scootergrisen 刚刚添加了一个编辑。伙计,HTML5 &lt;audio&gt; 还没有达到它需要的位置。我实际上通过 W3C 验证器运行了您的 HTML,因为我认为也许多个 ID 或其他东西可以解释疯狂的行为。不,没有错误。它只是还没有很好地开发。 没关系,它还没有开发出来,并且不能在所有浏览器中运行,我喜欢生活在边缘:D 但我想知道正确的方法是什么。 load() 修复了第二个音频播放器。是的,Chrome 有一些奇怪的问题,但这不是问题,我只想知道编写代码的正确方法是什么。意味着标准的 W3C 方式,即使它现在不能在浏览器中正常工作。无论如何,我刚刚发现 Firefox dossent 在与 addEventlistener() 一起使用时似乎支持 canplay 事件,但它确实支持 oncanplay 事件。【参考方案2】:

我认为正确的方法是使用现有的解决方案,例如http://mediaelementjs.com/

如果您真的对使用 js 播放音频和视频的最佳方式的详细信息感兴趣,请查看源代码: https://github.com/johndyer/mediaelement/tree/master/src/js

https://github.com/johndyer/mediaelement/blob/master/src/js/me-mediaelements.js

【讨论】:

github.com/johndyer/mediaelement/blob/master/build/… 有一个以“Chrome 现在支持 preload="none"” 开头的注释掉的部分,所以这可能暗示仍然可能存在一些问题。我写的代码是让其他人在我的网站上看到的,所以我不想使用 mediaelementjs 之类的代码。 借助 mediaelementjs,您甚至可以完全支持旧浏览器,并且大多数人会使用它而不是尝试重新发明***。您应该至少添加指向 mediaelementjs 页面的链接作为(imo:更好的)替代方案。 那很好,你认为它更好,但这不是我想要的。我想知道如何自己从底层编写代码,我不介意它在旧浏览器甚至所有新浏览器中都不起作用。

以上是关于从 Javascript 播放 <audio> + <video> 的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 javascript 从 Audio Element 录制音频

html javascript audio 音频监听器

Javascript:获取当前播放的 HTMLAudioElement

使用 Javascript 播放音频元素 (html5)

jQuery播放音频

如何在 iOS 上自动播放 HTML5 <video> 和 <audio> 标签?