1

我有一个正在输出音频文件的后台 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 启动并在此处捕获输出。

4

1 回答 1

0

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.dat并且out.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。

于 2013-09-07T06:32:18.820 回答