我有一个提供MJPEG流的ip网络摄像头。我可以在OSX下使用ffmpeg成功转码并保存该流。以下几乎给了我想要的东西:
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并保存文件。
我想以编程方式启动&使用PHP或Bash shell脚本停止录制。我尝试过以下方法:
<?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');
}
但有两个问题:
答案 0 :(得分:3)
所以我做错了。
对于初学者,我需要将输出格式ffmpeg推送到日志文件,并告诉它覆盖我的临时文件而不提示使用-y参数。
所以而不是
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之前没等多久,因此正在创建一个损坏的文件。
通过在1秒内添加-t(用于时间限制)参数,我确定ffmpeg平均需要15秒来记录1秒的视频。将时间限制增加到10秒使平均增加到25秒,所以似乎在我的服务器上至少有14秒的开销。通过将我的PHP脚本中的睡眠命令增加到30秒,我能够获得一个可用的视频文件。
因此,让PHP终止ffmpeg进程会导致未知(或近似最近)的录制时间长度,这完全取决于CPU功率,网络带宽等。
这有点令人失望,因为我希望能够根据一些外部变量增加录音长度(我有动作传感器输入数据库,我想记录直到动作停止)。
无论如何,这是一个有效的PHP脚本,以防将来帮助某人:
<?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 since we don't know the PID
echo "done\n\n";
exit();
?>
答案 1 :(得分:1)
向后台进程发送SIGQUIT
信号以正常终止ffmpeg命令。
只需使用
kill -s QUIT $PID
,此过程将以未损坏的MP4视频文件结束。
答案 2 :(得分:0)
我不确定你为什么要分叉。你为什么不只是背景ffmpeg?
#!/bin/bash
ffmpeg -f mjpeg -i "http://user:pass@10.0.1.200/nphMotionJp..../tmp/test.mp4 &
然后停止它,做这样的事情:
#!/bin/bash
osascript -e 'tell application "ffmpeg" to quit'
我没有ffmpeg,但也许你需要使用
osascript -e 'tell application "ffmpeg" to stop document /tmp/test.mp4"'
或
osascript -e 'tell application "System Events" to keystroke "q"'
答案 3 :(得分:0)
发送“ q”键:
process.StandardInput.WriteLine("q");