我有一台PHP服务器,通过从不公开的FTP服务器流式传输音频文件来提供音频文件。
发送approriate标头后,我只是使用ftp_get将文件流式传输到客户端,如下所示:
ftp_get($conn, 'php://output', $file, FTP_BINARY);
由于与Range
标题有关的原因,我现在必须提供仅发送此流的一部分:
$start = 300; // First byte to stream
$stop = 499; // Last byte to stream (the Content-Length is then $stop-$start+1)
我可以通过将整个内容临时下载到文件/内存,然后将所需的部分发送到输出来实现。但由于文件很大,该解决方案会导致客户端在开始下载到客户端之前必须等待文件首先下载到PHP服务器的延迟。
问题:
如果第一个php://output
字节被丢弃后,如何从FTP服务器开始流式传输到$start
,当我到达'$ stop'字节时,如何停止流式传输?
答案 0 :(得分:1)
不使用PHP的FTP extension(例如ftp_get
),而是可以使用PHP的内置FTP wrapper打开流。
以下代码会将部分FTP文件流式传输到php://output
:
$start = 300; // First byte to stream
$stop = 499; // Last byte to stream
$url = "ftp://username:password@server.com/path/file.mp3";
$ctx = stream_context_create(array('ftp' => array('resume_pos' => $start)));
$fin = fopen($url, 'r', false, $ctx);
$fout = fopen('php://output', 'w');
stream_copy_to_stream($fin, $fout, $stop-$start+1);
fclose($fin);
fclose($fout);
虽然stream_copy_to_stream
具有$offset
参数,但使用它会导致错误,因为该流不可搜索。然而,使用上下文选项resume_pos
工作正常。