Javascript Safari上的HTML5音频标签有延迟

Javascript Safari上的HTML5音频标签有延迟,javascript,html,html5-audio,Javascript,Html,Html5 Audio,我正在尝试完成一个简单的涂鸦行为,使用html标记,点击时会响起mp3/ogg声音。它应该在Firefox、Safari和Safari下工作,iPad非常受欢迎 我尝试了许多方法,并得出以下结论: HTML <span id="play-blue-note" class="play blue" ></span> <span id="play-green-note" class="play green" ></span>

我正在尝试完成一个简单的涂鸦行为,使用html标记,点击时会响起mp3/ogg声音。它应该在Firefox、Safari和Safari下工作,iPad非常受欢迎

我尝试了许多方法,并得出以下结论:

HTML

    <span id="play-blue-note" class="play blue" ></span>
    <span id="play-green-note" class="play green" ></span>


    <audio id="blue-note" style="display:none" controls preload="auto" autobuffer> 
        <source src="blue.mp3" />
        <source src="blue.ogg" />
        <!-- now include flash fall back -->
    </audio>

    <audio id="green-note" style="display:none" controls preload="auto" autobuffer> 
        <source src="green.mp3" />
        <source src="green.ogg" />
    </audio>

JS

function addSource(elem, path) {
    $('<source>').attr('src', path).appendTo(elem);
}

$(document).ready(function() {


    $('body').delegate('.play', 'click touchstart', function() {
        var clicked = $(this).attr('id').split('-')[1];

        $('#' + clicked + '-note').get(0).play();



    });

});  
函数addSource(元素,路径){
$('').attr('src',path).appendTo(elem);
}
$(文档).ready(函数(){
$('body').delegate('.play','click touchstart',function(){
var clicked=$(this.attr('id').split('-')[1];
$(“#”+单击+”-note').get(0.play();
});
});  
这在Firefox下似乎很有效,但Safari似乎在您单击时会有延迟,即使您多次单击并且音频文件已加载。在iPad上的Safari上,它的行为几乎不可预测

另外,当我在本地进行测试时,Safari的性能似乎有所提高,我猜Safari每次都在下载文件。这可能吗?我怎样才能避免这种情况?
谢谢

我刚刚回答了另一个iOS/
Safari的问题是每次播放音频文件时都会发出请求。您可以尝试创建HTML5缓存清单。不幸的是,根据我的经验,一次只能向缓存中添加一个音频文件。解决方法可能是将所有音频文件按顺序合并为单个音频文件,并根据需要在特定位置开始播放。您可以创建一个间隔来跟踪当前播放位置,并在达到某个时间戳后暂停

在此处阅读有关创建HTML5缓存清单的更多信息:

希望有帮助

苹果决定(为了节省celluar的费用)不预加载

在iOS上的Safari中(适用于所有设备,包括iPad),用户可以 在蜂窝网络上,按数据单元收费,预加载和 自动播放被禁用。在用户启动之前,不会加载任何数据。 这意味着JavaScript
play()
load()
方法也处于非活动状态 直到用户启动播放,除非使用
play()
load()
方法 由用户操作触发。换句话说,用户发起的播放 按钮起作用,但onLoad=“play()”事件不起作用

这将播放电影:

这在iOS上不起任何作用:


我不认为你可以绕过这个限制,但你也许可以

记住:谷歌是你最好的朋友



更新:经过一些实验,我找到了播放
的方法。似乎有效。

音频文件加载一次,然后缓存。。重复播放声音,即使在页面刷新之后,也不会在Safari中引起进一步的HTTP请求

我刚刚在音频编辑器中查看了您的一个声音-文件开头有少量的静音。。这将表现为延迟


这对你来说是一个可行的选择吗

我也有同样的问题。奇怪的是我正在预加载文件。但WiFi播放效果很好,但在手机数据上,启动前有很长的延迟。我认为这与加载速度有关,但在加载所有图像和音频文件之前,我不会开始播放我的场景。任何建议都很好。(我知道这不是一个答案,但我认为写一篇dup帖子更好)

在桌面Safari上,添加AudioContext解决了以下问题:

const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioCtx = new AudioContext();

我是偶然发现的,所以我不知道它为什么会工作,但这消除了我应用程序上的延迟。

Safari iOS上的HTML5音频延迟(

请在您自己的iOS设备上测试功能(我在iOS 12中测试过)

来自JS Fiddle的代码片段

//需要jQuery
//添加:
//去掉lowLag.js,使其仅支持audioContext(因此不支持IE11(仅边缘))
//添加循环音频所需的“循环”猴子补丁(我的主要用途)
//添加单个音频通道-避免音频播放重叠
//原始资料来源:https://lowlag.alienbill.com/lowLag.js
如果(!window.console)控制台={
日志:函数(){}
};
var lowLag=新函数(){
this.someVariable=未定义;
this.showNeedInit=函数(){
msg(“lowLag:必须首先调用lowLag.init());
}
this.load=this.showNeedInit;
this.play=this.showNeedInit;
this.pause=this.showNeedInit;
this.stop=this.showNeedInit;
this.switch=this.showNeedInit;
this.change=this.showNeedInit;
this.audioContext=未定义;
this.audioContextPendingRequest={};
this.audioBuffers={};
this.audioBufferSources={};
this.currentTag=未定义;
this.currentPlayingTag=未定义;
this.init=函数(){
this.msg(“init audioContext”);
this.load=this.loadSoundAudioContext;
this.play=this.playSoundAudioContext;
this.pause=this.pauseSoundAudioContext;
this.stop=this.stopSoundAudioContext;
this.switch=this.switchSoundAudioContext;
this.change=this.changeSoundAudioContext;
如果(!this.audioContext){
this.audioContext=new(window.audioContext | | window.webkitadiocontext)();
}
}
//我们将使用他们交给我们的标签,如果是单个标签,则使用url作为标签,
//还是第一个url
this.getTagFromURL=函数(url,标记){
如果(标记!=未定义)返回标记;
返回lowLag.getSingleURL(url);
}
this.getSingleURL=函数(URL){
if(typeof(url)=“string”)返回url;
返回URL[0];
}
//强制成为数组
this.getURLArray=函数(URL){
if(typeof(url)=“string”)返回[url];
返回URL;
}
this.loadSoundAudioContext=函数(URL、标记){
var url=lowLag.getSingleURL(url);
tag=lowLag.getTagFromURL(URL,标记);
lowLag.msg('webkit/chrome audio lo
const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioCtx = new AudioContext();