ffmpeg可以显示进度条吗?

时间:2023-01-16 12:00:34

I am converting a .avi file to .flv file using ffmpeg. As it takes a long time to convert a file I would like to display a progress bar. Can someone please guide me on how to go about the same.

我正在使用ffmpeg将.avi文件转换为.flv文件。由于转换文件需要很长时间,我想显示进度条。有人可以指导我如何去做同样的事情。

I know that ffmpeg somehow has to output the progress in a text file and I have to read it using ajax calls. But how do I get ffmpeg to output the progress to the text file?

我知道ffmpeg不得不在文本文件中输出进度,我必须使用ajax调用来读取它。但是如何让ffmpeg将进度输出到文本文件?

Thank you very much.

非常感谢你。

9 个解决方案

#1


I've been playing around with this for a few days. That "ffmpegprogress" thing helped, but it was very hard to get to work with my set up, and hard to read the code.

我已经玩了好几天了。那个“ffmpegprogress”的东西有所帮助,但很难用我的设置工作,并且很难阅读代码。

In order to show the progress of ffmpeg you need to do the following:

为了显示ffmpeg的进度,您需要执行以下操作:

  1. run the ffmpeg command from php without it waiting for a response (for me, this was the hardest part)
  2. 从php运行ffmpeg命令而不等待响应(对我来说,这是最难的部分)

  3. tell ffmpeg to send it's output to a file
  4. 告诉ffmpeg将其输出发送到文件

  5. from the front end (AJAX, Flash, whatever) hit either that file directly or a php file that can pull out the progress from ffmpeg's output.
  6. 从前端(AJAX,Flash,无论如何)直接命中该文件或者可以从ffmpeg的输出中取出进度的php文件。

Here's how I solved each part:

以下是我解决每个部分的方法:

1. I got the following idea from "ffmpegprogress". This is what he did: one PHP file calls another through an http socket. The 2nd one actually runs the "exec" and the first file just hangs up on it. For me his implementation was too complex. He was using "fsockopen". I like CURL. So here's what I did:

我从“ffmpegprogress”得到了以下想法。这就是他所做的:一个PHP文件通过http套接字调用另一个。第二个实际运行“exec”,第一个文件挂起就可以了。对我来说,他的实施过于复杂。他正在使用“fsockopen”。我喜欢CURL。所以这就是我做的:

$url = "http://".$_SERVER["HTTP_HOST"]."/path/to/exec/exec.php";
curl_setopt($curlH, CURLOPT_URL, $url);
$postData = "&cmd=".urlencode($cmd);
$postData .= "&outFile=".urlencode("path/to/output.txt");
curl_setopt($curlH, CURLOPT_POST, TRUE);
curl_setopt($curlH, CURLOPT_POSTFIELDS, $postData);

curl_setopt($curlH, CURLOPT_RETURNTRANSFER, TRUE);

// # this is the key!
curl_setopt($curlH, CURLOPT_TIMEOUT, 1);
$result = curl_exec($curlH);

Setting CURLOPT_TIMEOUT to 1 means it will wait 1 second for a response. Preferably that would be lower. There is also the CURLOPT_TIMEOUT_MS which takes milliseconds, but it didn't work for me.

将CURLOPT_TIMEOUT设置为1意味着它将等待1秒钟以进行响应。优选地,这将更低。还有CURLOPT_TIMEOUT_MS需要几毫秒,但它对我不起作用。

After 1 second, CURL hangs up, but the exec command still runs. Part 1 solved.

1秒后,CURL挂起,但exec命令仍然运行。第1部分解决了。

BTW - A few people were suggesting using the "nohup" command for this. But that didn't seem to work for me.

顺便说一句 - 有些人建议使用“nohup”命令。但这似乎对我不起作用。

*ALSO! Having a php file on your server that can execute code directly on the command line is an obvious security risk. You should have a password, or encode the post data in some way.

*也!在您的服务器上有一个可以直接在命令行上执行代码的php文件是一个明显的安全风险。您应该有密码,或以某种方式编码帖子数据。

2. The "exec.php" script above must also tell ffmpeg to output to a file. Here's code for that:

