ffmpeg添加水印 c 代码实现-凯发app官方网站

凯发app官方网站-凯发k8官网下载客户端中心 | | 凯发app官方网站-凯发k8官网下载客户端中心
  • 博客访问: 3000192
  • 博文数量: 864
  • 博客积分: 14125
  • 博客等级: 上将
  • 技术积分: 10634
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-27 16:53
个人简介

https://github.com/zytc2009/bigteam_learning

文章分类

(864)

  • (1)
  • (1)
  • (0)
  • (8)
  • (3)
  • (0)
  • (9)
  • (5)
  • (5)
  • (20)
  • (150)
  • (21)
  • (16)
  • (1)
  • (7)
  • (12)
  • (5)
  • (8)
  • (40)
  • (12)
  • (79)
  • (8)
  • (187)
  • (2)
  • (17)
  • (46)
  • (2)
  • (54)
  • (74)
  • (68)
  • (3)
文章存档

(1)

(1)

(3)

(1)

(10)

(3)

(8)

(3)

(69)

(103)

(357)

(283)

(22)

我的朋友
相关博文
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·

分类: c/c

2023-05-11 10:35:44

使用 ffmpeg 在 c 中添加水印并将其保存到文件的示例代码。
在代码中,我们使用 ffmpeg 的 c api,需要安装 ffmpeg 库并进行链接。在代码中,我们使用 
avformat_open_input() 函数打开输入文件,使用 avformat_find_stream_info() 函数查找流信息,使用 avcodec_find_decoder() 函数查找解码器,使用 avcodec_open2() 函数打开解码器,使用 av_read_frame() 函数读取视频帧,使用 avcodec_send_packet() 函数将解码数据包发送到解码器,使用 avcodec_receive_frame() 函数接收解码后的视频帧,使用 av_frame_alloc() 函数分配帧内存,使用 av_frame_copy() 函数复制帧,使用 avfilter_graph_alloc() 函数分配滤镜图,使用 avfilter_graph_parse2() 函数解析滤镜图,使用 avfilter_graph_config() 函数配置滤镜图,使用 av_buffersrc_write_frame() 函数将视频帧写入滤镜图,使用 av_buffersink_get_frame() 函数从滤镜图中获取处理后的视频帧,使用 avcodec_send_frame() 函数将处理后的视频帧发送到编码器,使用 avcodec_receive_packet() 函数接收编码后的数据包,使用 av_write_frame() 函数将数据包写入输出文件,使用 av_write_trailer() 函数写入输出文件尾。


