问题

使用ffmpeg把一个视频文件发布成一个rtmp流,并设置成循环推流,此时需要使用参数stream_loop,命令如下:

ffmpeg.exe -stream_loop -1 -re -i D:\tools\ffmpeg-5.1.2\bin\sei.h264 -c copy -f flv -safe 0 rtmp://localhost:1935/live/test

但是发现一个问题,stream_loop参数没有生效,循环推流失败,报错如下:

[flv @ 0000024c65c266c0] Timestamps are unset in a packet for stream 0. This is deprecated and will stop working in the future. Fix your code to set the timestamps properly Seek to start failed.=-1.0 size=   21954kB time=00:00:46.38 bitrate=3877.7kbits/s speed=   1x D:\tools\ffmpeg-5.1.2-full_build\bin\sei.h264: Operation not permitted [flv @ 0000024c65c266c0] Failed to update header with correct duration. [flv @ 0000024c65c266c0] Failed to update header with correct filesize. frame= 1116 fps= 24 q=-1.0 Lsize=   21954kB time=00:00:46.50 bitrate=3867.3kbits/s speed=0.999x video:21932kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.100925%

截图:

解决

通过分析日志可以发现,报错前出现了一个报警信息:Seek to start failed. 个人猜测循环推流没有成功就是因为Seek操作失败了,首先看一下ffmpeg源码:

if (ret < 0 && ifile->loop) {

AVCodecContext *avctx;

for (i = 0; i < ifile->nb_streams; i++) {

ist = input_streams[ifile->ist_index + i];

avctx = ist->dec_ctx;

if (ist->processing_needed) {

ret = process_input_packet(ist, NULL, 1);

if (ret>0)

return 0;

if (ist->decoding_needed)

avcodec_flush_buffers(avctx);

}

}

#if HAVE_THREADS

free_input_thread(file_index);

#endif

ret = seek_to_start(ifile, is);

#if HAVE_THREADS

thread_ret = init_input_thread(file_index);

if (thread_ret < 0)

return thread_ret;

#endif

if (ret < 0)

av_log(NULL, AV_LOG_WARNING, "Seek to start failed.\n");

else

ret = get_input_packet(ifile, &pkt);

if (ret == AVERROR(EAGAIN)) {

ifile->eagain = 1;

return ret;

}

}

报警是seek_too_start方法触发的,传入的参数是文件名,同时,接下来的报错又是文件读取没有权限:Operation not permitted。所以自己大胆猜测可能是文件格式不支持。

于是,自己又将sei.h264封装成mp4,命令如下:

ffmpeg.exe -i sei.h264 -c copy sei.mp4

然后再次执行本文开头的推流命令,发现循环推流成功了。

最后,发现循环推流两个多小时,没有任何问题。之后手动停止推流,截图如下:

好文链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。