2.上面的“exec.php”脚本还必须告诉ffmpeg输出到文件。这是代码:

exec("ffmpeg -i path/to/input.mov path/to/output.flv 1> path/to/output.txt 2>&1");

Note the "1> path/to/output.txt 2>&1". I'm no command line expert, but from what I can tell this line says "send normal output to this file, AND send errors to the same place". Check out this url for more info: http://tldp.org/LDP/abs/html/io-redirection.html

注意“1> path / to / output.txt 2>&1”。我不是命令行专家,但从我能说的这句话说“将正常输出发送到此文件,并将错误发送到同一个地方”。查看此网址以获取更多信息:http://tldp.org/LDP/abs/html/io-redirection.html

3. From the front end call a php script giving it the location of the output.txt file. That php file will then pull out the progress from the text file. Here's how I did that:

3.从前端调用一个php脚本,为它提供output.txt文件的位置。那个php文件将从文本文件中取出进度。这是我如何做到的:

// # get duration of source
preg_match("/Duration: (.*?), start:/", $content, $matches);

$rawDuration = $matches[1];

// # rawDuration is in 00:00:00.00 format. This converts it to seconds.
$ar = array_reverse(explode(":", $rawDuration));
$duration = floatval($ar[0]);
if (!empty($ar[1])) $duration += intval($ar[1]) * 60;
if (!empty($ar[2])) $duration += intval($ar[2]) * 60 * 60;


// # get the current time
preg_match_all("/time=(.*?) bitrate/", $content, $matches); 

$last = array_pop($matches);
// # this is needed if there is more than one match
if (is_array($last)) {
    $last = array_pop($last);
}

$curTime = floatval($last);


// # finally, progress is easy
$progress = $curTime/$duration;

Hope this helps someone.

希望这有助于某人。

#2


There is an article in Russian which describes how to solve your problem.

俄语中有一篇文章描述了如何解决您的问题。

The point is to catch Duration value before encoding and to catch time=... values during encoding.

重点是在编码之前捕获持续时间值并在编码期间捕获time = ...值。

--skipped--
Duration: 00:00:24.9, start: 0.000000, bitrate: 331 kb/s
--skipped--
frame=   41 q=7.0 size=     116kB time=1.6 bitrate= 579.7kbits/s
frame=   78 q=12.0 size=     189kB time=3.1 bitrate= 497.2kbits/s
frame=  115 q=13.0 size=     254kB time=4.6 bitrate= 452.3kbits/s
--skipped--

#3


FFmpeg uses stdout for outputing media data and stderr for logging/progress information. You just have to redirect stderr to a file or to stdin of a process able to handle it.

FFmpeg使用stdout输出媒体数据,使用stderr输出日志/进度信息。您只需将stderr重定向到文件或能够处理它的进程的stdin。

With a unix shell this is something like:

使用unix shell时,这类似于:

ffmpeg {ffmpeg arguments} 2> logFile

or

ffmpeg {ffmpeg arguments} 2| processFFmpegLog

Anyway, you have to run ffmpeg as a separate thread or process.

无论如何,您必须将ffmpeg作为单独的线程或进程运行。

#4


It’s very simple if you use the pipeview command. To do this, transform

如果使用pipeview命令,则非常简单。要做到这一点,转换

ffmpeg -i input.avi {arguments}

to

pv input.avi | ffmpeg -i pipe:0 -v warning {arguments}

No need to get into coding!

无需编码!

#5


You can do it with ffmpeg's -progress argument and nc

你可以用ffmpeg的-progress参数和nc来做

WATCHER_PORT=9998

DURATION= $(ffprobe -select_streams v:0 -show_entries "stream=duration" \
    -of compact $INPUT_FILE | sed 's!.*=\(.*\)!\1!g')

nc -l $WATCHER_PORT | while read; do
    sed -n 's/out_time=\(.*\)/\1 of $DURATION/p')
done &

ffmpeg -y -i $INPUT_FILE -progress localhost:$WATCHER_PORT $OUTPUT_ARGS

#6


javascript should tell php to start converting [1] and then do [2] ...

javascript应该告诉php开始转换[1]然后做[2] ...