点击(此处)折叠或打开

  1. #include <iostream>
  2. #include <string>
  3. #include <sstream>


  4. extern "c" {
  5. #include <libavcodec/avcodec.h>
  6. #include <libavformat/avformat.h>
  7. #include <libavfilter/avfilter.h>
  8. #include <libavfilter/buffersrc.h>
  9. #include <libavfilter/buffersink.h>
  10. #include <libavutil/imgutils.h>
  11. #include <libavutil/opt.h>
  12. #include <libswscale/swscale.h>
  13. }


  14. using namespace std;


  15. static void custom_log(void *ptr, int level, const char *fmt, va_list vl)
  16. {
  17.     vprintf(fmt, vl);
  18. }


  19. int main(int argc, char *argv[])
  20. {
  21.     if (argc < 4) {
  22.         cerr << "usage: " << argv[0] << " " << endl;
  23.         return -1;
  24.     }


  25.     const char *input_file = argv[1];
  26.     const char *watermark_file = argv[2];
  27.     const char *output_file = argv[3];


  28.     av_register_all();
  29.     avfilter_register_all();
  30.     av_log_set_callback(custom_log);


  31.     // open input file and find video stream
  32.     avformatcontext *in_fmt_ctx = null;
  33.     if (avformat_open_input(&in_fmt_ctx, input_file, null, null) < 0) {
  34.         av_log(null, av_log_error, "cannot open input file: %s\n", input_file);
  35.         return -1;
  36.     }


  37.     if (avformat_find_stream_info(in_fmt_ctx, null) < 0) {
  38.         av_log(null, av_log_error, "cannot find input stream information\n");
  39.         return -1;
  40.     }


  41.     int video_stream_index = -1;
  42.     for (int i = 0; i < in_fmt_ctx->nb_streams; i) {
  43.         if (in_fmt_ctx->streams[i]->codecpar->codec_type == avmedia_type_video) {
  44.             video_stream_index = i;
  45.             break;
  46.         }
  47.     }


  48.     if (video_stream_index == -1) {
  49.         av_log(null, av_log_error, "cannot find video stream\n");
  50.         return -1;
  51.     }


  52.     // find decoder for video stream and open it
  53.     avcodec *codec = avcodec_find_decoder(in_fmt_ctx->streams[video_stream_index]->codecpar->codec_id);
  54.     if (!codec) {
  55.         av_log(null, av_log_error, "cannot find decoder for codec id %d\n", in_fmt_ctx->streams[video_stream_index]->codecpar->codec_id);
  56.         return -1;
  57.     }


  58.     avcodeccontext *codec_ctx = avcodec_alloc_context3(codec);
  59.     if (!codec_ctx) {
  60.         av_log(null, av_log_error, "cannot allocate codec context\n");
  61.         return -1;
  62.     }


  63.     if (avcodec_parameters_to_context(codec_ctx, in_fmt_ctx->streams[video_stream_index]->codecpar) < 0) {
  64.         av_log(null, av_log_error, "cannot set codec context parameters\n");
  65.         return -1;
  66.     }


  67.     if (avcodec_open2(codec_ctx, codec, null) < 0) {
  68.         av_log(null, av_log_error, "cannot open decoder\n");
  69.         return -1;
  70.     }


  71.     // open watermark image file and create filter graph
  72.     avfiltercontext *buffersrc_ctx = null;
  73.     avfiltercontext *buffersink_ctx = null;
  74.     avfiltergraph *filter_graph = avfilter_graph_alloc();
  75.     if (!filter_graph) {
  76.         av_log(null, av_log_error, "cannot allocate filter graph\n");
  77.         return -1;
  78.     }


  79.     avfilter *buffersrc = avfilter_get_by_name("buffer");
  80.     avfilter *buffersink = avfilter_get_by_name("buffersink");
  81.     if (!buffersrc || !buffersink) {
  82.         av_log(null, av_log_error, "cannot find buffer source/sink filters\n");
  83.         return -1;
  84.     }


  85.     avframe *watermark_frame = av_frame_alloc();


  86.     avcodec *watermark_codec = avcodec_find_decoder_by_name("png");
  87.     if (!watermark_codec) {
  88.         av_log(null, av_log_error, "cannot find decoder for watermark image\n");
  89.         return -1;
  90.     }


  91.     avcodeccontext *watermark_codec_ctx = avcodec_alloc_context3(watermark_codec);
  92.     if (!watermark_codec_ctx) {
  93.         av_log(null, av_log_error, "cannot allocate codec context for watermark image\n");
  94.         return -1;
  95.     }


  96.     if (avcodec_open2(watermark_codec_ctx, watermark_codec, null) < 0) {
  97.         av_log(null, av_log_error, "cannot open decoder for watermark image\n");
  98.         return -1;
  99.     }


  100.     avpacket watermark_packet;
  101.     av_init_packet(&watermark_packet);
  102.     watermark_packet.data = null;
  103.     watermark_packet.size = 0;


  104.     if (avcodec_send_packet(watermark_codec_ctx, &watermark_packet) < 0) {
  105.         av_log(null, av_log_error, "cannot send packet to decoder for watermark image\n");
  106.         return -1;
  107.     }


  108.     int got_picture = 0;
  109.     while (avcodec_receive_frame(watermark_codec_ctx, watermark_frame) == 0) {
  110.         got_picture = 1;
  111.         break;
  112.     }


  113.     avframe *watermark_buffer_frame = av_frame_alloc();


  114.     av_image_copy(watermark_buffer_frame->data, watermark_buffer_frame->linesize, watermark_frame->data, watermark_frame->linesize, watermark_codec_ctx->pix_fmt, watermark_codec_ctx->width, watermark_codec_ctx->height);


  115.     avbuffersrcparameters *buffersrc_params = av_buffersrc_parameters_alloc();
  116.     buffersrc_params->format = watermark_codec_ctx->pix_fmt;
  117.     buffersrc_params->width = watermark_codec_ctx->width;
  118.     buffersrc_params->height = watermark_codec_ctx->height;
  119.     buffersrc_params->time_base = (avrational){1, 1};


  120.     stringstream filterss;
  121.     filterss << "scale=" << codec_ctx->width << ":" << codec_ctx->height << "[watermark];[watermark]format=" << av_get_pix_fmt_name(codec_ctx->pix_fmt) << "[watermarkfmt];[0:v][watermarkfmt]overlay=0:0";


  122.     const char *filter_descr = filterss.str().c_str();


  123.     if (avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in", filter_descr, buffersrc_params, filter_graph) < 0) {
  124.         av_log(null, av_log_error, "cannot create buffer source\n");
  125.         return -1;
  126.     }


  127.     if (avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out", null, null, filter_graph) < 0) {
  128.         av_log(null, av_log_error, "cannot create buffer sink\n");
  129.         return -1;
  130.     }


  131.     if (avfilter_link(buffersrc_ctx, 0, buffersink_ctx, 0) < 0) {
  132.         av_log(null, av_log_error, "cannot link filters\n");
  133.         return -1;
  134.     }


  135.     if (avfilter_graph_config(filter_graph, null) < 0) {
  136.         av_log(null, av_log_error, "cannot configure filter graph\n");
  137.         return -1;
  138.     }


  139.     // open output file and find video stream
  140.     avformatcontext *out_fmt_ctx = null;
  141.     if (avformat_alloc_output_context2(&out_fmt_ctx, null, null, output_file) < 0) {
  142.         av_log(null, av_log_error, "cannot allocate output context\n");
  143.         return -1;
  144.     }


  145.     if (!out_fmt_ctx) {
  146.         av_log(null, av_log_error, "cannot create output context\n");
  147.         return -1;
  148.     }


  149.     int out_video_stream_index = av_rescale_q(in_fmt_ctx->streams[video_stream_index]->time_base.den, in_fmt_ctx->streams[video_stream_index]->time_base.num, codec_ctx->time_base.den) * codec_ctx->time_base.num / in_fmt_ctx->streams[video_stream_index]->time_base.den;


  150.     avstream *out_video_stream = avformat_new_stream(out_fmt_ctx, null);
  151.     if (!out_video_stream) {
  152.         av_log(null, av_log_error, "cannot create output video stream\n");
  153.         return -1;
  154.     }


  155.     if (avcodec_copy_context(out_video_stream->codec, codec_ctx) < 0) {
  156.         av_log(null, av_log_error, "cannot copy codec context to output stream\n");
  157.         return -1;
  158.     }


  159.     out_video_stream->codec->codec_tag = 0;
  160.     if (out_fmt_ctx->oformat->flags & avfmt_globalheader) {
  161.         out_video_stream->codec->flags |= av_codec_flag_global_header;
  162.     }


  163.     // write output file header
  164.     if (avio_open(&out_fmt_ctx->pb, output_file, avio_flag_write) < 0) {
  165.         av_log(null, av_log_error, "cannot open output file: %s\n", output_file);
  166.         return -1;
  167.     }


  168.     if (avformat_write_header(out_fmt_ctx, null) < 0) {
  169.         av_log(null, av_log_error, "cannot write output file header\n");
  170.         return -1;
  171.     }


  172.     // process each frame and write to output file
  173.     avpacket pkt;
  174.     av_init_packet(&pkt);
  175.     pkt.data = null;
  176.     pkt.size = 0;


  177.     avframe *frame = av_frame_alloc();
  178.     avframe *filtered_frame = av_frame_alloc();


  179.     int frame_count = 0;
  180.     while (1) {
  181.         // todo: read a frame from the input file


  182.         // todo: decode the frame


  183.         // todo: send the decoded frame to the filter graph


  184.         // todo: receive the filtered frame from the filter graph


  185.         // todo: encode the filtered frame


  186.         // todo: write the encoded frame to the output file
  187.     }


  188.     // todo: write the trailer and close the output file


  189.     // todo: free resources and close the input file

  190.     return 0;
  191. }


阅读(650) | 评论(0) | 转发(0) |
0

上一篇:

下一篇:没有了

给主人留下些什么吧!~~
")); function link(t){ var href= $(t).attr('href'); href ="?url=" encodeuricomponent(location.href); $(t).attr('href',href); //setcookie("returnouturl", location.href, 60, "/"); }
网站地图