Web音频事件“结束”;在播放源缓冲区的一部分时未被触发
Web Audio event "ended" not being fired when playing part of a source buffer
我们有一个web音频助手功能,可以播放声音表中的声音,并让我们知道它们何时完成。在过去,我们在更新循环中使用playbackState
来检查已经完成播放的节点,但由于Chrome 36现在使用当前规范,不支持playbackState
,我们更新了代码以使用'ended'
事件。
然而,这似乎并没有被解雇。
以下是我们的playAudio函数:-playAudio: function(trackName){
var node = this._atx.createBufferSource();
node.buffer = this._buffer;
var gain = this._atx.createGain();
node.connect(gain);
gain.connect(this._atx.destination);
var start = this._tracks[trackName][0];
var length = this._tracks[trackName][1] - start;
node.start(0, start, length);
var sound = {name: trackName, srcNode: node, gainNode: gain, startTime: this._atx.currentTime, duration: length, loop: false, playHeadStart: start};
if (this._features.hasEvents) {
//node.addEventListener("ended", function () {
// this._soundEnded(sound)
//}.bind(this));
node.onended = function(){
this._soundEnded(sound);
}.bind(this);
}
this._playingSounds[++this._soundId] = sound;
return this._soundId;
},
_soundEnded: function (sound) {
this._playingSounds[sound] = null;
delete this._playingSounds[sound];
}
通过在加载期间创建的音频节点上检查node.onended !== null
来设置this._features.hasEvents
变量。缓冲区是通过XHR文件创建的。这可以是mp3或m4a,这取决于我们播放的是什么。
_soundedEnded
函数没有被调用的原因是什么?我尝试了node.onended = function(){...}
和node.addEventListener("ended", function(){..})
语法,都没有运气。我们似乎在iOS 7 Safari和桌面/Android Chrome中都有相同的行为。
我刚刚解决了这个问题,在意识到我做了一些愚蠢的事情之后。这个bug不是WebAudio,而是回调函数,它应该从_playingSounds
数组中删除声音对象。
这段代码:
var sound = {name: trackName, srcNode: node, gainNode: gain, startTime: this._atx.currentTime, duration: length, loop: false, playHeadStart: start};
if (this._features.hasEvents) {
//node.addEventListener("ended", function () {
// this._soundEnded(sound)
//}.bind(this));
node.onended = function(){
this._soundEnded(sound);
}.bind(this);
}
this._playingSounds[++this._soundId] = sound;
return this._soundId;
应该更像这样:
var sound = {name: trackName, srcNode: node, gainNode: gain, startTime: this._atx.currentTime, duration: length, loop: false, playHeadStart: start};
var soundId = ++this._soundId;
if (this._features.hasEvents) {
node.onended = function(){
this._soundEnded(soundId);
}.bind(this);
}
this._playingSounds[soundId] = sound;
return soundId;
我试图通过值而不是键来删除对象,这显然不起作用。现在,代码将键传递给函数,一切都恢复正常。
相关文章:
- 为什么当我分配给element.style时,我的元素的样式没有改变
- jQuery 数据表 在页面上导航时,在分页表上重置行的数据
- 网格分页栏在重新加载时未更新
- 表中使用分页时的后退按钮
- 打印包含1页以上的表数据时,如何在浏览器打印中添加分页符
- Angularjs在使用分页时无法显示orderBy
- 分页没有'当我点击javascript和php按钮时,它不起作用
- 在部分视图内渲染的WebGrid将引发“;“jQuery未定义”,当尝试执行基于ajax的分页或过滤时
- 当uib分页被包装在另一个指令中时,AngularJS表数据没有更新
- 当作为 CommonJS 模块加载时,Angular 是否全局将自己分配给“window.angular”
- 使用分页时如何从 DataTables.net 获取所有数据行
- 使用 Ajax 分页时缺少元素(Facebook 赞按钮)
- Ajax 和 PHP 重新加载分页时无法弄清楚
- 使用 jsoup 时处理网页中的分页
- 打印时每页上的分页符和表头.打印表 CSS 问题
- 当我在 javascript 中单击分页项时,我如何查看图片
- 代码点火器 - jQuery 数据表 搜索和分页时不会保留复选框中的选中值
- 页面加载时显示完整列表的分页
- 页面加载时的 Ajax 分页
- 如何在单击按钮时切换 jquery 数据表的分页