[1] php: start conversion and write status to file (see above):

[1] php:启动转换并将状态写入文件(参见上文):

exec("ffmpeg -i path/to/input.mov path/to/output.flv 1>path/to/output.txt 2>&1");

For the second part we need just javascript to read the file. The following example uses dojo.request for AJAX, but you could use jQuery or vanilla or whatever as well :

对于第二部分,我们只需要javascript来读取文件。以下示例使用dojo.request进行AJAX,但您可以使用jQuery或vanilla或其他任何东西:

[2] js: grab the progress from the file:

[2] js:从文件中获取进度:

var _progress = function(i){
    i++;
    // THIS MUST BE THE PATH OF THE .txt FILE SPECIFIED IN [1] : 
    var logfile = 'path/to/output.txt';

/* (example requires dojo) */

request.post(logfile).then( function(content){
// AJAX success
    var duration = 0, time = 0, progress = 0;
    var resArr = [];

    // get duration of source
    var matches = (content) ? content.match(/Duration: (.*?), start:/) : [];
    if( matches.length>0 ){
        var rawDuration = matches[1];
        // convert rawDuration from 00:00:00.00 to seconds.
        var ar = rawDuration.split(":").reverse();
        duration = parseFloat(ar[0]);
        if (ar[1]) duration += parseInt(ar[1]) * 60;
        if (ar[2]) duration += parseInt(ar[2]) * 60 * 60;

        // get the time 
        matches = content.match(/time=(.*?) bitrate/g);
        console.log( matches );

        if( matches.length>0 ){
            var rawTime = matches.pop();
            // needed if there is more than one match
            if (lang.isArray(rawTime)){ 
                rawTime = rawTime.pop().replace('time=','').replace(' bitrate',''); 
            } else {
                rawTime = rawTime.replace('time=','').replace(' bitrate','');
            }

            // convert rawTime from 00:00:00.00 to seconds.
            ar = rawTime.split(":").reverse();
            time = parseFloat(ar[0]);
            if (ar[1]) time += parseInt(ar[1]) * 60;
            if (ar[2]) time += parseInt(ar[2]) * 60 * 60;

            //calculate the progress
            progress = Math.round((time/duration) * 100);
        }

        resArr['status'] = 200;
        resArr['duration'] = duration;
        resArr['current']  = time;
        resArr['progress'] = progress;

        console.log(resArr);

        /* UPDATE YOUR PROGRESSBAR HERE with above values ... */

        if(progress==0 && i>20){
            // TODO err - giving up after 8 sec. no progress - handle progress errors here
            console.log('{"status":-400, "error":"there is no progress while we tried to encode the video" }'); 
            return;
        } else if(progress<100){ 
            setTimeout(function(){ _progress(i); }, 400);
        }
    } else if( content.indexOf('Permission denied') > -1) {
        // TODO - err - ffmpeg is not executable ...
        console.log('{"status":-400, "error":"ffmpeg : Permission denied, either for ffmpeg or upload location ..." }');    
    } 
},
function(err){
// AJAX error
    if(i<20){
        // retry
        setTimeout(function(){ _progress(0); }, 400);
    } else {
        console.log('{"status":-400, "error":"there is no progress while we tried to encode the video" }');
        console.log( err ); 
    }
    return; 
});

}
setTimeout(function(){ _progress(0); }, 800);

#7


Calling php's system function blocks that thread, so you'll need to spawn off 1 HTTP request for performing the conversion, and another polling one for reading the txt file, that's being generated.

调用php的系统函数会阻塞该线程,因此您需要生成1个HTTP请求来执行转换,另一个轮询用于读取正在生成的txt文件。

Or, better yet, clients submit the video for conversion and then another process is made responsible for performing the conversion. That way the client's connection won't timeout while waiting for the system call to terminate. Polling is done in the same way as above.

或者,更好的是,客户提交视频进行转换,然后另一个流程负责执行转换。这样,在等待系统调用终止时,客户端的连接不会超时。轮询以与上述相同的方式完成。

#8


Had problems with the second php part. So I am using this instead:

