【发布时间】:2022-01-08 05:03:09
【问题描述】:
我正在处理 iOS/MacOS 问题。
我正在尝试通过 HTML5 音频元素播放一个简单的音频文件,除 iOS/MacOS 外,一切正常。
我的应用基于 Symfony 构建,使用 Nginx 和自定义 PHP 控制器来提供音频资源。音频元素的给定源是指向处理流的路由的链接。
我的逻辑如下:
- 从 url ID 获取文件
- 读取请求标头以查找预期范围和长度
- 设置好的标题以强制 206 部分内容行为
- 正在写入预期的文件块并返回 206 响应。
下面是代码:
public function getAudio(Request $request, $audioId)
{
/*
* Getting the file
*/
$em = $this->getDoctrine()->getManager();
$voice = $em->getRepository("CoreBundle:Audio")->findOneById($audioId);
$media = $audio->getFile();
$path = $this->container->get('sonata.media.twig.extension')->path($media, 'reference');
$file = $this->get('kernel')->getRootDir() . "/../web$path";
/*
* Setting length and offset for serving the right chunk
*/
$offset = 0;
$requestedRange = $request->headers->get("Range");
$size = $media->getSize();
$length = $size;
if($requestedRange){
preg_match('/bytes=(\d+)-(\d+)?/', $requestedRange, $matches);
$offset = intval($matches[1]);
if(count($matches) > 2){
$length = intval($matches[2]) - $offset + 1;
}
else{
$length = ($size) - $offset;
}
}
if(file_exists($file) && $length) {
$file = fopen($file, 'r');
fseek($file, $offset);
$data = fread($file, $length);
fclose($file);
if($requestedRange){
header('Content-Range: bytes ' . $offset . '-' . ($offset + $length-1) . '/' . $size);
}
else{
header('Content-Range: bytes 0-'.($size-1).'/'.$size);
}
/*
* Forcing some headers in the response to fit request attempts
*/
header("Pragma: public");
header("Expires: 0");
header('Content-type: audio/mpeg');
header('Content-Disposition: inline');
header('Accept-Ranges: bytes');
header('Content-Length: '.$length);
header('X-Pad: avoid browser bug');
header('Cache-Control: no-cache');
print($data);
return new Response("",206);
}
else{
return new Response("",200);
}
}
再一次,在 Firefox 和 Chrome 上一切正常,文件流式传输并完美播放。 但是当涉及到 IOS 和 MacOS 时,文件就无法播放。查看网络控制台会显示两个后续请求,最后一个请求出错(请参阅下一个链接)。
但是,PHP 中没有记录任何错误,我现在完全卡住了。
【问题讨论】:
标签: ios networking safari html5-audio