基于FFMPEG水印添加---avfilter库

基于ffmpeg水印添加---avfilter库   avfilter,是ffmpeg为图像和语音处理提供的滤镜子框架,代码位于libavfilter目录。
  libavfilter提供了一个通用框架来实现audio和video的原始数据filter处理,如对视频添加叠加logo图片或者时间文字等信息、对视频进行裁剪和翻转。
1.硬件平台操作系统:ubuntu18.04ffmpeg版本:ffmpeg4.2.5 2.ffmpeg编译   在使用avfilter库添加汉字水印时,ffmepg默认模式时不支持矢量字库的,要实现汉字水印添加就需要进行configure配置。
2.1 freetype库编译    freetype下载地址:https://download.savannah.gnu.org/releases/freetype/
2.2 fribidi库编译    fribidi下载地址:https://www.linuxfromscratch.org/blfs/view/svn/general/fribidi.html
#解压源码tar xvf /mnt/hgfs/ubuntu/software_pack/fribidi-1.0.11.tar.xz#配置生成makefile./configure --prefix=$pwd/_install#编译安装make && make install #编译安装#将生成的文件拷贝到/usr/lib目录下cp ./_install/lib/pkgconfig/ /usr/lib -rf 2.3 ffmpeg库编译#解压源码tar xvf /mnt/hgfs/ubuntu/software_pack/ffmpeg-4.2.5.tar.bz2 #配置生成makefile./configure --enable-static --enable-shared --prefix=$pwd/_install --extra-cflags=-i/home/wbyq/src_pack/x264-master/_install/include --extra-ldflags=-l/home/wbyq/src_pack/x264-master/_install/lib --extra-cflags=-i/home/wbyq/src_pack/freetype-2.10.0/_install/include --extra-ldflags=-l/home/wbyq/src_pack/freetype-2.10.0/_install/lib --extra-cflags=-i/home/wbyq/src_pack/fribidi-1.0.11/_install/include --extra-ldflags=-l/home/wbyq/src_pack/fribidi-1.0.11/_install/lib --enable-ffmpeg --enable-libx264 --enable-gpl --enable-libfreetype --enable-libfontconfig --enable-libfribidi --enable-avfilter#编译安装make && make install #将生成的文件拷贝到/usr/lib目录下cp ./_install/lib/pkgconfig/ /usr/lib -rf 2.4 ffmpeg命令行添加时间水印 2.4.1 以实时时间动态添加时间水印ffmpeg -i 最后一滴水.mp4 -vf drawtext=“fontfile=msyhbd.ttc:x=100:y=10:fontcolor=white:fontsize=30:expansion=strftime:basetime=$(date +%s )000000:text=‘%y-%m-%d %h:%m: %s’” output.mp4drawtext 字符串水印fontfile=msyhbd.ttc矢量字库,可在windows下c:windowsfonts拷贝到当期目录下x=100:y=10显示位置,距离左上脚fontcolor=white:fontsize=30字体颜色和大小expansion=strftime:basetime=$(date +%s )000000以当前实时时间添加动态水印text=‘%y-%m-%d %h:%m: %s’ 时间显示格式 2.4.1 以指定时间动态添加时间水印ffmpeg -i 最后一滴水.mp4 -vf drawtext=fontfile=msyhbd.ttc:x=100:y=10:fontcolor=white:fontsize=30:expansion=strftime:basetime=$(date +%s -d '2020-8-8 14:10:50')000000:text='%y-%m-%d %h:%m: %s' it_阿水 output.mp4 3.代码实现水印添加   参考雷霄骅博客处理示例:https://blog.csdn.net/leixiaohua1020/article/details/50618190
  致敬雷神!致敬雷神!致敬雷神!