有第二个PHP部分的问题。所以我改用它:

    $log = @file_get_contents($txt);
    preg_match("/Duration:([^,]+)/", $log, $matches);
    list($hours,$minutes,$seconds,$mili) = split(":",$matches[1]);
    $seconds = (($hours * 3600) + ($minutes * 60) + $seconds);
    $seconds = round($seconds);

    $page = join("",file("$txt"));
    $kw = explode("time=", $page);
    $last = array_pop($kw);
    $values = explode(' ', $last);
    $curTime = round($values[0]);
    $percent_extracted = round((($curTime * 100)/($seconds)));

Outputs perfectly.

Would like to see something for multiple uploads for another progress bar. This passing for the current file for one percentage. Then an overall progress bar. Almost there.

希望看到有关多个上传内容的其他进度条。这传递给当前文件一个百分比。然后是整体进度条。差不多了。

Also, if people are having a hard time getting:

此外,如果人们很难获得:

exec("ffmpeg -i path/to/input.mov path/to/output.flv 1> path/to/output.txt 2>&1");

To work.

Try:

exec("ffmpeg -i path/to/input.mov path/to/output.flv 1>path/to/output.txt 2>&1");

"1> path" to "1>path" OR "2> path" to "2>path"

“1>路径”到“1>路径”或“2>路径”到“2>路径”

Took me awhile to figure it out. FFMPEG kept failing. Worked when I changed to no space.

我花了一段时间来搞清楚。 FFMPEG一直在失败。当我改为无空间时工作。

#9


Sadly, ffmpeg itself still cannot show a progress bar – also, many of the aforementioned bash- or python-based stop-gap solutions have become dated and nonfunctional.

可悲的是,ffmpeg本身仍然无法显示进度条 - 此外,许多上述基于bash或python的止损解决方案已经过时且无法正常运行。

Thus, i recommend giving the brand-new ffmpeg-progressbar-cli a try:

因此,我建议尝试全新的ffmpeg-progressbar-cli:

ffmpeg可以显示进度条吗?

It's a wrapper for the ffmpeg executable, showing a colored, centered progress bar and the remaining time.

它是ffmpeg可执行文件的包装器,显示彩色的,居中的进度条和剩余时间。

Also, it's open-source, based on Node.js and actively developed, handling most of the mentioned quirks (full disclosure: i'm its current lead developer).

此外,它是开源的,基于Node.js并积极开发,处理大多数提到的怪癖(完全披露:我是它目前的首席开发人员)。

#1


I've been playing around with this for a few days. That "ffmpegprogress" thing helped, but it was very hard to get to work with my set up, and hard to read the code.

我已经玩了好几天了。那个“ffmpegprogress”的东西有所帮助,但很难用我的设置工作,并且很难阅读代码。

In order to show the progress of ffmpeg you need to do the following:

为了显示ffmpeg的进度,您需要执行以下操作:

  1. run the ffmpeg command from php without it waiting for a response (for me, this was the hardest part)
  2. 从php运行ffmpeg命令而不等待响应(对我来说,这是最难的部分)

  3. tell ffmpeg to send it's output to a file
  4. 告诉ffmpeg将其输出发送到文件

  5. from the front end (AJAX, Flash, whatever) hit either that file directly or a php file that can pull out the progress from ffmpeg's output.
  6. 从前端(AJAX,Flash,无论如何)直接命中该文件或者可以从ffmpeg的输出中取出进度的php文件。

Here's how I solved each part:

以下是我解决每个部分的方法:

1. I got the following idea from "ffmpegprogress". This is what he did: one PHP file calls another through an http socket. The 2nd one actually runs the "exec" and the first file just hangs up on it. For me his implementation was too complex. He was using "fsockopen". I like CURL. So here's what I did:

我从“ffmpegprogress”得到了以下想法。这就是他所做的:一个PHP文件通过http套接字调用另一个。第二个实际运行“exec”,第一个文件挂起就可以了。对我来说,他的实施过于复杂。他正在使用“fsockopen”。我喜欢CURL。所以这就是我做的:

