Apple 网站上的说明
简短的回答:
因为 iOS 设备要求服务器支持视频的字节范围请求,而您的代码不提供该功能。
长答案:
当 iOS 设备请求视频时,它们不会下载整个视频。他们一次只下载一小块,以最大限度地减少带宽使用,也因为用户可能希望跳到视频的后面部分而不下载前面的部分。为此,他们提出字节范围请求。基本上,他们告诉服务器“嘿,给我第 100 和第 200 字节之间的文件部分”。字节范围请求使用Range
标头,如下所示
GET /myvideo.mp4 HTTP/1.1
Host: www.example.com
Range: bytes=500-999
在这种情况下,服务器必须回复类似的内容
HTTP/1.1 206 Partial Content
Content-Type: video/mp4
Content-Range: bytes 500-999/20000
所以你需要的不仅仅是这四个 php 行来支持 iOS 设备。首先,您将解析Range
标题。此信息在$_SERVER['HTTP_RANGE']
全局变量中可用。然后,您只需要获取文件的那一部分并将其发送给客户端。您还需要填充Content-Range
标题。
请注意,Content-Range
标头包含完整的文件大小,因此您的代码将需要提供该信息。另请注意,几乎每个服务器都支持这种对静态文件的请求。如果您不需要对文件进行特殊处理,一个可能的选择是将文件复制到公共服务器上并让它为您完成工作。
非相关评论
将其视为建设性的批评,但您当前形式的代码将使您的服务器陷入困境。您基本上在发送之前将整个文件放在内存中,更糟糕的是,您对每个请求都执行此操作。如果 100 个人同时下载 100MB 的视频,则服务器上需要10GB的内存来为他们提供服务。这不成比例,一点也不。
更好的解决方案是使用readfile函数将文件作为从 CDN 读取的内容发送。这样,您只需要使用一小块内存,就可以处理更多的并发请求。
编辑:实际上,您还需要使用特殊的响应代码进行响应,即 206 部分内容。我在这个答案的第一个版本中忘记了这一点。现在已修复