我刚刚使用socket.io构建了一个实时应用程序,其中一个" master"用户可以在接收设备(桌面浏览器,移动浏览器)上触发声音。该主用户可以看到声音文件列表,并可以点击"播放"在声音文件上。
音频播放在浏览器上即时播放。然而,在手机上,延迟时间为0.5-2秒(我的Nexus 4和iPhone 5约为1秒,iPhone 3GS为1-2秒)。
我已经尝试了几项优化音频播放的功能,以便在手机上更快。现在(在最佳"阶段"它的优化我会说),我将所有的mp3组合在一个音频文件中(它创建.mp3,.ogg和。 mp4文件)。我需要有关如何进一步修复/改善此问题的想法。瓶颈似乎真的出现在hmtl 5音频方法中,例如.play()
。
在我使用的接收器上:
<audio id="audioFile" preload="auto">
<source src="/output.m4a" type="audio/mp4"/>
<source src="/output.mp3" type="audio/mpeg"/>
<source src="/output.ogg" type="audio/ogg"/>
<p>Your browser does not support HTML5 audio.</p>
</audio>
在我的JS中:
var audioFile = document.getElementById('audioFile');
// Little hack for mobile, as only a user generated click will enable us to play the sounds
$('#prepareAudioBtn').on('click', function () {
$(this).hide();
audioFile.play();
audioFile.pause();
audioFile.currentTime = 0;
});
// Master user triggered a sound sprite to play
socket.on('playAudio', function (audioClip) {
if (audioFile.paused)
audioFile.play();
audioFile.currentTime = audioClip.startTime;
// checks every 750ms to pause the clip if the endTime has been reached.
// There is a second of "silence" between each sound sprite so the pause is sure to happen at a correct time.
timeListener(audioClip.endTime);
});
function timeListener(clipEndTime) {
this.clear = function () {
clearInterval(interval);
interval = null;
};
if (interval !== null) {
this.clear();
}
interval = setInterval(function () {
if (audioFile.currentTime >= clipEndTime) {
audioFile.pause();
this.clear();
}
}, 750);
}
对于每种声音也被认为是blob,但是有些声音可以持续几分钟,这就是为什么我将所有声音组合在一起用于1个大音频文件(优于页面上的几个audio
标签夹)
答案 0 :(得分:1)
我不是暂停/播放,而是在不应该播放时将音量设置为0,在应该播放时将音量设置为1。即使在iPhone 3GS上,Audio
方法currentTime
和volume
也不会减慢音频播放速度。
我还在音频元素中添加了'loop'属性,因此不必再次.play()
。
将所有mp3声音组合在一起非常有成效,因为这种解决方案可以正常运行。
编辑:audioElement.muted = true或audioElement.muted = false更有意义。
Edit2:无法代表用户在iOS上控制音量,因此我必须暂停()并播放()音频元素,而不是将其静音和取消静音。
答案 1 :(得分:1)
在手机上进行测试时,我遇到了同样的延迟问题。我发现一些HTML 5游戏正在使用音频,因为游戏需要非常低的延迟。有些人正在使用SoundJS。我建议您尝试一下该库。
您可以在此处找到使用HTML Audio标签与使用SoundJS之间的速度比较:
http://www.nickfrazier.com/javascript/audio/ui/2016/08/14/js-sound-libraries.html
(在手机中进行测试以了解不同之处)
通过我的测试 SoundJS 更快。
实际上,它足以在游戏中使用,或在用户界面中用于声音反馈。
答案 2 :(得分:0)
由于preload
属性,您的设置在桌面上运行良好。
不幸的是,这里Apple on the subject of preload
:
iOS上的Safari永远不会预加载。
这里MDN:
注意:此值通常会在移动平台上被忽略。
移动平台正在进行权衡以节省电池和数据使用量,以便在用户实际与用户进行互动或以编程方式播放时加载媒体(autoplay
通常不会用于类似原因)。
我认为您要做的最好的事情就是将您的曲目组合在一起,正如您所说的那样,所以您不必支付初始加载费用&#34;成本&#34;同样多。
答案 3 :(得分:0)
老问题,但这是我使用上面答案之一的解决方案:
const el = document.createElement("audio");
el.muted = true;
el.loop = true;
const source = document.createElement("source");
source.src = lineSe;
source.type = "audio/mpeg";
el.appendChild(source);
// need to call this function after user first interaction, or safari won't do it.
function firstPlay() {
el.play();
}
let timeout = null;
function play() {
// In case user press the button too fast, cancel last timeout
if (lineSeTimeout) {
clearTimeout(timeout);
}
// Back to beginning
el.currentTime = 0;
// unmute
el.muted = false;
// set to mute after the audio finish. In my case 500ms later
// onended event won't work because loop=tue
timeout = setTimeout(() => {
// mute audio again
el.muted = true;
}, 500);
}