21xrx.com
2025-06-11 18:17:58 Wednesday
文章检索 我的文章 写文章
如何在iOS平台上使用FFmpeg来给视频添加水印
2023-10-18 04:42:07 深夜i     29     0
iOS平台 FFmpeg 视频 水印 添加

在iOS平台上添加水印是一个很常见的需求,而FFmpeg是一个功能强大的多媒体处理库,可以用于在iOS平台上对视频文件进行编辑和处理。本文将介绍如何使用FFmpeg在iOS平台上给视频添加水印。

首先,我们需要将FFmpeg集成到我们的iOS项目中。可以通过CocoaPods或手动添加静态库的方式来实现。一旦我们成功地集成了FFmpeg,就可以开始编写代码了。

1. 导入头文件

在我们的代码中,首先需要导入FFmpeg的头文件:

#import <ffmpeg/avformat.h>
#import <ffmpeg/avfilter.h>
#import <ffmpeg/avdevice.h>

2. 打开输入文件并创建输出文件

在添加水印之前,我们需要打开输入文件并创建输出文件。

objective-c
AVFormatContext *inputFormatContext = avformat_alloc_context();
avformat_open_input(&inputFormatContext, [inputFilePath UTF8String], NULL, NULL);
AVFormatContext *outputFormatContext = avformat_alloc_context();
avformat_alloc_output_context2(&outputFormatContext, NULL, NULL, [outputFilePath UTF8String]);

3. 获取输入文件的视频流

我们需要获取输入文件中的视频流,以便进行后续的处理。

objective-c
AVStream *inputVideoStream = NULL;
for (int i = 0; i < inputFormatContext->nb_streams; i++) {
  if (inputFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
    inputVideoStream = inputFormatContext->streams[i];
    break;
  }
}

4. 创建滤镜过滤器图

FFmpeg使用滤镜过滤器图来对视频进行处理。我们需要创建一个滤镜过滤器图,并将其与输出文件相关联。

objective-c
AVFilterGraph *filterGraph = avfilter_graph_alloc();
AVFilter *inputFilter = avfilter_get_by_name("buffer");
AVFilter *outputFilter = avfilter_get_by_name("buffersink");
NSString *filterDescription = [NSString stringWithFormat:@"[in]drawtext=fontfile=%@:text='%@':x=(w/2-text_w/4):y=(h/2-text_h/2):fontsize=20:fontcolor=white@0.8:box=1:boxcolor=black@0.5[out]", fontFilePath, watermarkText];
avfilter_graph_create_filter(&inputFilterContext, inputFilter, "in", NULL, NULL, filterGraph);
avfilter_graph_create_filter(&outputFilterContext, outputFilter, "out", NULL, NULL, filterGraph);
AVFilterInOut *outputs = avfilter_inout_alloc();
AVFilterInOut *inputs = avfilter_inout_alloc();
outputs->name = av_strdup("in");
outputs->filter_ctx = inputFilterContext;
outputs->pad_idx = 0;
outputs->next = NULL;
inputs->name = av_strdup("out");
inputs->filter_ctx = outputFilterContext;
inputs->pad_idx = 0;
inputs->next = NULL;
avfilter_graph_parse(filterGraph, [filterDescription UTF8String], inputs, outputs, NULL);
avfilter_graph_config(filterGraph, NULL);

5. 创建输出文件的视频流

我们还需要创建输出文件的视频流,并将其与滤镜过滤器图相关联。

objective-c
AVStream *outputVideoStream = avformat_new_stream(outputFormatContext, NULL);
AVCodecContext *outputCodecContext = avcodec_alloc_context3(NULL);
avcodec_parameters_to_context(outputCodecContext, outputVideoStream->codecpar);
outputCodecContext->codec_id = AV_CODEC_ID_MPEG4;
outputCodecContext->codec_type = AVMEDIA_TYPE_VIDEO;
outputCodecContext->width = inputVideoStream->codecpar->width;
outputCodecContext->height = inputVideoStream->codecpar->height;
outputCodecContext->pix_fmt = inputVideoStream->codecpar->format;
outputCodecContext->time_base = inputVideoStream->time_base;
outputCodecContext->bit_rate = inputVideoStream->codecpar->bit_rate;
outputCodecContext->gop_size = inputVideoStream->codecpar->gop_size;
avcodec_parameters_from_context(outputVideoStream->codecpar, outputCodecContext);
avio_open(&outputFormatContext->pb, [outputFilePath UTF8String], AVIO_FLAG_WRITE);
avformat_write_header(outputFormatContext, NULL);
avfilter_link(inputFilterContext, 0, inputs->filter_ctx, inputs->pad_idx);
avfilter_link(outputFilterContext, 0, outputs->filter_ctx, outputs->pad_idx);
av_buffersink_set_frame_size(outputFilterContext, outputCodecContext->frame_size);
av_buffersink_set_frame_pts(outputFilterContext, 1);

6. 对每一帧进行处理,并写入输出文件

最后,我们需要对输入文件的每一帧进行处理,并将处理后的帧写入输出文件。

objective-c
AVFrame *inputFrame = av_frame_alloc();
AVFrame *outputFrame = av_frame_alloc();
while (av_read_frame(inputFormatContext, &inputPacket) >= 0) {
  if (inputPacket.stream_index == inputVideoStream->index) {
    avcodec_send_packet(inputCodecContext, &inputPacket);
    while (avcodec_receive_frame(inputCodecContext, inputFrame) == 0) {
      // 给帧添加水印
      av_buffersrc_add_frame_flags(inputFilterContext, inputFrame, AV_BUFFERSRC_FLAG_KEEP_REF);
      av_buffersink_get_frame(outputFilterContext, outputFrame);
      // 写入输出文件
      avcodec_send_frame(outputCodecContext, outputFrame);
      avcodec_receive_packet(outputCodecContext, &outputPacket);
      av_interleaved_write_frame(outputFormatContext, &outputPacket);
      av_frame_unref(outputFrame);
    }
  }
  av_packet_unref(&inputPacket);
}
av_write_trailer(outputFormatContext);

7. 清理和释放资源

在处理完所有帧之后,我们需要进行必要的清理和资源释放。

objective-c
avfilter_graph_free(&filterGraph);
avformat_close_input(&inputFormatContext);
avformat_free_context(inputFormatContext);
avformat_free_context(outputFormatContext);

通过以上步骤,我们可以使用FFmpeg在iOS平台上给视频添加水印。当然,根据实际需求,我们还可以通过FFmpeg来实现更多的视频处理操作。这里只是给出了一个简单的示例,希望能对你有所帮助。

  
  

评论区