如果遇到“No such filter: 'drawtext'
”错误,通常是由于 FFmpeg 未正确编译或缺少支持 drawtext 滤镜的库。在使用 FFmpeg 时,确保它是用 libfreetype 支持编译的。
如果在编译 FFmpeg 时没有使用 --enable-libfreetype
选项,就不能使用 drawtext
滤镜。
通过以下命令来检查 FFmpeg 是否支持 drawtext
滤镜:
ffmpeg -filters | grep drawtext
在运行 ./configure --enable-libfreetype
时,如果遇到这个错误,说明pkg-config
没有找到 freetype2
。这通常是因为没有安装 pkg-config
或 freetype
开发包。
ERROR: freetype2 not found using pkg-config
解决方法,安装 pkg-config
和 freetype
开发包(ubuntu):
sudo apt-get update
sudo apt-get install pkg-config libfreetype6-dev
代码实现如下:
#include <iostream>
#include <fstream>
#include <string>
extern "C"{
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavfilter/avfilter.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include <libavutil/opt.h>
}
void add_text_to_video(const char* input_filename, const char* output_filename, const char* text) {
av_register_all();
avfilter_register_all();
AVFormatContext* formatContext = nullptr;
if (avformat_open_input(&formatContext, input_filename, nullptr, nullptr) < 0) {
std::cerr << "Could not open input file" << std::endl;
return;
}
if (avformat_find_stream_info(formatContext, nullptr) < 0) {
std::cerr << "Could not find stream info" << std::endl;
return;
}
AVCodec* decoder = nullptr;
int videoStreamIndex = av_find_best_stream(formatContext, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
if (videoStreamIndex < 0) {
std::cerr << "Could not find video stream" << std::endl;
return;
}
AVCodecContext* codecContext = avcodec_alloc_context3(decoder);
avcodec_parameters_to_context(codecContext, formatContext->streams[videoStreamIndex]->codecpar);
avcodec_open2(codecContext, decoder, nullptr);
AVFilterGraph* filterGraph = avfilter_graph_alloc();
AVFilterContext* buffersrcContext = nullptr;
AVFilterContext* buffersinkContext = nullptr;
const AVFilter* buffersrc = avfilter_get_by_name("buffer");
const AVFilter* buffersink = avfilter_get_by_name("buffersink");
char args[512];
snprintf(args, sizeof(args),
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
codecContext->width, codecContext->height, codecContext->pix_fmt,
formatContext->streams[videoStreamIndex]->time_base.num, formatContext->streams[videoStreamIndex]->time_base.den,
codecContext->sample_aspect_ratio.num, codecContext->sample_aspect_ratio.den);
avfilter_graph_create_filter(&buffersrcContext, buffersrc, "in", args, nullptr, filterGraph);
avfilter_graph_create_filter(&buffersinkContext, buffersink, "out", nullptr, nullptr, filterGraph);
AVFilterInOut* inputs = avfilter_inout_alloc();
AVFilterInOut* outputs = avfilter_inout_alloc();
inputs->name = av_strdup("in");
inputs->filter_ctx = buffersrcContext;
inputs->pad_idx = 0;
inputs->next = nullptr;
outputs->name = av_strdup("out");
outputs->filter_ctx = buffersinkContext;
outputs->pad_idx = 0;
outputs->next = nullptr;
std::string drawtextArgs = "drawtext=fontfile=/usr/share/fonts/truetype/freefont/FreeSans.ttf:text='" + std::string(text) + "':x=10:y=10:fontsize=24:fontcolor=white";
avfilter_graph_parse_ptr(filterGraph, drawtextArgs.c_str(), &inputs, &outputs, nullptr);
avfilter_graph_config(filterGraph, nullptr);
AVFormatContext* outputFormatContext = nullptr;
avformat_alloc_output_context2(&outputFormatContext, nullptr, nullptr, output_filename);
AVStream* out_stream = avformat_new_stream(outputFormatContext, nullptr);
avcodec_parameters_copy(out_stream->codecpar, formatContext->streams[videoStreamIndex]->codecpar);
if (avio_open(&outputFormatContext->pb, output_filename, AVIO_FLAG_WRITE) < 0) {
std::cerr << "Could not open output file" << std::endl;
return;
}
avformat_write_header(outputFormatContext, nullptr);
AVPacket packet;
av_init_packet(&packet);
AVFrame* frame;
while (av_read_frame(formatContext, &packet) >= 0) {
if (packet.stream_index == videoStreamIndex) {
avcodec_send_packet(codecContext, &packet);
while (avcodec_receive_frame(codecContext, frame) >= 0) {
frame->pts = frame->best_effort_timestamp;
av_buffersrc_add_frame(buffersrcContext, frame);
while (av_buffersink_get_frame(buffersinkContext, frame) >= 0) {
av_interleaved_write_frame(outputFormatContext, &packet);
av_frame_unref(frame);
}
}
}
av_packet_unref(&packet);
}
av_write_trailer(outputFormatContext);
avfilter_graph_free(&filterGraph);
avcodec_free_context(&codecContext);
avformat_close_input(&formatContext);
avformat_free_context(outputFormatContext);
av_frame_free(&frame);
av_packet_unref(&packet);
}
int main() {
const char* input_filename = "input.mp4";
const char* output_filename = "output.mp4";
const char* text = "Hello, World!";
add_text_to_video(input_filename, output_filename, text);
return 0;
}
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » ffmpeg滤镜-添加文字-cpp
发表评论 取消回复