NGINX-服务于电影的PHP-FPM寻求&连接手柄 [英] NGINX - PHP-FPM Serving Movies Seek & Connection Handle

查看:85
本文介绍了NGINX-服务于电影的PHP-FPM寻求&连接手柄的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在运行PHP-FPM 5.6和Nginx 1.7.6.

I'm running PHP-FPM 5.6 and Nginx 1.7.6.

我正在使用PHP文件提供Matroska/Mp4电影.代码为:

<?php
register_shutdown_function( 'shutdown' );

$request = 'movie.mp4';

header( 'X-Accel-Buffering: no' ); //avoid nginx buffering.
header( 'Content-type: video/mp4' );

if ( file_exists( $request ) )
{

    $fp = @fopen( $request, 'rb' );

    $size = filesize( $request ); // File size
    $length = $size; // Content length
    $start = 0; // Start byte
    $end = $size - 1; // End byte
    header( "Accept-Ranges: 0-$length" );
    if ( isset( $_SERVER['HTTP_RANGE'] ) )
    {

        $c_start = $start;
        $c_end = $end;

        list( , $range ) = explode( '=', $_SERVER['HTTP_RANGE'], 2 );
        if ( strpos( $range, ',' ) !== false )
        {
            header( 'HTTP/1.1 416 Requested Range Not Satisfiable' );
            header( "Content-Range: bytes $start-$end/$size" );
            exit;
        }
        if ( $range == '-' )
        {
            $c_start = $size - substr( $range, 1 );
        }
        else
        {
            $range = explode( '-', $range );
            $c_start = $range[0];
            $c_end = ( isset( $range[1] ) && is_numeric( $range[1] ) ) ? $range[1] : $size;
        }
        $c_end = ( $c_end > $end ) ? $end : $c_end;
        if ( $c_start > $c_end || $c_start > $size - 1 || $c_end >= $size )
        {
            header( 'HTTP/1.1 416 Requested Range Not Satisfiable' );
            header( "Content-Range: bytes $start-$end/$size" );
            exit;
        }
        $start = $c_start;
        $end = $c_end;
        $length = $end - $start + 1;
        fseek( $fp, $start );
        header( 'HTTP/1.1 206 Partial Content' );
    }

    header( "Content-Range: bytes $start-$end/$size" );
    header( "Content-Length: " . $length );
    ob_end_flush();


    $buffer = 1024 * 8;
    while ( ! feof( $fp ) && ClientConnected() && ( $p = ftell( $fp ) ) <= $end )
    {
        $response = stream_get_line( $fp, $buffer );
        echo $response;

    }

    fclose( $fp );
}

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

    return true;
}


function shutdown()
{
    //main cause of problems is that line
    //posix_kill( getmypid(), 9 );
}

您会注意到上面的脚本支持接受范围,因此用户可以观看电影该功能与电影本身一样完美.通过访问该文件,我可以从播放器上观看电影,完全没有任何问题.

You will notice that the above script has support of Accept ranges so a user can seek into the movie! That feature works perfectly as well as the movie itself. I can see the movie from my player by accessing that file without any problems at all.

问题出在关机功能上.您可能会问为什么我要使用posix_kill并杀死php pid.

The problem is in the shutdown function. You may ask why i want to use posix_kill and kill the php pid.

用户可以选择从我的应用程序中观看多部电影.用户对可以打开我的服务器的连接有LIMIT个限制.这意味着,如果用户有1个可用插槽来连接到服务器,则他将只能一次打开一部电影.

User has the option to select multiple movies to see from my application. A user has LIMIT to connections that can be opened to my server. That means if a user has 1 available slots to connect to the server he will be able to open only one movie at once.

基于这个原因,假设用户当前正在观看电影,而他想将当前电影ZAP(更改)为另一部电影.

For that reason, let's say that a user is currently watching a Movie and he wants to ZAP (change) the current movie to another one.

他将无法执行此操作,因为旧的连接不会很快结束,并且pid还会保持打开状态几秒钟.

He won't be able to do that, because the old connection will not be ended fast and the pid will remain open for some seconds more.

如果我们取消注释上面代码的//posix_kill行,则用户将完全看不到任何电影,因为posix_kill函数会覆盖所有上面的标头,nginx/php不会发送我在文件中包含的标头.

If we uncomment the //posix_kill line of the above code the user won't be able to see any movie at all because somehow the posix_kill function override all the above headers and the nginx/php does not send the headers i have in the file.

但是,如果我按照说明禁用了HTTP SEEK并启用posix_kill,则用户将能够观看电影,但他将无法搜索.之所以发生这种情况,是因为当我们有了Accept-Ranges标头时,播放器会在打开电影之前对电影进行多次请求.

However, if i DISABLE the HTTP SEEK and enable the posix_kill as explained, user will be able to watch movies BUT he wont be able to seek . This is happening because when we have the Accept-Ranges header, players are doing multiple requests to the movie before opening it.

因此,例如,玩家将对该PHP文件发出2-3个请求,以了解并识别搜索.但是,Posix_kill将快速杀死那些pid,并且玩家将无法获得正确的标头.

So for example, a player will do 2-3 requests to that PHP File to understand and identify the seek. Posix_kill however will kill those pids fast, and the player wont be able to take the right headers.

因此,我们希望有一个解决方案,该解决方案将在用户关闭连接但保留查找支持时立即删除服务器中连接的PID.

So, we want a solution that will make the PID of the connection in the server to be dropped instantly when the user closes the connection but remain the seek support.

PS.上面启用了posix_kill的代码可以在实时流媒体上正常运行,因为我们没有查找到的内容,因此播放器只会发出一个请求.

希望你能理解我 谢谢

推荐答案

如果您没有任何安全问题.比起使用nginx的mp4模块.它可以将您用作mp4的伪流.在此之后,您不需要php来寻找电影的任何部分. Nginx Handel本身.

If you don't have any security issue. Than use mp4 module of nginx. It working you as pseudo streaming for mp4. After this you don't need php to seek movie on any part. Nginx handel itself.

这篇关于NGINX-服务于电影的PHP-FPM寻求&amp;连接手柄的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