stream audio/video files from gridFS on the browser

强颜欢笑 提交于 2019-12-08 06:02:21

问题


I have been trying to read an audio file from mongoDB which i have stored using GridFS. I could download the file in the system and play from it but I wanted to stream those audio/video files from the DB itself and play it in the browser. Is there anyway to do that without downloading the file to the system? Any help would be good.


回答1:


The PHP GridFS support has a MongoGridFSFile::getResource() function that allows you to get the stream as a resource - which doesn't load the whole file in memory. Combined with fread/echo or stream_copy_to_stream you can prevent the whole file from being loaded in memory. With stream_copy_to_stream, you can simply copy the GridFSFile stream's resource to the STDOUT stream:

<?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 );
?>

Alternatively, you can use fseek() on the returned $stream resource to only send back parts of the stream to the client. Combined with HTTP Range requests, you can do this pretty efficiently.




回答2:


If the other recipe fails, for example with NginX and php-fpm, because STDOUT is not available in fpm, you can use

fpassthru($stream);

instead of

stream_copy_to_stream( $stream, STDOUT );

So a complete solution looks like:

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);
}

FYI:

In this example:

  • File is not acccessed by the filename, instead it is accessed by a number stored in the metadata. Hint: You can set an unique index to ensure, that no number can be used twice.
  • Content-Type is read from GridFS, too, so you do not need to hardcode this.
  • NginX caching is switched off to enable streaming.

This way you can even handle other things like video or html pages. If you want to enable NginX caching, perhaps only output X-Accel-Buffering on bigger sizes.



来源:https://stackoverflow.com/questions/18185390/stream-audio-video-files-from-gridfs-on-the-browser

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!