PHP NginX - выходная буферизация - потоковая передача видео

(Так как это содержит некоторое кодирование, но также и это касается nginx конфигурации, я думаю, что было бы лучше иметь его в serverfault).

У меня есть некоторые Видеофайлы в моем Сервере, которые хранятся в папке в моей файловой системе, и я использую PHP, чтобы прочитать Видеофайл и отправить его непосредственно в пользовательское использование NginX как WebServer.

Большинство Видеофайлов является прямыми трансляциями, которые я генерирую использование FFmpeg, но у меня есть некоторые фильмы также.

Живые Файлы Потоковой передачи: существуют splitted в сегменты, и с php я считал m3u8 файл, я получаю *.ts файлы, и я передаю их потоком использующий PHP, в то время как FFmpeg все еще работает в фоне.

Файлы ролика: Всего один статический Файл

У меня есть некоторые вопросы относительно nginx/php конфигурации.

Моя конфигурация NginX следующая:

server {
    listen 80;
    index index.php index.html index.htm;
    root /var/www;
    server_tokens off;
    chunked_transfer_encoding off;


    location ~ \.php$ {    
        try_files $uri =404;
        fastcgi_index index.php;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
    }
}

Для каждого Клиента, что чтение Файлов Видео с моего Сервера я регистрирую соединение и я могу предсказать, онлайн ли он все еще или никакое использование

connection_aborted () функционируют от PHP (В нескольких словах, если сценарий PHP все еще работает),

Теперь проблема:

NginX имеет по умолчанию fastcgi_buffering на; и это вызывает мне проблему, когда я вручаю фильмы клиентам. Когда я хочу служить, Живая Потоковая передача Регистрирует, это прекрасно, так как я хочу, чтобы некоторые буферы уменьшили возможности для задержки к произошедшему, в то время как PHP читает содержание живых файлов потоковой передачи.

Но в фильмах это просто анализирует весь фильм (даже если это - 2 ГБ), непосредственно к буферам, и не может предсказать, получил ли клиент ответ или нет. Концы сценария PHP через только секунду и затем nginx вручают фильм клиенту так файл регистрации соединений, я говорил о том, прежде чем был закончен в течение одной секунды.

Если я выключаю fastcgi_buffering; все работает, как я хочу, но я видел некоторые задержки в Живом Обслуживании Потоковой передачи.

Лучшее должно было бы иметь fastcgi_buffering на; в прямых трансляциях и fastcgi_buffering прочь; в фильмах. Но у меня нет действительно идеи, как сделать это.

Я попробовал (верный) ob_implicit_flush; но это не работает ни один с NginX, я думаю. На самом деле я не могу играть ни с каким сбросом () функцию и т.д.

Потоковая передача Файл PHP использует следующую технику, чтобы отправить видеофайл клиенту

<?php

# $video_file can be either a live stream or movie file.

$bytes = 0;

$stream = fopen( $video_file, "rb" );

while ( ! feof( $stream ) && ClientConnected() )
{
    $response = stream_get_line( $stream, 8192 );
    $bytes += strlen( $response );
    echo $response;
}

fclose( $stream );

/*
    $bytes have been sent
    In movie files the bytes directly goes to the filesize of movie file if fastcgi_buffering is on. 
*/

function ClientConnected()
{
    if ( connection_status() != CONNECTION_NORMAL || connection_aborted() )
    {
        return false;
    }

    return true;
}
?>
1
задан 15 July 2014 в 13:53
1 ответ

Проблема в том, что PHP не знает о состоянии соединения с клиентом, буферах и т.д., необходимых для потоковой передачи.

Опции nginx fastcgi_buffer* имеют смысл только для nginx, они указывают только размер входного буфера nginx для данных, поступающих через интерфейс FastCGI.

Если входные (в вашем случае - потоковые) данные, поступающие через FastCGI, больше буферов памяти, выделенных директивами, то nginx хранит вывод во временном файле на диске.

Вы можете попробовать реализовать ручные задержки на стороне PHP, но так как вы не знаете о состоянии клиентского потока, вы не можете реализовать эти задержки точно.

Если ваше видео закодировано в MPEG4, то я рекомендую использовать ngx_http_mp4_module. Это реализует потоковое видео непосредственно внутри nginx.

.
0
ответ дан 4 December 2019 в 08:35

Теги

Похожие вопросы