(因为它包含一些编码,但也是关于nginxconfiguration,我认为这将是最好的在serverfault)。
我有我的服务器中的一些video文件存储在我的文件系统内的文件夹中,我正在使用PHP来读取video文件,并直接发送给使用NginX作为WebServer的用户。
大部分video文件都是使用FFmpeg生成的实时stream ,但我也有一些电影 。
实况stream文件 :有分裂成段和PHP我读了m3u8文件,我得到* .ts文件,而我正在使用PHPstream媒体,而FFmpeg仍然在后台运行。
电影文件 :只有一个静态文件
我有一些关于nginx / phpconfiguration的问题。
我的NginXconfiguration如下:
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; } }
对于每一个从我的服务器上读取video文件的客户端,我login连接,我可以预测他是否仍然在线或没有使用
PHP中的connection_aborted()函数(简单来说,如果php脚本仍在运行)
现在的问题:
Nginx默认fastcgi_buffering; 当我向客户提供电影时,这就给我造成了一个问题。 当我想要为Live Streaming文件提供服务时,这很好,因为我想要一些缓冲区来减lessPHP在读取实时stream文件内容时发生滞后的机会。
但是在电影中,它只是将整个电影(即使是2GB)直接parsing到缓冲区,并且无法预测客户端是否得到响应或不响应。 php脚本在一秒之内结束,然后nginx将电影提供给客户端,所以我之前提到的连接日志已经在一秒之内结束了。
如果我把fastcgi_bufferingclosures; 一切工作正如我想,但我看到现场直播服务的一些滞后。
最好的办法是有fastcgi_buffering; 在直播和fastcgi_bufferingclosures; 在电影里。 但我真的不知道该怎么做。
我试过ob_implicit_flush(true); 但是这不能与NginX的工作,我认为。 事实上,我不能玩任何flush()函数等
stream式PHP文件使用以下技术将video文件发送到客户端
<?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; } ?>
这里的问题是PHP不知道客户端连接状态,缓冲区等,这是stream媒体所需要的。
nginx fastcgi_buffer*选项仅对于nginx有意义,它们仅指定通过FastCGI接口发送的数据的nginxinput缓冲区大小。
如果通过FastCGI来的input(在你的情况下是stream数据)大于用指令分配的内存缓冲区,那么nginx将输出存储到磁盘上的一个临时文件。
您可以尝试在PHP端实现手动延迟,但是由于您不了解客户端stream式传输状态,因此无法准确执行延迟。
如果您的video使用MPEG4编码,我build议您使用ngx_http_mp4_module 。 这实现了直接在nginx里面的stream媒体video。