目前正在开发一个项目,在 Safari 的 ios 版本中遇到了一个奇怪的问题,涉及从服务器播放音频文件。
我目前面临以下问题:
- 用户进入具有标准 html5 音频标签的页面,以及用于下载目的的音频文件的直接链接。
- 用户尝试收听音频标签中的音频,内容播放 x 分钟,然后中断然后重复(x 分钟不是录音的长度,并且不一致)。
- 当用户尝试直接链接录制内容,而不是下载录制内容时,Safari 似乎会转到新页面并将下载网址封装在视频元素中,并且会出现与步骤 2 相同的问题。
现在音频文件是通过 java scriptlet 提供的,它使用以下代码片段提供文件:
String fn = saveTo + file_name;
f = new File(fn);
String fname = f.getName();
String contentType = "audio/wav";
if(fname.endsWith("mp3")){
contentType = "audio/mp3";
}
response.setContentType(contentType);
response.setHeader("Content-Transfer-Encoding", "binary");
response.setHeader("Content-disposition", "attachment;filename="+f.getName());
response.setHeader("Content-Length", ""+f.length());
FileInputStream fin = null;
try{
fin = new FileInputStream(f.getCanonicalFile());
byte[] data = new byte[1024];
int x = 0;
while((x = fin.read(data, 0, 1024))>=0){
response.getOutputStream().write(data, 0, x);
Thread.sleep(1);
}
} finally {
if(fin != null) {
try{
fin.close();
}catch(Exception ex){}
}
}
现在我知道代码无论如何都不是最好的,它不是我的代码,而且我们显然是在假设文件已找到的情况下工作。
我发现在 iPhone 上使用 Debug模式在 Mac 上进行调试时,它似乎没有显示返回状态代码。它没有显示响应 header ,但显然它必须接收到一些东西。服务器日志似乎认为它返回状态 200,这在 Chrome 和 Firefox 中显示。
上面的代码似乎适用于 Chrome 和 Firefox,但不适用于 Safari。
我唯一猜测的是它与 Safari 不喜欢的文件被推送到输出流的方式有关,或者可能它变得困惑并且应该有不同的状态代码。好几天来,我一直在努力反对这个问题,并尽可能多地阅读有关 Safari 的内容,尽管我找到的大多数文档都是关于其“独特”的网络音频实现,以及使用似乎与此无关的单一 channel 。
如有任何帮助,我们将不胜感激。
最佳答案
我在 iOS 上使用 Safari 时遇到了同样的问题,经过大量调试后,我发现问题与应用于响应的 header 组合有关。
我的应用程序是基于 C# 的,但这个解决方案应该是平台独立的(因为如前所述,这是一个响应 header 问题)。
必要的 header :
- 内容范围:字节0-[内容长度]/[内容长度]
- 内容传输编码:二进制
- 内容长度:[内容长度]
- 接受范围:字节
我在检查了通过 Akamai 的内容交付服务交付的 MP3 的响应后设计了这个。
关于来自服务器的音频的 iOS Safari 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34190593/