如何以编程方式启动/停止FFMPEG流转码 [英] How to programmatically start/stop FFMPEG stream transcoding

查看:998
本文介绍了如何以编程方式启动/停止FFMPEG流转码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个提供MJPEG流的IP网络摄像头.我可以在OSX下使用ffmpeg成功转码并保存该流.以下是我想要的东西:

I have an ip webcam which provides an MJPEG stream. I can successfully transcode and save that stream with ffmpeg under OSX. The following gives me pretty much what I want:

ffmpeg -f mjpeg -i "http://user:pass@10.0.1.200/nphMotionJpeg?Resolution=640x480&Quality=Standard" -b:v 1500k -vcodec libx264 /tmp/test.mp4

这将启动FFMPEG会话,并开始将实时流保存到我的test.mp4文件中.按q将退出ffmpeg并保存文件.

That will start an FFMPEG session and begin saving the live stream to my test.mp4 file. pressing q will quit ffmpeg and save the file.

我想以编程方式启动&使用PHP或Bash Shell脚本停止录制.我尝试了以下方法:

I would like to programmatically start & stop the recording using a PHP or Bash shell script. I have tried the following:

<?php

$pid = pcntl_fork();

if($pid == -1){
    die("could not fork"); 
}elseif($pid){
    // we are the parent...
    print $pid.' started recording. waiting 10 seconds...';
    sleep(10); // Wait 10 seconds

    print_r(shell_exec("kill ".$pid)); // Kill the child recording process

    echo 'done';
    exit(); 
}else{
    // we are the child process. call ffmpeg.
    exec('../lib/ffmpeg -f mjpeg -i "http://user:pass@10.0.1.200/nphMotionJpeg?Resolution=640x480&Quality=Standard" -b:v 1500k -vcodec libx264 /tmp/test.mp4');
}

但是有两个问题:

  1. ffmpeg进程没有结束/死亡(可能是因为它再次分叉了)
  2. 当我手动终止ffmpeg进程时,视频文件不可读

推荐答案

所以我做错了很多事情.

So I was doing a combination of things wrong.

对于初学者来说,我需要将ffmpeg的输出格式推送到日志文件,并告诉它覆盖临时文件,而无需使用-y参数提示.

For starters, I needed to push the output form ffmpeg to a log file and also tell it to overwrite my temp file without prompting using the -y argument.

所以不是

ffmpeg -f mjpeg -i "http://user:pass@10.0.1.200/nphMotionJpeg?Resolution=640x480&Quality=Standard" -b:v 1500k -vcodec libx264 /tmp/test.mp4

我正在使用

ffmpeg -y -f mjpeg -i "http://user:pass@10.0.1.200/nphMotionJpeg?Resolution=640x480&Quality=Standard" -b:v 1500k -vcodec libx264 /tmp/test.mp4 </dev/null >/dev/null 2>/tmp/ffmpeg.log &

第二个问题是在将kill命令发送给ffmpeg之前,我等待的时间不够长,因此正在创建损坏的文件.

The second problem was that I wasn't waiting long enough before sending the kill command to ffmpeg, and so a corrupt file was being created.

通过将-t(用于时间限制)参数加上1秒,我确定ffmpeg记录一秒钟的视频平均需要15秒.将时间限制增加到10秒,平均时间增加到25秒,因此看来,至少在我的服务器上,有14秒的开销.通过将我的php脚本中的sleep命令增加到30秒,我可以获得一个可用的视频文件.

By adding the -t (for time limit) argument with 1 second, I determined that it takes an average of 15 seconds for ffmpeg to record 1 second of video. Increasing the time limit to 10 seconds made the average increase to 25 seconds, so it seems that on my server at least, theres 14 seconds of overhead. By increasing my sleep command in my php script to 30 seconds, I was able to get a useable video file.

因此,用PHP杀死ffmpeg进程会导致未知的记录时间长度(或最佳近似值),而记录时间长度完全取决于CPU功率,网络带宽等.

So having PHP kill the ffmpeg process results in an unknown (or approximate at best) recording time length which is completely dependent on CPU power, network bandwidth, etc.

那真是太糟糕了,因为我希望能够根据某些外部变量来增加记录长度(我有insteon运动传感器为数据库提供数据,我想进行记录直到运动停止).

Thats a bit of a bummer because I had hoped to be able to increase the recording length depending on some external variables (I have insteon motion sensors feeding a database, i would like to record until the motion stops).

无论如何,这是一个有效的PHP脚本,以防将来对某人有所帮助:

In any event, here is a working PHP script in case it helps someone in the future:

<?php
print date('H:i:s')."\nStarted recording. waiting 60 seconds...\n";
exec('../lib/ffmpeg -y -f mjpeg -i "http://user:pass@10.0.1.200/nphMotionJpeg?Resolution=640x480&Quality=Standard" -b:v 1500k -vcodec libx264 /tmp/test.mp4 </dev/null >/dev/null 2>/tmp/ffmpeg.log &');
sleep(60); // Wait long enough before killing, otherwise the video will be corrupt!

shell_exec('pkill ffmpeg'); // find and kill    
echo "done\n\n";
exit(); 
?>

这篇关于如何以编程方式启动/停止FFMPEG流转码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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