我一直在尝试从使用GridFS存储的mongoDB中读取音频文件。我可以在系统中下载该文件并从中播放,但我想从数据库本身流式传输这些音频/视频文件并在浏览器中播放。无论如何都没有将文件下载到系统吗?任何帮助都会很好。
答案 0 :(得分:0)
PHP GridFS支持具有MongoGridFSFile::getResource()功能,允许您将流作为资源获取 - 它不会将整个文件加载到内存中。结合fread/echo
或stream_copy_to_stream,您可以阻止整个文件加载到内存中。使用stream_copy_to_stream,您只需将GridFSFile流的资源复制到STDOUT流:
<?php
$m = new MongoClient;
$images = $m->my_db->getGridFS('images');
$image = $images->findOne('mongo.png');
header('Content-type: image/png;');
$stream = $image->getResource();
stream_copy_to_stream( $stream, STDOUT );
?>
或者,您可以在返回的fseek()
资源上使用$stream
,仅将部分流发送回客户端。结合HTTP Range requests,您可以非常有效地完成此任务。
答案 1 :(得分:0)
如果other recipe失败,例如NginX
和php-fpm
失败,因为STDOUT
中没有fpm
,您可以使用
fpassthru($stream);
而不是
stream_copy_to_stream( $stream, STDOUT );
所以完整的解决方案如下:
function img($nr)
{
$mongo = new MongoClient();
$img = $mongo->ai->getGridFS('img')->findOne(array('metadata.nr'=>$nr));
if (!$img)
err("not found");
header('X-Accel-Buffering: no');
header("Content-type: ".$img->file["contentType"]);
header("Content-length: ".$img->getSize());
fpassthru($img->getResource());
exit(0);
}
供参考:
在这个例子中:
这样你甚至可以处理视频或html页面等其他内容。如果要启用NginX缓存,可能只在较大的大小上输出X-Accel-Buffering
。