2013-08-12 2 views
1

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

ответ

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

+0

Hey Derick. Я пытался получить звук, чтобы играть, но напрасно. Я уже написал вышеуказанный код, чтобы соответствовать моему коду, но я получаю плеер, но не файл для воспроизведения. Не могли бы вы помочь мне? – fastLearner

+0

Я получаю файл, но не могу пропустить его, выполнив поиск (file_handle, length). Мой вопрос: если пользователь нажимает на временную шкалу игрока, то как мне позаботиться о смещении места, которое он нажал? – fastLearner

+0

@ user2610503 Вам нужно будет подключить интерфейс для отдыха в ваше приложение, которое может принять представление flash/html5, запрашивающее пропуски из файла – Sammaye

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

FYI:

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

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

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

Смежные вопросы