HTML5音频:如何快速停止和重新开始剪辑?

11

请看标题。我正在尝试连续播放一个音频文件4次,每300毫秒播放一次。然而,这个片段的长度超过了300毫秒,因此它会忽略新的播放请求,直到片段播放完毕。我正在寻找一些方法来在每300毫秒停止和重新启动片段。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
</head>
<body>
    <audio id="note0440"><source src="0440.a4.wav" type="audio/wav"></audio>
    <script type="text/javascript">
        function playNote (loop) {
            var n = document.getElementById("note0440")
            if (loop > 4)
                return
            n.volume = 0.05
            // n.currentTime = 0
            n.pause()
            n.play()
            setTimeout("playNote("+(loop + 1)+")", 300)
        }
    </script>
    <div style="margin:50px"><button onclick="playNote(1)">Play Note</button></div>
</body>
</html>

这并不起作用。无论是否使用 n.currentTime = 0,它都不能停止和重新启动。

如果需要测试,这里有一个WAV文件:http://popstrip.com/misc/0440.a4.wav


在运行.play()之前运行.stop()是否有效?我已经阅读了一些文档,看起来没有.stop()。但是像一些人建议的那样,暂停然后将时间设置回0应该会产生相同的效果。 - Shadow
另外,FYI,您的文档类型声明指定了一个不支持音频标签的HTML版本。请将其更改为<!DOCTYPE html>。 - Max DeLiso
4个回答

33

无论您在哪里停止通话,只需按以下顺序执行:

 n.pause();
 n.currentTime = 0;
 n.play();      

你在Firefox上试过吗?在Chrome中对我有效,但FF无效。谢谢! - user353885
正如@user931794和shadow指出的那样-火狐浏览器可能还没有完全支持此方法,但这应该是正确的方法。我想现在又得回到Flash了。=/ - user353885

4

摘自规范第4.8.10.6节:

media.duration 返回媒体资源的长度(秒),假设媒体资源的起始时间为零。

如果时长不可用,则返回NaN。

对于无界流,返回Infinity。

media.currentTime [ = value ] 返回官方播放位置(秒)。

可以设置,以便跳转到给定时间。

如果没有选择媒体资源或存在当前媒体控制器,则会引发InvalidStateError异常。

因此,这个规范不允许小于一秒的跳转。然而,不同的浏览器都会以不同的方式实现它(当然)。有些浏览器可能支持这个功能,但要让它在所有已部署的浏览器中可靠地工作将是一个巨大的麻烦。假设您可以发出毫秒级的跳转,另一个问题是js解释器可能无法及时满足您的请求,即跳转的处理时间超过了跳转值,这会导致其他困难。

如果您确实需要小于一秒的跳转粒度,请暂时放弃html5方法,如果可能,请使用插件或在主机上本地运行的一些代码。


1
那很方便知道。但我认为他不想寻找 - 我认为他只是想在运行时间过长时停止它? - Shadow
据我所知,停止和启动必须发生在寻求边界上。 - Max DeLiso
1
@shadow所说的是 - 目标不是争取在一秒内寻找(快速重复10次),而是快速连续播放剪辑4次。我只想听到剪辑快速重复(确切地说是每300毫秒)。谢谢! - user353885
那就是Firefox的问题。恐怕我要同意@user931794的观点 - 它还没有得到足够的支持。您可能可以使用Flash来完成这种操作。 - Shadow
你会发现它不能工作的原因与我发布的内容密切相关。也许几年后会有更好的支持这种事情的方式(但可能不会)。一定要喜欢网络开发。 - Max DeLiso
显示剩余2条评论

1
这个答案看起来是正确的 https://dev59.com/GGYr5IYBdhLWcg3w--4I#13243338,但是我在没有controls属性的音频元素中尝试了一下,它没有工作。只有当使用https://dev59.com/GGYr5IYBdhLWcg3w--4I#13243333中提到的audioElement.currentTime=1时才能工作,但对于我的用例来说,0秒后1秒太长了。
所以我尝试了audioElement.currentTime=null,它可以工作!✅ 这是我的解决方案片段。
<audio src="/file.mp3" id="audioElement" />

audioElement.play()
audioElement.currentTime = null

它在Chrome 87和Firefox 84上运行良好,我很快会在其他浏览器上进行测试,并在此更新。

谢谢。


-2

这有点取巧,但我会这样做:

<audio src="blah.wav" type="audio/wav" preload="preload" id="blah0"></audio>
<audio src="blah.wav" type="audio/wav" preload="preload" id="blah1"></audio>
<audio src="blah.wav" type="audio/wav" preload="preload" id="blah2"></audio>
<audio src="blah.wav" type="audio/wav" preload="preload" id="blah3"></audio>

var audioStore = [
  document.getElementById('blah0'),
  document.getElementById('blah1'),
  document.getElementById('blah2'),
  document.getElementById('blah3'),
];

var n = 0;

function playBlah () {
  // Cycle through the clips
  audioStore[n].play();
  n = (n+1)%4;
}

针对您需要的数量执行此操作。好处是,您不会失去声音的尾巴,因此可以使用环境声(例如,游戏有时希望声音重叠)。

有更优雅的方法来完成这个任务。我实际上会编写一个函数,该函数接受音频文件名、ID词干(例如示例中的blah)和要循环的元素数量(该声音的最大同时值),并返回可调用以播放声音的函数。此函数还将添加元素到页面中。

最后,您应该至少使用MP3和Wav以获得最大的跨浏览器兼容性,格式越多越好,因为波形是主要的带宽占用者。

希望这可以帮助您。(我已在Win、Mac OSX和Linux上的Chrome、Firefox、Ice Weasel中使用了这种技术)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接