ffmpeg编解码中,给本地视频加上时间水印,并保存到本地,使用到的技术是ffmpeg中的avfilter库;
具体效果如下
yuv:

mp4

本方法不适合摄像头解码,解码出来糊得不行,本地视频的话会好得多;
具体代码如下:
int video::waterMark(AVFrame *frame_in,AVFrame *frame_out,int w,int h,const char *str)
{
int ret;
/*根据名字获取ffmegding定义的filter*/
const AVFilter *buffersrc=avfilter_get_by_name("buffer");//原始数据
const AVFilter *buffersink=avfilter_get_by_name("buffersink");//处理后的数据
/*动态分配AVFilterInOut空间*/
outputs=avfilter_inout_alloc();
inputs=avfilter_inout_alloc();
/*创建AVFilterGraph,分配空间*/
filter_graph = avfilter_graph_alloc();
enum AVPixelFormat pix_fmts[]={AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE};//设置格式
/*过滤器参数:解码器的解码帧将被插入这里。*/
char args[256];
snprintf(args, sizeof(args),
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
w,h,AV_PIX_FMT_YUV420P,1,25,1,1);//图像宽高,格式,帧率,画面横纵比
qDebug()<<args;
/*创建过滤器上下文,源数据AVFilterContext*/
AVFilterContext *buffersrc_ctx = nullptr;
ret=avfilter_graph_create_filter(&buffersrc_ctx,buffersrc,"in",args,NULL,filter_graph);
if(ret<0)
{
qDebug()<<"创建过滤器上下文失败AVFilterContext";
return -1;
}
/*创建过滤器上下文,处理后数据buffersink_params*/
AVBufferSinkParams *buffersink_params;
buffersink_params=av_buffersink_params_alloc();
buffersink_params->pixel_fmts=pix_fmts;//设置格式
AVFilterContext *buffersink_ctx;
ret=avfilter_graph_create_filter(&buffersink_ctx,buffersink,"out",NULL,buffersink_params,filter_graph);
av_free(buffersink_params);
if(ret<0)
{
qDebug()<<"创建sink过滤器上下文失败AVFilterContext";
return -2;
}
/*过滤器链输入/输出链接列表*/
outputs->name =av_strdup("in");
outputs->filter_ctx =buffersrc_ctx;
outputs->pad_idx =0;
outputs->next =NULL;
inputs->name =av_strdup("out");
inputs->filter_ctx =buffersink_ctx;
inputs->pad_idx =0;
inputs->next =NULL;
char filter_desrc[200]={0};//要添加的水印数据
snprintf(filter_desrc,sizeof(filter_desrc),"drawtext=fontfile=arial.ttf:fontcolor=green:fontsize=20:x=450:y=50:text='%s'",str);
qDebug()<<filter_desrc;
if(avfilter_graph_parse_ptr(filter_graph,filter_desrc,&inpu

本文详细介绍了如何使用FFmpeg的avfilter库为本地视频添加时间水印,并展示了关键代码实现。文章提到,该方法不适用于摄像头解码,但在本地视频上效果良好。作者在解码线程中循环操作,通过avfilter_graph_create_filter和avfilter_graph_parse_ptr等函数设置过滤器,然后利用avcodec_send_packet和avcodec_receive_frame进行解码和接收帧数据。在解码过程中,还涉及到SwsContext用于视频格式转换。在实际运行中,可能出现的问题包括未注册avfilter组件、找不到字体文件等,作者给出了相应的解决方案。
最低0.47元/天 解锁文章
2724