$url = "http://".$_SERVER["HTTP_HOST"]."/path/to/exec/exec.php";
curl_setopt($curlH, CURLOPT_URL, $url);
$postData = "&cmd=".urlencode($cmd);
$postData .= "&outFile=".urlencode("path/to/output.txt");
curl_setopt($curlH, CURLOPT_POST, TRUE);
curl_setopt($curlH, CURLOPT_POSTFIELDS, $postData);

curl_setopt($curlH, CURLOPT_RETURNTRANSFER, TRUE);

// # this is the key!
curl_setopt($curlH, CURLOPT_TIMEOUT, 1);
$result = curl_exec($curlH);

Setting CURLOPT_TIMEOUT to 1 means it will wait 1 second for a response. Preferably that would be lower. There is also the CURLOPT_TIMEOUT_MS which takes milliseconds, but it didn't work for me.

将CURLOPT_TIMEOUT设置为1意味着它将等待1秒钟以进行响应。优选地,这将更低。还有CURLOPT_TIMEOUT_MS需要几毫秒,但它对我不起作用。

After 1 second, CURL hangs up, but the exec command still runs. Part 1 solved.

1秒后,CURL挂起,但exec命令仍然运行。第1部分解决了。

BTW - A few people were suggesting using the "nohup" command for this. But that didn't seem to work for me.

顺便说一句 - 有些人建议使用“nohup”命令。但这似乎对我不起作用。

*ALSO! Having a php file on your server that can execute code directly on the command line is an obvious security risk. You should have a password, or encode the post data in some way.

*也!在您的服务器上有一个可以直接在命令行上执行代码的php文件是一个明显的安全风险。您应该有密码,或以某种方式编码帖子数据。

2. The "exec.php" script above must also tell ffmpeg to output to a file. Here's code for that:

2.上面的“exec.php”脚本还必须告诉ffmpeg输出到文件。这是代码:

exec("ffmpeg -i path/to/input.mov path/to/output.flv 1> path/to/output.txt 2>&1");

Note the "1> path/to/output.txt 2>&1". I'm no command line expert, but from what I can tell this line says "send normal output to this file, AND send errors to the same place". Check out this url for more info: http://tldp.org/LDP/abs/html/io-redirection.html

注意“1> path / to / output.txt 2>&1”。我不是命令行专家,但从我能说的这句话说“将正常输出发送到此文件,并将错误发送到同一个地方”。查看此网址以获取更多信息:http://tldp.org/LDP/abs/html/io-redirection.html

3. From the front end call a php script giving it the location of the output.txt file. That php file will then pull out the progress from the text file. Here's how I did that:

3.从前端调用一个php脚本,为它提供output.txt文件的位置。那个php文件将从文本文件中取出进度。这是我如何做到的:

// # get duration of source
preg_match("/Duration: (.*?), start:/", $content, $matches);

$rawDuration = $matches[1];

// # rawDuration is in 00:00:00.00 format. This converts it to seconds.
$ar = array_reverse(explode(":", $rawDuration));
$duration = floatval($ar[0]);
if (!empty($ar[1])) $duration += intval($ar[1]) * 60;
if (!empty($ar[2])) $duration += intval($ar[2]) * 60 * 60;


// # get the current time
preg_match_all("/time=(.*?) bitrate/", $content, $matches); 

$last = array_pop($matches);
// # this is needed if there is more than one match
if (is_array($last)) {
    $last = array_pop($last);
}

$curTime = floatval($last);


// # finally, progress is easy
$progress = $curTime/$duration;

Hope this helps someone.

希望这有助于某人。

#2


There is an article in Russian which describes how to solve your problem.

俄语中有一篇文章描述了如何解决您的问题。

The point is to catch Duration value before encoding and to catch time=... values during encoding.

重点是在编码之前捕获持续时间值并在编码期间捕获time = ...值。

--skipped--
Duration: 00:00:24.9, start: 0.000000, bitrate: 331 kb/s
--skipped--
frame=   41 q=7.0 size=     116kB time=1.6 bitrate= 579.7kbits/s
frame=   78 q=12.0 size=     189kB time=3.1 bitrate= 497.2kbits/s
frame=  115 q=13.0 size=     254kB time=4.6 bitrate= 452.3kbits/s
--skipped--

