【Qt+FFmpeg】给视频添加时间水印

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

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
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

logani

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值