ffmpeg 创建 mpeg-dash 块文件的速度太慢导致 404 错误

问题描述

我有一个硬件编码器提供 FFmpeg 来创建一个 MPEG-DASH 低延迟流。运行了一段时间后效果很好,但是让FFmpeg运行了一段时间并重新加载页面后,出现了许多404错误

发生这种情况时,dash.js 播放器会尝试在“实时边缘”上获取文件,但 FFmpeg 尚未创建该文件。例如运行20-30分钟,加载网页播放器后,web服务器中的调试代码显示

2021-07-16 16:46:30.64 : GET REQUEST : /data/ott/chunk-stream0-00702.m4s
2021-07-16 16:46:30.67 : NOT FOUND. Latest files on filesystem:
    chunk-stream0-00699.m4s.tmp
    chunk-stream0-00698.m4s
    chunk-stream0-00697.m4s
    chunk-stream0-00696.m4s
    ...

因此您可以看到浏览器请求的块 702,但服务器上的最新块是 699(的一部分)。2 秒块,即 3-5 秒的内容尚不可用。

为了分析,我修改了 FFmpeg 的 dashenc.c 以在每次打开文件添加一个时间戳,显示如下:

[dash @ 0x9b17c0] 21:48:52.935 1626443332.935  : dashenc_io_open() - opened /data/ott/chunk-stream0-00060.m4s.tmp

并将时间戳加载到 Excel 中。

尽管段持续时间为 2.000 秒,但文件打开之间的平均时间为 2.011 秒。两个多小时后,计算的实时边缘与服务器上的最新文件间的差异累积为 45 秒

硬件编码器设置为 25 fps,GOP 大小为 5。我通过分析硬件编码器输出的 H.264 NALU 确认了这两者。

我的问题:这是 FFmpeg 中的错误还是我可以通过调整硬件编码器和/或 FFmpeg 选项的设置来避免这个问题?

参考

FFmpeg: Version 4.4 
Centos 8 
Apache 2.4.37

FFmpeg 命令行(管道由进程读取硬件编码器馈送)

ffmpeg -re -loglevel verbose -an -f h264 -i pipe:17 -c:v copy \
-f dash -dash_segment_type mp4 -b:v 1000000 -seg_duration 2.000000 \
-frag_type duration -frag_duration 0.200000 -target_latency 1 \
-window_size 10 -extra_window_size 5 -remove_at_exit 1 -streaming 1 \
-ldash 1 -use_template 1 -use_timeline 0 -write_prft 1 -avioflags direct \
-fflags +nobuffer+flush_packets -format_options movflags=+cmaf \
-utc_timing_url /web/be/time.PHP /data/ott/master.mpd

从 dashenc.c 修改 dash_io_open()

static int 
dashenc_io_open(AVFormatContext *s,AVIOContext **pb,char *filename,AVDictionary **options)
{
    DASHContext *c = s->priv_data;
    int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
    int err = AVERROR_muxer_NOT_FOUND;
    if (!*pb || !http_base_proto || !c->http_persistent)
    {
        err = s->io_open(s,pb,filename,AVIO_FLAG_WRITE,options);

        // My Debug
        {
            char buf[20],milli[60];
            struct timeb tp;

            ftime(&tp); // sec + ms
            struct tm *tmInfo = localtime(&tp.time);

            // 2020-05-15 21:15:12.123
            strftime(buf,sizeof(buf),"%H:%M:%s",tmInfo);
            snprintf(milli,59,"%s.%03d %d.%03d ",buf,tp.millitm,tp.time,tp.millitm);

            av_log(s,AV_LOG_INFO,"%s : dashenc_io_open() - opened %s\n",milli,filename);
        }
    }
    return err;
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)