потоковые аудио / видео файлы из gridFS в браузере

Я пытался прочитать аудиофайл из mongoDB, который я сохранил с помощью GridFS. Я могу загрузить файл в систему и играть с ним, но я хотел бы передать эти аудио / видео файлы из самой базы данных и воспроизвести их в браузере. Есть ли способ сделать это, не загружая файл в систему? Любая помощь будет хорошей.

Поддержка 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 вы можете сделать это довольно эффективно.

Если другой рецепт не работает, например, с 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); } 

FYI:

В этом примере:

  • Файл не обрабатывается именем файла, вместо этого он получает доступ к числу, хранящемуся в метаданных. Подсказка: вы можете установить уникальный индекс, чтобы гарантировать, что номер не может использоваться дважды.
  • Content-Type также считывается из GridFS, поэтому вам не нужно жестко указывать это.
  • NginX-кеширование отключено для включения потоковой передачи.

Таким образом, вы можете обрабатывать другие вещи, такие как видео или html-страницы. Если вы хотите включить кеширование NginX, возможно, только выход X-Accel-Buffering для больших размеров.