#include #include #include #include #include #include #include #define file_src sintel_480x272_yuv420p.yuv //源文件int watermark(avframe *frame_in,avframe *frame_out,int w,int h,const char *str);int main(int argc,char *argv[]){ int ret; /*打开输入yuv文件*/ file *fp_in=fopen(file_src,rb+); if(fp_in==null) { printf(文件打开失败n); return 0; } int in_width=480; int in_height=272; /*处理后的文件*/ file *fp_out=fopen(new.yuv,wb+); if(fp_out==null) { printf(文件创建失败n); return 0; } char buff[50]; avframe *frame_in=av_frame_alloc(); unsigned char *frame_buffer_in; frame_buffer_in=(unsigned char *)av_malloc(av_image_get_buffer_size(av_pix_fmt_yuv420p,in_width,in_height,4)); /*根据图像设置图像指针和内存对齐方式*/ av_image_fill_arrays(frame_in->data,frame_in->linesize,frame_buffer_in,av_pix_fmt_yuv420p,in_width,in_height,4); avframe *frame_out=av_frame_alloc(); unsigned char *frame_buffer_out; frame_buffer_out=(unsigned char *)av_malloc(av_image_get_buffer_size(av_pix_fmt_yuv420p,in_width,in_height,4)); av_image_fill_arrays(frame_out->data,frame_out->linesize,frame_buffer_out,av_pix_fmt_yuv420p,in_width,in_height,4); frame_in->width=in_width; frame_in->height=in_height; frame_in->format=av_pix_fmt_yuv420p; char sys_time[64]; time_t sec,sec2; while(1) { if(fread(frame_buffer_in,1,in_width*in_height*3/2,fp_in)!=in_width*in_height*3/2) { break; } frame_in->data[0]=frame_buffer_in; frame_in->data[1]=frame_buffer_in+in_width*in_height; frame_in->data[2]=frame_buffer_in+in_width*in_height*5/4; sec=time(null); if(sec!=sec2) { sec2=sec; struct tm* today = localtime(&sec2); strftime(sys_time, sizeof(sys_time), %y/%m/%d %h:%m:%s, today); } watermark(frame_in,frame_out,in_width,in_height,sys_time);//添加水印 /*添加水印后的数据写入到过滤器*/ if(frame_out->format==av_pix_fmt_yuv420p) { for(int i=0;iheight;i++) { fwrite(frame_out->data[0]+frame_out->linesize[0]*i,1,frame_out->width,fp_out); } for(int i=0;iheight/2;i++) { fwrite(frame_out->data[1]+frame_out->linesize[1]*i,1,frame_out->width/2,fp_out); } for(int i=0;iheight/2;i++) { fwrite(frame_out->data[2]+frame_out->linesize[2]*i,1,frame_out->width/2,fp_out); } printf(一帧数据处理完成n); } av_frame_unref(frame_out); } fclose(fp_in); fclose(fp_out); av_frame_free(&frame_in); av_frame_free(&frame_out); return 0; }int 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空间*/ avfilterinout *outputs=avfilter_inout_alloc(); avfilterinout *inputs=avfilter_inout_alloc(); /*创建avfiltergraph,分配空间*/ avfiltergraph *filter_graph;//对filters系统的整体管理结构体 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);//图像宽高,格式,帧率,画面横纵比 /*创建过滤器上下文,源数据avfiltercontext*/ avfiltercontext *buffersrc_ctx; ret=avfilter_graph_create_filter(&buffersrc_ctx,buffersrc,in,args,null,filter_graph); if(retpixel_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(retname =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=msyhbd.ttc:fontcolor=green:fontsize=20:x=50:y=20:text='%snit_阿水',str); if(avfilter_graph_parse_ptr(filter_graph,filter_desrc,&inputs,&outputs, null)name); if(!strcmp(filter_ctxn->name,parsed_drawtext_0)) { parsed_drawtext_0_index=i; } } if(parsed_drawtext_0_index==-1) { printf([%s %d]:no parsed_drawtext_0n,__function__,__line__);//没有找到过滤器 } filter_ctx=filter_graph->filters[parsed_drawtext_0_index];//保存找到的过滤器 /*获取系统时间,将时间加入到过滤器*/ char sys_time[64]; time_t sec,sec2; sec=time(null); if(sec!=sec2) { sec2=sec; struct tm* today = localtime(&sec2); strftime(sys_time, sizeof(sys_time), %y/%m/%d %h:%m:%s, today); //24小时制 } av_opt_set(filter_ctx->priv, text, sys_time, 0 ); //设置text到过滤器 #endif /*往源滤波器buffer中输入待处理数据*/ if(av_buffersrc_add_frame(buffersrc_ctx,frame_in)<0) { return -5; } /*从滤波器中输出处理数据*/ if(av_buffersink_get_frame(buffersink_ctx, frame_out)<0) { return -6; } avfilter_inout_free(&outputs); avfilter_inout_free(&inputs); avfilter_graph_free(&filter_graph); return 0;}   makefile文件:
obj=addwatermart.ocflags =-i/home/wbyq/src_pack/ffmpeg-4.2.5/_install/include -l/home/wbyq/src_pack/ffmpeg-4.2.5/_install/libcflags +=-lpthread -lm -ldl -lsdl2_image -lavcodec -lavfilter -lavutil -lswresample -lavdevice -lavformat -lpostproc -lswscale -lpthread -lstdc++ -lm -lasound -lavfilter -lfreetypeapp:$(obj) gcc -o app $(obj) $(cflags) .phony=cleanclean: rm app -f   本示例实现效果为动态添加时间水印。示例效果:


华为P30Pro拍照为什么这么强
作业盒子累积融资20 亿元,人工智能实现教育公平!
2019年第四季度中国智能手机市场的出货量总结分析
如何根据电机的功率选择接触器/空开/电线
深入理解锂离子电池中的核心问题
基于FFMPEG水印添加---avfilter库
NE5532N引脚功能_NE5532N典型应用电路
工地噪音扰民怎么办?扬尘在线监测系统帮你解决
华为发布“超融合+”战略及系列新品,帮助伙伴造好用好超融合
MAH推出一个定制AR应用程序,为画廊添彩
简单介绍带排污阀Y型过滤器
iQOO熔岩橙高清图赏
jesd204b协议相关知识介绍
接口静电保护器件二极管,12V如何选型号
英国还是用了华为5G,特朗普怒了
U 设计周 x NVIDIA Omniverse:元宇宙设计大赛,邀 3D 设计师一起创造未来!
Android应用开发中的数据存储介绍
激光镭雕技术在吉利汽车上的应用
翠展微宣布完成近亿元A轮融资 用于新建车规级IGBT模块产线
开放原子开源基金会理事长孙文龙一行赴山东大学考察交流