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

问题描述 投票:0回答:1

我使用 ffmpeg 将 raspberrypi 视频源(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
input ffmpeg raspberry-pi output
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 命令正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.