#3


FFmpeg uses stdout for outputing media data and stderr for logging/progress information. You just have to redirect stderr to a file or to stdin of a process able to handle it.

FFmpeg使用stdout输出媒体数据,使用stderr输出日志/进度信息。您只需将stderr重定向到文件或能够处理它的进程的stdin。

With a unix shell this is something like:

使用unix shell时,这类似于:

ffmpeg {ffmpeg arguments} 2> logFile

or

ffmpeg {ffmpeg arguments} 2| processFFmpegLog

Anyway, you have to run ffmpeg as a separate thread or process.

无论如何,您必须将ffmpeg作为单独的线程或进程运行。

#4


It’s very simple if you use the pipeview command. To do this, transform

如果使用pipeview命令,则非常简单。要做到这一点,转换

ffmpeg -i input.avi {arguments}

to

pv input.avi | ffmpeg -i pipe:0 -v warning {arguments}

No need to get into coding!

无需编码!

#5


You can do it with ffmpeg's -progress argument and nc

你可以用ffmpeg的-progress参数和nc来做

WATCHER_PORT=9998

DURATION= $(ffprobe -select_streams v:0 -show_entries "stream=duration" \
    -of compact $INPUT_FILE | sed 's!.*=\(.*\)!\1!g')

nc -l $WATCHER_PORT | while read; do
    sed -n 's/out_time=\(.*\)/\1 of $DURATION/p')
done &

ffmpeg -y -i $INPUT_FILE -progress localhost:$WATCHER_PORT $OUTPUT_ARGS

#6


javascript should tell php to start converting [1] and then do [2] ...

javascript应该告诉php开始转换[1]然后做[2] ...


[1] php: start conversion and write status to file (see above):

[1] php:启动转换并将状态写入文件(参见上文):

exec("ffmpeg -i path/to/input.mov path/to/output.flv 1>path/to/output.txt 2>&1");

For the second part we need just javascript to read the file. The following example uses dojo.request for AJAX, but you could use jQuery or vanilla or whatever as well :

对于第二部分,我们只需要javascript来读取文件。以下示例使用dojo.request进行AJAX,但您可以使用jQuery或vanilla或其他任何东西:

[2] js: grab the progress from the file:

[2] js:从文件中获取进度:

var _progress = function(i){
    i++;
    // THIS MUST BE THE PATH OF THE .txt FILE SPECIFIED IN [1] : 
    var logfile = 'path/to/output.txt';

/* (example requires dojo) */

request.post(logfile).then( function(content){
// AJAX success
    var duration = 0, time = 0, progress = 0;
    var resArr = [];

    // get duration of source
    var matches = (content) ? content.match(/Duration: (.*?), start:/) : [];
    if( matches.length>0 ){
        var rawDuration = matches[1];
        // convert rawDuration from 00:00:00.00 to seconds.
        var ar = rawDuration.split(":").reverse();
        duration = parseFloat(ar[0]);
        if (ar[1]) duration += parseInt(ar[1]) * 60;
        if (ar[2]) duration += parseInt(ar[2]) * 60 * 60;

        // get the time 
        matches = content.match(/time=(.*?) bitrate/g);
        console.log( matches );

        if( matches.length>0 ){
            var rawTime = matches.pop();
            // needed if there is more than one match
            if (lang.isArray(rawTime)){ 
                rawTime = rawTime.pop().replace('time=','').replace(' bitrate',''); 
            } else {
                rawTime = rawTime.replace('time=','').replace(' bitrate','');
            }

            // convert rawTime from 00:00:00.00 to seconds.
            ar = rawTime.split(":").reverse();
            time = parseFloat(ar[0]);
            if (ar[1]) time += parseInt(ar[1]) * 60;
            if (ar[2]) time += parseInt(ar[2]) * 60 * 60;

            //calculate the progress
            progress = Math.round((time/duration) * 100);
        }

        resArr['status'] = 200;
        resArr['duration'] = duration;
        resArr['current']  = time;
        resArr['progress'] = progress;

        console.log(resArr);

        /* UPDATE YOUR PROGRESSBAR HERE with above values ... */

        if(progress==0 && i>20){
            // TODO err - giving up after 8 sec. no progress - handle progress errors here
            console.log('{"status":-400, "error":"there is no progress while we tried to encode the video" }'); 
            return;
        } else if(progress<100){ 
            setTimeout(function(){ _progress(i); }, 400);
        }
    } else if( content.indexOf('Permission denied') > -1) {
        // TODO - err - ffmpeg is not executable ...
        console.log('{"status":-400, "error":"ffmpeg : Permission denied, either for ffmpeg or upload location ..." }');    
    } 
},
function(err){
// AJAX error
    if(i<20){
        // retry
        setTimeout(function(){ _progress(0); }, 400);
    } else {
        console.log('{"status":-400, "error":"there is no progress while we tried to encode the video" }');
        console.log( err ); 
    }
    return; 
});

}
setTimeout(function(){ _progress(0); }, 800);

