【问题标题】:Pushing file to web-browser while being written在写入时将文件推送到 Web 浏览器
【发布时间】:2013-09-07 14:53:04
【问题描述】:

我有一个正在输出音频文件的后台 ffmpeg 进程,我想将此文件推送到用户网络浏览器,同时 ffmpeg 继续写入该文件。我尝试了以下方法,但这会发送 0 字节文件。

// open the file in a binary mode
$fp = fopen($fname, 'rb');

// send the right headers
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($fname));
ob_end_clean();
fpassthru($fp);
exit;

ffmpeg 无法从 PHP/Python 启动并在此处捕获输出。

【问题讨论】:

    标签: php python linux file-io ffmpeg


    【解决方案1】:

    fpassthru 函数在这里无法完成这项工作。此外,还有一个知道文件何时完成的问题。

    文件读取功能在到达文件末尾时停止。如果有一个并发写入器增加了文件的长度,那么在看到 EOF 之前读取器会走多远是不确定的。另外,没有明确的方法——通过文件操作——知道文件写入是否完成。

    使用这样的循环(伪代码)尝试超时读取可能是可行的:

    LOOP
        READ bytes
        IF count read == 0
        THEN
            SLEEP briefly
            INCREMENT idle_count
        ELSE
            SET idle_count = 0
            WRITE
        END IF
    UNTIL ( idle_count == 10 )
    

    如果有帮助,我可以将其放入 PHP 代码中。

    这是使用两个文件执行此操作的 PHP 代码,in.datout.dat

    <?php
    
    $in_fp = fopen("./in.dat", "r");
    
    $out_fp = fopen("./out.dat", "w");
    
    $idle_count = 0;
    
    while ( $idle_count < 10 )
    {
        if ( $idle_count > 0 )
            sleep(1);
    
        $val = fread($in_fp, 4192);
        if ( ! $val )
        {
            $idle_count++;
        }
        else
        {
            $idle_count = 0;
            $rc = fwrite($out_fp, $val);
            if ( $rc != strlen($val) )
                die("error on writing of the output file\n");
        }
    }
    

    注意睡眠的奇数位置是为了防止在最后一次尝试读取后一秒进入睡眠。

    为此,我建议将空闲超时限制设置为高于 10。

    【讨论】:

    • ffmpeg 进程正在输出大小为 3-10MB 的文件,所以我猜您建议的解决方案应该可行。你能请。提供一个即插即用的示例供我尝试,谢谢。编辑:还有一件事,这将读取文件但不会实时将其推送给用户,对吗?
    • 实时推送。伪代码没有提到写入;我的错。我会把它放在那里。
    • 实时推送文件的价值我很清楚。 ffmpeg 和文件推送都是长时间运行的过程,因此最好同时进行。希望有一种更明确的方式来了解 ffmpeg 是以通用方式完成的。如果您可以修改 ffmpeg 进程(例如,向调用 ffmpeg 的脚本添加更多命令),那么标记文件将是一个不错的选择。然后你可以消除空闲检查,而是在它的位置添加一个“check-if-marker-file-exists”。
    • 情况是这样的 - ffmpeg command,我需要上述解决方案的唯一原因(我有一种强烈的感觉是解决这个问题的错误方法)是以某种方式验证输入文件不是由于上游 wget(在相当模式下)命令的错误导致零字节。
    • 有趣 - 我看不出它如何适合 PHP,因为那里没有零字节大小检查。如果是这种情况,标志文件可能是通知 PHP 脚本 ffmpeg 处理完成的最佳方式。
    猜你喜欢
    • 2013-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-18
    • 1970-01-01
    • 2016-07-08
    相关资源
    最近更新 更多