我需要使用ffmpeg C ++ API对mpegts视频进行编码。输出视频应有两个流:第一个应为AVMEDIA_TYPE_VIDEO类型;第二个应为AVMEDIA_TYPE_DATA类型,并包含一组KLV数据。
我已经编写了自己的KLV库来管理KLV格式。
但是,我无法从头开始创建""通过组合两个流来组合新视频。按照FFMPEG C api h.264 encoding / MPEG2 ts streaming problems中的实施,我可以使用单个视频流成功编码mpegts视频。
但是我无法向输出视频添加新的AVMEDIA_TYPE_DATA流,因为只要我使用avformat_new_stream(...)等方法添加新数据流,输出视频就会为空:数据都不是流,也不生成视频,输出文件为空。
有人可以建议我一个教程页面或一个关于如何以mpegts格式正确地将数据流添加到输出视频的示例吗?
非常感谢!
答案 0 :(得分:0)
通过从FFmpeg源附带的“ muxing.c”示例开始并进行如下修改,我能够将KLV流添加到多路复用输出中。
首先,我如下创建AVStream,其中“ oc”是AVFormatContext(muxer)变量:
AVStream *klv_stream = klv_stream = avformat_new_stream(oc, NULL);
klv_stream->codec->codec_type = AVMEDIA_TYPE_DATA;
klv_stream->codec->codec_id = AV_CODEC_ID_TIMED_ID3;
klv_stream->time_base = AVRational{ 1, 30 };
klv_stream->id = oc->nb_streams - 1;
然后,在编码/混合循环中:
AVPacket pkt;
av_init_packet(&pkt);
pkt.data = (uint8_t*)GetKlv(pkt.size);
auto res = write_frame(oc, &video_st.st->time_base, klv_stream, &pkt);
free(pkt.data);
(GetKlv()函数返回一个malloc()的二进制数据数组,该数组将被您用来获取编码KLV的任何内容所替换。它将pkt.size设置为数据长度。)< / p>
使用此修改并指定“ .ts”目标文件,我得到了一个三流文件,在VLC中可以正常播放。 KLV流的stream_type为0x15,表示同步KLV。
请注意AV_CODEC_ID_TIMED_ID3的codec_id值。根据libavformat源文件“ mpegtsenc.c”,对于异步KLV(无随附的PTS或DTS),AV_CODEC_ID_OPUS的值应导致stream_type 6。这实际上对我的应用程序很重要,但是我无法使其正常工作-调用avformat_write_header()会导致除以零错误。如果知道了,我将在此处添加更新。