#7


Calling php's system function blocks that thread, so you'll need to spawn off 1 HTTP request for performing the conversion, and another polling one for reading the txt file, that's being generated.

调用php的系统函数会阻塞该线程,因此您需要生成1个HTTP请求来执行转换,另一个轮询用于读取正在生成的txt文件。

Or, better yet, clients submit the video for conversion and then another process is made responsible for performing the conversion. That way the client's connection won't timeout while waiting for the system call to terminate. Polling is done in the same way as above.

或者,更好的是,客户提交视频进行转换,然后另一个流程负责执行转换。这样,在等待系统调用终止时,客户端的连接不会超时。轮询以与上述相同的方式完成。

#8


Had problems with the second php part. So I am using this instead:

有第二个PHP部分的问题。所以我改用它:

    $log = @file_get_contents($txt);
    preg_match("/Duration:([^,]+)/", $log, $matches);
    list($hours,$minutes,$seconds,$mili) = split(":",$matches[1]);
    $seconds = (($hours * 3600) + ($minutes * 60) + $seconds);
    $seconds = round($seconds);

    $page = join("",file("$txt"));
    $kw = explode("time=", $page);
    $last = array_pop($kw);
    $values = explode(' ', $last);
    $curTime = round($values[0]);
    $percent_extracted = round((($curTime * 100)/($seconds)));

Outputs perfectly.

Would like to see something for multiple uploads for another progress bar. This passing for the current file for one percentage. Then an overall progress bar. Almost there.

希望看到有关多个上传内容的其他进度条。这传递给当前文件一个百分比。然后是整体进度条。差不多了。

Also, if people are having a hard time getting:

此外,如果人们很难获得:

exec("ffmpeg -i path/to/input.mov path/to/output.flv 1> path/to/output.txt 2>&1");

To work.

Try:

exec("ffmpeg -i path/to/input.mov path/to/output.flv 1>path/to/output.txt 2>&1");

"1> path" to "1>path" OR "2> path" to "2>path"

“1>路径”到“1>路径”或“2>路径”到“2>路径”

Took me awhile to figure it out. FFMPEG kept failing. Worked when I changed to no space.

我花了一段时间来搞清楚。 FFMPEG一直在失败。当我改为无空间时工作。

#9


Sadly, ffmpeg itself still cannot show a progress bar – also, many of the aforementioned bash- or python-based stop-gap solutions have become dated and nonfunctional.

可悲的是,ffmpeg本身仍然无法显示进度条 - 此外,许多上述基于bash或python的止损解决方案已经过时且无法正常运行。

Thus, i recommend giving the brand-new ffmpeg-progressbar-cli a try:

因此,我建议尝试全新的ffmpeg-progressbar-cli:

ffmpeg可以显示进度条吗?

It's a wrapper for the ffmpeg executable, showing a colored, centered progress bar and the remaining time.

它是ffmpeg可执行文件的包装器,显示彩色的,居中的进度条和剩余时间。

Also, it's open-source, based on Node.js and actively developed, handling most of the mentioned quirks (full disclosure: i'm its current lead developer).

此外,它是开源的,基于Node.js并积极开发,处理大多数提到的怪癖(完全披露:我是它目前的首席开发人员)。