<audio> 的正确加载

Posted

技术标签:

【中文标题】<audio> 的正确加载【英文标题】:Proper onload for <audio> 【发布时间】:2012-03-14 06:26:28 【问题描述】:

我一直在环顾四周,我开始担心这是不可能的。 有什么办法可以制作一个标准的&lt;audio&gt; 标记与后备...

<audio>
    <source src='song.ogg' type='audio/ogg'></source>
    <source src='song.mp3' type='audio/mp3'></source>
</audio>

...有一个 onload 事件。我环顾四周,我能找到的只是一些可能有效或无效的黑客(它们在 Chrome 上不适合我)和canplaythrough 事件。 我想要这个的原因是因为我正在制作一个演示文稿,其中有很多音频片段可以在某些点播放。我不希望在加载所有音频之前开始演示(否则事情可能会不同步)。我希望一次加载 1 个剪辑,以便创建一种加载栏。我真的不想求助于使用 Flash 声音,因为这应该展示纯 Web 技术。 所以基本上我有一个loadAudio 函数,它循环遍历要加载的音频文件数组audioQueueloadAudio 被调用一次,然后它会调用自身,直到所有文件都加载完毕。 问题是我没有找到触发加载下一个文件的正确事件。

loadAudio = function(index)

mer = audioQueue[index];
var ob = "<audio id='" + mer + "'><source src='resources/sounds/" + mer + ".ogg' type='audio/ogg'></source><source src='resources/sounds/" + mer + ".mp3' type='audio/mp3'></source></audio>";
$("#audios").append(ob);
$("#" + mer).get(0).addEventListener('A WORKING EVENT RIGHT HERE WOULD BE NICE', function()  alert("loaded"); 
     if (index + 1 < audioQueue)  loadAudio(index + 1);  , false);

所以。有机会进行适当的音频加载吗?只要还是 htmljavascript,我基本上愿意做任何事情。

【问题讨论】:

前段时间有同样的问题,请参阅:***.com/questions/9332167/preload-audio-files-event 只是“剥离”图像部分。 @m90 啊,完美运行。你能把它变成一个答案,以便我把它设置为正确的吗? Preload Audio Files / Event?的可能重复 【参考方案1】:

您可以使用loadeddata-MediaEvent。例如,您可以将所有音频文件放在一个数组中并执行以下操作:

var files = ['a.mp3', 'b.mp3'];

$.each(files, function() 
    $(new Audio())
        .on('loadeddata', function() 
            var i = files.indexOf(this);
            files.splice(i, 1);
            if (!files.length) 
                alert('Preloading done!');
            
        )
        .attr('src', this);
);

编辑:从 2016 年开始,这将是一种更现代的方法:

var files = ['a.mp3','b.mp3'];

Promise
    .all(files.map(function(file) 
        return new Promise(function(resolve) 
            var tmp = new Audio();
            tmp.src = file;
            tmp.addEventListener('loadeddata', resolve);
        );
    )).then(function() 
        alert('Preloading done!');
    );

【讨论】:

想知道这是否仍然有效。收到此错误 ******* Uncaught TypeError: tmp.on is not a function 所以这就是我必须做的......不确定这是否是“解决方案”,但对我有用 ******************* ****************************************************** ****************************************************** ***** $.each(files,function() var tmp = new Audio(); tmp.src = this; //this 被转换为 URL tmp.textContent = this; $(tmp).on( 'loadeddata',function() var i = files.indexOf(this.textContent); files.splice(i,1); if (!files.length) console.log('Preloading done!'); ); ); Node.prototype.on = function(...args) this.addEventListener(...args); return this; ;【参考方案2】:

我用 WebGL 和一些声音标签做了一个小型 PONG 游戏。我从 Opera 的 Emberwind HTML5 实现中借用了音频实现:https://github.com/operasoftware/Emberwind/blob/master/src/Audio.js

他们的解决方案对我来说效果很好(Chrome、Opera 和 Firefox)。也许你会感兴趣?他们有一些代码会尝试从第 22 行及以下找到可播放的格式。

【讨论】:

这可行,但它使用 canplaythrough 事件和我想避免的声音的“spritesheet”。这是一个很好的资源。

以上是关于<audio> 的正确加载的主要内容,如果未能解决你的问题,请参考以下文章

jQuery 和 HTML 5 <audio> [关闭]

原生js控制audio标签播放暂停重新加载

javascript 音频加载

怎样获得html5的audio组件加载的MP3文件的总时长

基于react的audio组件

html5 jquery audio player插件怎么用