FFmpeg总是在第一次运行命令时给我输入/输出错误。

3
我正在使用ffmpeg将树莓派视频(CSI相机)推送到nginx-RTMP服务器,然后nginx将其推送到youtube。我的问题是,每次运行ffmpeg命令时,它总是给我输入/输出错误。但是当我第二次运行完全相同的ffmpeg命令时,它就可以正常工作了。如何解决这个问题?我想在脚本文件中启动ffmpeg命令,并将脚本放入crontab中,以便自动开始直播流。但这个错误使这不可能实现。
我的ffmpeg命令如下(将真实域名更改为mydomain.com):
ffmpeg -thread_queue_size 512 -f v4l2  -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100  -input_format yuyv422 -video_size 1280x720 -framerate 30 -i /dev/video0 -vf eq=gamma=1.5:saturation=1.3 -c:v h264_omx -b:v 20480K -vsync 1 -g 16  -f flv rtmp://mydomain.com:1935/live/

错误日志:
Input #1, video4linux2,v4l2, from '/dev/video0':
  Duration: N/A, start: 474200.421802, bitrate: 442368 kb/s
    Stream #1:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 1280x720, 442368 kb/s, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
rtmp://rtmp.simonliu.space:1935/live/: Input/output error

虽然我还没有弄清楚ffmpeg第一次失败的原因,但是我找到了一种方法,在它失败时重新启动ffmpeg在一个screen会话中。基本上,我按照这个答案的步骤进行操作。 - undefined
我遇到了同样的问题,只是第一次。有人有什么想法吗? - undefined
一样的情况,一旦运行起来就很好,但第一次连接时卡住了。正在努力解决。有时候需要多次尝试才能连接成功。 - undefined
1个回答

0
我的RTMP没问题,问题是每次运行ffmpeg命令时,大部分时间都会在第一次出现输入/输出错误。当你手动尝试两三次后,再运行相同的ffmpeg命令时,就能正常工作。听起来像是某种不同步或丢失了初始信号或握手,导致卡住,当你按下Cntr-C中断后,就会出现I/O错误。
我找到了一个解决方法,对我来说有效。
#!/usr/bin/sh
NUMERO=$(pgrep -f salida/mystream.m3u8)
echo $NUMERO

MOD_TIME=`stat -c %Y /home/public_html/salida/mystream.m3u8`
RIGHTNOW=`date +%s`
HOW_LONG=`expr $RIGHTNOW - $MOD_TIME`
NUM_MINS=`expr $HOW_LONG / 60`
NUM_SECS=`expr $HOW_LONG % 60`

echo "$NUM_MINS minutes, $NUM_SECS seconds since modified."

if [[ $NUMERO == "" ]];
then
echo "Start new ffmpeg";
ffmpeg -re -i rtmp://www.yourdomain.com:1934/live -codec copy -preset ultrafast -crf 22 -threads 8 -f hls -hls_time 5 -hls_list_size 5 -hls_flags delete_segments /home/public_html/salida/mystream.m3u8
fi

if [[ $NUM_SECS -gt 10 ||  $NUM_MINS -gt 1 ]];
then
kill -9 $NUMERO
echo "Killed Stuck ffmpeg";
ffmpeg -re -i rtmp://www.yourdomain.com:1934/live -codec copy -preset ultrafast -crf 22 -threads 8 -f hls -hls_time 5 -hls_list_size 5 -hls_flags delete_segments /home/public_html/salida/mystream.m3u8
fi
解释步骤:首先,您需要在此处获取PID号码:
#!/usr/bin/sh
NUMERO=$(pgrep -f salida/mystream.m3u8)
echo $NUMERO

然后你需要获取文件的创建时间或修改时间:
MOD_TIME=`stat -c %Y /home/public_html/salida/mystream.m3u8`
RIGHTNOW=`date +%s`
HOW_LONG=`expr $RIGHTNOW - $MOD_TIME`
NUM_MINS=`expr $HOW_LONG / 60`
NUM_SECS=`expr $HOW_LONG % 60`

echo "$NUM_MINS minutes, $NUM_SECS seconds since modified."

如果您的PID不存在,那么您可以运行新的FFMPEG。
if [[ $NUMERO == "" ]];
then
echo "Start new ffmpeg";
ffmpeg -re -i rtmp://www.yourdomain.com:1934/live -codec copy -preset ultrafast -crf 22 -threads 8 -f hls -hls_time 5 -hls_list_size 5 -hls_flags delete_segments /home/public_html/salida/mystream.m3u8
fi

如果您的PID存在,那么请检查您创建文件的时间,如果超过10秒钟,那么很可能出现了卡顿的情况,您需要终止该PID并重新运行FFMPEG来重新启动服务。
if [[ $NUM_SECS -gt 10 ||  $NUM_MINS -gt 1 ]];
then
kill -9 $NUMERO
echo "Killed Stuck ffmpeg";
ffmpeg -re -i rtmp://www.yourdomain.com:1934/live -codec copy -preset ultrafast -crf 22 -threads 8 -f hls -hls_time 5 -hls_list_size 5 -hls_flags delete_segments /home/public_html/salida/mystream.m3u8
fi

你需要将它放在一个cron中,每隔一分钟运行一次。如果它正在运行,并且一个m3u8或者其他你创建的文件(mp4,ts等)的年龄小于10秒,那么就跳过并保持之前的FFMPEG命令正常工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接