ffmpeg 代码实现视频添加水印功能.docx
- 文档编号:6256079
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:4
- 大小:16.88KB
ffmpeg 代码实现视频添加水印功能.docx
《ffmpeg 代码实现视频添加水印功能.docx》由会员分享,可在线阅读,更多相关《ffmpeg 代码实现视频添加水印功能.docx(4页珍藏版)》请在冰豆网上搜索。
ffmpeg代码实现视频添加水印功能
ffmpeg代码实现视频添加水印功能
备忘:
用ffmpeg给视频添加水印的命令为:
ffmpeg-iin.mp4-ixxx.png-filter_complex"overlay=5:
5"out.mp4代码实现如下,主要是用了参考了ffmpeg.c里面的filter_complex的代码:
[cpp]viewplaincopy#include<unistd.h>#include<stdio.h>#include<assert.h>#include<libavcodec/avcodec.h>#include<libavformat/avformat.h>#include<libavfilter/avfiltergraph.h>#include<libavfilter/avcodec.h>#include<libavfilter/buffersink.h>#include<libavfilter/buffersrc.h>#include<libswscale/swscale.h>constchar*filter_descr="overlay=5:
5";#defineENABLE_YUV_FILE1AVFormatContext*input_fmt_ctx;AVCodecContext*input_dec_ctx;AVFormatContext*overlay_fmt_ctx;AVCodecContext*overlay_dec_ctx;intinput_video_stream_idx,overlay_video_stream_idx;AVFilterGraph*filter_graph;AVFilterInOut*inputs;AVFilterInOut*outputs;AVFilterContext*buffersrc_ctx;AVFilterContext*bufferoverlay_ctx;AVFilterContext*buffersink_ctx;intret;intgot_frame;intvideo_eof_reached=0;intoverlay_eof_reached=0;intactive_stream_index=-1;FILE*fp_yuv;voidyuv420p_save(AVFrame*pFrame);intvideo_transcode_step(AVFrame*mVideoFrame);intoverlay_transcode_step(AVFrame*mOverlayFrame);intvideo_output_eof_packet(constchar*tag,AVStream*ist,AVFilterContext*ifilter);staticintopen_input_file(constchar*filename){intret;AVCodec*dec;if((ret=avformat_open_input(&input_fmt_ctx,filename,NULL,NULL))<0){av_log(NULL,AV_LOG_ERROR,"Cannotopeninputfile\n");returnret;}if((ret=avformat_find_stream_info(input_fmt_ctx,NULL))<0){av_log(NULL,AV_LOG_ERROR,"Cannotfindstreaminformation\n");returnret;}/*selectthevideostream*/ret=av_find_best_stream(input_fmt_ctx,AVMEDIA_TYPE_VIDEO,-1,-1,&dec,0);if(ret<0){av_log(NULL,AV_LOG_ERROR,"Cannotfindavideostreamintheinputfile\n");returnret;}input_video_stream_idx=ret;input_dec_ctx=input_fmt_ctx->streams[input_video_stream_idx]->codec;/*initthevideodecoder*/if((ret=avcodec_open2(input_dec_ctx,dec,NULL))<0){av_log(NULL,AV_LOG_ERROR,"Cannotopenvideodecoder\n");returnret;}return0;}staticintopen_overlay_file(constchar*filename){intret;AVCodec*dec;if((ret=avformat_open_input(&overlay_fmt_ctx,filename,NULL,NULL))<0){av_log(NULL,AV_LOG_ERROR,"Cannotopeninputfile\n");returnret;}if((ret=avformat_find_stream_info(overlay_fmt_ctx,NULL))<0){av_log(NULL,AV_LOG_ERROR,"Cannotfindstreaminformation\n");returnret;}/*selectthevideostream*/ret=av_find_best_stream(overlay_fmt_ctx,AVMEDIA_TYPE_VIDEO,-1,-1,&dec,0);if(ret<0){av_log(NULL,AV_LOG_ERROR,"Cannotfindavideostreamintheinputfile\n");returnret;}overlay_video_stream_idx=ret;overlay_dec_ctx=overlay_fmt_ctx->streams[overlay_video_stream_idx]->codec;/*initthevideodecoder*/if((ret=avcodec_open2(overlay_dec_ctx,dec,NULL))<0){av_log(NULL,AV_LOG_ERROR,"Cannotopenvideodecoder\n");returnret;}printf("overlayformat=%s\n",overlay_fmt_ctx->iformat->name);return0;}staticintvideo_config_input_filter(AVFilterInOut*inputs,AVFilterContext**input_filter_ctx){charargs[512];memset(args,0,sizeof(args));AVFilterContext*first_filter=inputs->filter_ctx;intpad_idx=inputs->pad_idx;AVFilter*filter=avfilter_get_by_name("buffer");//AVRationaltime_base=input_dec_ctx->time_base;AVStream*video_st=input_fmt_ctx->streams[input_video_stream_idx];AVRationaltime_base=video_st->time_base;snprintf(args,sizeof(args),"video_size=%dx%d:
pix_fmt=%d:
time_base=%d/%d:
pixel_aspect=%d/%d:
sws_param=flags=%d:
frame_rate=%d/%d",input_dec_ctx->width,input_dec_ctx->height,input_dec_ctx->pix_fmt,input_dec_ctx->time_base.num,input_dec_ctx->time_base.den,input_dec_ctx->sample_aspect_ratio.num,input_dec_ctx->sample_aspect_ratio.den,SWS_BILINEAR+((video_st->codec->flags&CODEC_FLAG_BITEXACT)?
SWS_BITEXACT:
0),video_st->r_frame_rate.num,video_st->r_frame_rate.den);printf("inputargs=%s\n",args);ret=avfilter_graph_create_filter(input_filter_ctx,filter,"src_in",args,NULL,filter_graph);if(ret<0){printf("videoconfiginputfilterfail.\n");return-1;}ret=avfilter_link(*input_filter_ctx,0,first_filter,pad_idx);assert(ret>=0);printf("video_config_input_filteravfilter_linkret=%d\n",ret);returnret;}staticintvideo_config_overlay_filter(AVFilterInOut*inputs,AVFilterContext**overlay_filter_ctx){charargs[512];memset(args,0,sizeof(args));AVFilterContext*first_filter=inputs->filter_ctx;intpad_idx=inputs->pad_idx;AVFilter*filter=avfilter_get_by_name("buffer");//AVRationaltime_base=overlay_dec_ctx->time_base;AVStream*overlay_st=overlay_fmt_ctx->streams[overlay_video_stream_idx];AVRationaltime_base=overlay_st->time_base;snprintf(args,sizeof(args),"video_size=%dx%d:
pix_fmt=%d:
time_base=%d/%d:
pixel_aspect=%d/%d:
sws_param=flags=%d:
frame_rate=%d/%d",overlay_dec_ctx->width,overlay_dec_ctx->height,overlay_dec_ctx->pix_fmt,time_base.num,time_base.den,overlay_dec_ctx->sample_aspect_ratio.num,overlay_dec_ctx->sample_aspect_ratio.den,SWS_BILINEAR+((overlay_st->codec->flags&CODEC_FLAG_BITEXACT)?
SWS_BITEXACT:
0),overlay_st->r_frame_rate.num,overlay_st->r_frame_rate.den);printf("overlayargs=%s\n",args);ret=avfilter_graph_create_filter(overlay_filter_ctx,filter,"overlay_in",args,NULL,filter_graph);if(ret<0){printf("videoconfigoverlayfilterfail.\n");return-1;}ret=avfilter_link(*overlay_filter_ctx,0,first_filter,pad_idx);assert(ret>=0);printf("video_config_overlay_filterret=%d\n",ret);avfilter_inout_free(&inputs);returnret;}staticintvideo_config_output_filter(AVFilterInOut*outputs,AVFilterContext**out_filter_ctx){charargs[512];AVFilterContext*last_filter=outputs->filter_ctx;intpad_idx=outputs->pad_idx;AVFilter*buffersink=avfilter_get_by_name("ffbuffersink");intret=avfilter_graph_create_filter(out_filter_ctx,buffersink,"video_out",NULL,NULL,filter_graph);assert(ret>=0);if(ret<0)returnret;ret=avfilter_link(last_filter,pad_idx,*out_filter_ctx,0);assert(ret>=0);if(ret<0)returnret;avfilter_inout_free(&outputs);return0;}staticintinit_input_filters(){filter_graph->scale_sws_opts=av_strdup("flags=0x4");av_opt_set(filter_graph,"aresample_swr_opts","",0);ret=avfilter_graph_parse2(filter_graph,filter_descr,&inputs,&outputs);assert(inputs&&inputs->next&&!
inputs->next->next);ret=video_config_input_filter(inputs,&buffersrc_ctx);ret=video_config_overlay_filter(inputs->next,&bufferoverlay_ctx);returnret;}staticintinit_output_filters(){returnvideo_config_output_filter(outputs,&buffersink_ctx);}intreap_filters(){AVFilterBufferRef*picref;while
(1){ret=av_buffersink_get_buffer_ref(buffersink_ctx,&picref,AV_BUFFERSINK_FLAG_NO_REQUEST);if(ret==AVERROR(EAGAIN)||ret==AVERROR_EOF){//printf("reap_filtersfailret=%d\n",ret);return0;//noframefiltered.}printf("samplesref-------------------\n");AVFrame*filtered_frame=avcodec_alloc_frame();avcodec_get_frame_defaults(filtered_frame);avfilter_copy_buf_props(filtered_frame,picref);yuv420p_save(filtered_frame);avfilter_unref_bufferp(&picref);}}inttranscode_from_filter(AVFilterContext**ifilters,int*eof_reached_arr,int*active_stream_indext){intret=0;ret=avfilter_graph_request_oldest(filter_graph);if(ret>=0){returnret;}if(ret==AVERROR_EOF){returnret;}if(ret!
=AVERROR(EAGAIN)){returnret;}intnb_requests_max=0;inti;for(i=0;i<2;i++){inteof_reached=eof_reached_arr[i];if(eof_reached){continue;}AVFilterContext*ifilter=ifilters[i];intnb_requests=av_buffersrc_get_nb_failed_requests(ifilter);if(nb_requests>nb_requests_max){nb_requests_max=nb_requests;*active_stream_indext=i;}}returnret;}intmain(){avcodec_register_all();av_register_all();avfilter_register_all();avformat_network_init();char*video_file="outFileSrc.mp4";char*overlay_video_file="my_logo.png";//light1.mp4#ifENABLE_YUV_FILEconstchar*yuvFile="outWater.yuv";fp_yuv=fopen(yuvFile,"wb");#endifopen_input_file(video_file);open_overlay_file(overlay_video_file);filter_graph=avfilter_graph_alloc();if(!
filter_graph){printf("filtergraphallocfail.\n");return-1;}init_input_filters();init_output_filters();if((ret=avfilter_graph_config(filter_graph,NULL))<0)returnret;AVFrame*mVideoFrame=avcodec_alloc_frame();AVFrame*mOverlayFrame=avcodec_alloc_frame();while
(1){if(video_eof_reached&&overlay_eof_reached){printf("streamEOF.\n");break;}AVFilterContext*ifilters[]={buffersrc_ctx,bufferoverlay_ctx};inteof_reacheds[]={video_eof_reached,overlay_eof_reached};ret=transcode_from_filter(ifilters,eof_reacheds,&active_stream_index);if(ret>=0){ret=reap_filters();assert(ret>=0);continue;}if(ret==AVERROR_EOF){ret=reap_filters();assert(ret>=0);continue;}if(ret==AVERROR(EAGAIN)&&active_stream_index<0){continue;}assert(active_stream_index>=0);printf("active_stream_index=%d\n",active_stream_index);if(active_stream_index==0){video_transcode_step(mVideoFrame);continue;}overlay_transcode_step(mOverlayFrame);}if(input_dec_ctx)avcodec_close(input_dec_ctx);avformat_close_input(&input_fmt_ctx);if(overlay_dec_ctx)avcodec_close(overlay_dec_ctx);avformat_close_input(&overlay_fmt_ctx);printf("my_filtering_video3end-------\n");return0;}intvideo_transcode_step(AVFrame*mVideoFrame){intret=0;AVPack
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ffmpeg 代码实现视频添加水印功能 代码 实现 视频 添加 水印 功能