当前位置: 首页 > article >正文

FFmpeg视频处理入门级教程

在这里插入图片描述

一、FFmpeg常规处理流程

初始化上下文
打开媒体文件
查找流信息
获取视频流索引
获取解码器
打开解码器
循环读取数据包
是否视频流?
解码数据包
处理解码帧
释放资源

文字说明:

  1. 初始化容器格式和编解码器
  2. 打开输入文件建立连接
  3. 解析媒体流信息(时长/分辨率/编码格式等)
  4. 遍历找到视频流索引
  5. 根据编码器ID查找对应解码器
  6. 初始化并配置解码器上下文
  7. 循环读取压缩数据包
  8. 判断数据包类型并解码视频帧
  9. 对原始帧进行格式转换或处理
  10. 释放所有分配的资源

二、FFmpeg核心模块解析

2.1 模块预览

FFmpeg由多个功能模块组成,以下是8个核心模块的详细说明:

模块名称功能描述典型应用场景
libavcodec编解码库,包含主流音视频编码器的实现H.264解码、MP3编码、音频重采样
libavformat封装/解封装库,处理多媒体容器格式(MP4/MKV/FLV等)解析MP4文件头信息、将H.264流封装为TS格式
libavutil基础工具库,提供通用数据结构、数学运算等基础功能时间戳计算、内存管理、日志输出
libswscale图像处理库,实现色彩空间转换和图像缩放YUV420转RGB24、4K视频缩放到1080p
libavfilter滤镜处理库,支持多路视频流的复杂滤镜处理添加水印、视频画中画、音频混音
libavdevice设备访问库,支持采集显示设备数据摄像头抓取画面、屏幕录制、音频采集卡输入
libswresample音频重采样库,处理音频格式转换48kHz转44.1kHz、单声道转立体声、PCM格式转换
libpostproc后处理库,提供视频后期效果处理视频去块效应、MPEG视频补偿

模块依赖关系:

avformat → avcodec → avutil
avfilter → avformat
swscale/swresample → avutil

2.2 部分模块说明详解:

libavcodec 工作机理

输入编码数据
解析帧头信息
初始化解码器
空间分配
熵解码
反量化
反变换
运动补偿
输出YUV帧

libavfilter 处理链示例

// 创建滤镜图:视频缩放+叠加水印
filter_graph = avfilter_graph_alloc();
avfilter_graph_create_filter(&buffer_src_ctx, "输入源");
avfilter_graph_create_filter(&scale_filter, "scale=640:480");
avfilter_graph_create_filter(&overlay_filter, "overlay=10:10");
avfilter_graph_create_filter(&buffer_sink_ctx, "输出端");// 连接滤镜节点
avfilter_link(buffer_src_ctx, 0, scale_filter, 0);
avfilter_link(scale_filter, 0, overlay_filter, 0);
avfilter_link(overlay_filter, 0, buffer_sink_ctx, 0);

模块选择原则

  1. 文件操作:优先使用avformat
  2. 编解码处理:使用avcodec
  3. 图像处理:使用swscale或avfilter
  4. 实时流采集:配合avdevice使用

三、核心API函数说明

函数名称功能描述关键参数说明
av_register_all()注册所有封装格式与编解码器(新版本已弃用)无参数
avformat_open_input()打开媒体文件并初始化AVFormatContextps: 上下文指针地址
url: 文件路径
fmt: 强制指定格式(可NULL)
avformat_find_stream_info()获取媒体流详细信息ic: 上下文指针
options: 额外选项(通常NULL)
avcodec_find_decoder()根据编码ID查找解码器id: 编码格式ID(如AV_CODEC_ID_H264)
avcodec_open2()打开解码器avctx: 解码器上下文
codec: 解码器指针
options: 额外参数
av_read_frame()读取媒体文件中的数据包s: 上下文指针
pkt: 输出的数据包
avcodec_send_packet()发送压缩数据到解码器avctx: 解码器上下文
avpkt: 输入数据包
avcodec_receive_frame()从解码器获取解码后的帧avctx: 解码器上下文
frame: 输出的原始帧
sws_getContext()初始化图像缩放转换上下文参数包含源/目标分辨率、格式等图像特征
sws_scale()执行像素格式转换和缩放sws_ctx: 转换上下文
srcSlice: 源数据指针

四、视频解码显示实战

实现一个ffmpeg读取视频文件,并使用opencv进行显示的例子。

4.1 实现流程图

初始化FFmpeg
打开视频文件
获取视频流信息
定位视频流索引
配置解码器
初始化SWS转换上下文
循环读取帧
解码完成?
读取数据包
是视频包?
发送到解码器
接收解码帧
转换为RGB格式
OpenCV显示
释放资源

4.2 完整实现代码

#include <opencv2/opencv.hpp>
extern "C" {
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}int main() {// 初始化FFmpegavformat_network_init();AVFormatContext* fmt_ctx = NULL;// 打开输入文件if(avformat_open_input(&fmt_ctx, "test.mp4", NULL, NULL) != 0){printf("无法打开文件\n");return -1;}// 获取流信息if(avformat_find_stream_info(fmt_ctx, NULL) < 0){printf("无法获取流信息\n");return -1;}// 查找视频流索引int video_stream = -1;for(int i=0; i<fmt_ctx->nb_streams; i++){if(fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){video_stream = i;break;}}// 获取解码器参数AVCodecParameters* codec_par = fmt_ctx->streams[video_stream]->codecpar;const AVCodec* decoder = avcodec_find_decoder(codec_par->codec_id);// 初始化解码器上下文AVCodecContext* codec_ctx = avcodec_alloc_context3(decoder);avcodec_parameters_to_context(codec_ctx, codec_par);avcodec_open2(codec_ctx, decoder, NULL);// 准备转换上下文(YUV->RGB)SwsContext* sws_ctx = sws_getContext(codec_ctx->width, codec_ctx->height, codec_ctx->pix_fmt,codec_ctx->width, codec_ctx->height, AV_PIX_FMT_RGB24,SWS_BILINEAR, NULL, NULL, NULL);// 准备帧结构AVFrame* frame = av_frame_alloc();AVFrame* rgb_frame = av_frame_alloc();uint8_t* buffer = (uint8_t*)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_RGB24, codec_ctx->width, codec_ctx->height, 1));av_image_fill_arrays(rgb_frame->data, rgb_frame->linesize, buffer, AV_PIX_FMT_RGB24, codec_ctx->width, codec_ctx->height, 1);AVPacket pkt;while(av_read_frame(fmt_ctx, &pkt) >= 0){if(pkt.stream_index == video_stream){// 发送到解码器avcodec_send_packet(codec_ctx, &pkt);// 接收解码帧while(avcodec_receive_frame(codec_ctx, frame) == 0){// 格式转换sws_scale(sws_ctx, (const uint8_t* const*)frame->data, frame->linesize,0, codec_ctx->height,rgb_frame->data, rgb_frame->linesize);// OpenCV显示cv::Mat img(codec_ctx->height, codec_ctx->width, CV_8UC3, rgb_frame->data[0]);cv::imshow("Video", img);cv::waitKey(1);}}av_packet_unref(&pkt);}// 释放资源av_frame_free(&frame);av_frame_free(&rgb_frame);avcodec_free_context(&codec_ctx);avformat_close_input(&fmt_ctx);sws_freeContext(sws_ctx);return 0;
}

4.3 关键代码解析

  1. 图像转换配置:
sws_ctx = sws_getContext(   // 创建转换器实例srcW, srcH, srcFormat,  // 源图像参数dstW, dstH, dstFormat,  // 目标图像参数flags,                  // 缩放算法选择...);                   // 其他可选参数
  1. OpenCV显示核心:
cv::Mat img(height, width,        // 创建Mat对象CV_8UC3,                      // 数据类型:8位无符号3通道rgb_frame->data[0],           // RGB数据首地址rgb_frame->linesize[0]);      // 每行字节数(步长)
  1. 解码循环逻辑:
while(av_read_frame() >=0){       // 读取压缩包if(视频流){avcodec_send_packet();    // 送入解码队列while(avcodec_receive_frame() ==0){ // 获取解码帧// 处理帧数据}}av_packet_unref();            // 必须释放数据包
}

五、常见问题处理

  1. 颜色显示异常:检查像素格式转换参数(AV_PIX_FMT_RGB24)
  2. 无法打开文件:检查文件路径和FFmpeg的协议支持
  3. 内存泄漏:确保每个av_malloc都有对应的av_free
  4. 花屏现象:检查解码器是否成功初始化,数据包是否完整

相关文章:

FFmpeg视频处理入门级教程

一、FFmpeg常规处理流程 #mermaid-svg-W8X1llNEyuYptV3I {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-W8X1llNEyuYptV3I .error-icon{fill:#552222;}#mermaid-svg-W8X1llNEyuYptV3I .error-text{fill:#552222;str…...

C/C++ | 每日一练 (4)

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 C/C | 每日一练 (4)题目参考答案基础容器序列容器std:…...

数据安全_笔记系列06:数据生命周期管理(存储、传输、使用、销毁)深度解析

数据安全_笔记系列06&#xff1a;数据生命周期管理&#xff08;存储、传输、使用、销毁&#xff09;深度解析 数据生命周期管理&#xff08;存储、传输、使用、销毁&#xff09;详解 数据生命周期管理&#xff08;Data Lifecycle Management, DLM&#xff09;是围绕数据从创建…...

后端返回文件流,前端导出excel文件

1、当后端接口返回文件流时&#xff0c;需前端导出excel文件&#xff0c;在请求中添加 responseType: blob限制条件&#xff0c;根据返回的文件流导出 封装的方法&#xff1a; /** * 公共的导出excel方法 * param {*} content 后端接口返回的二进制文件 * param {*} name 导出…...

Python开发 Flask框架面试题及参考答案

目录 Flask 的核心设计理念是什么?与 Django 相比有哪些显著差异? 解释 Flask 框架的核心理念及其作为 “微框架” 的优缺点 Flask 的依赖库有哪些?简述 Werkzeug 和 Jinja2 的作用 什么是 WSGI?Flask 如何基于 WSGI 实现服务端与应用的交互 解释 RESTful API 的设计原…...

Python 3.11 69 个内置函数(完整版)

一、数学与数值运算&#xff08;12个&#xff09; 函数 说明 示例 abs(x) 绝对值 abs(-5)→ 5 divmod(a, b) 返回(a//b, a%b) divmod(7,3)→ (2,1) max(iterable) 最大值 max([1,2,3])→ 3 min(iterable) 最小值 min([1,2,3])→ 1 pow(a, b) a^b&#xff08;等…...

蓝桥杯备考:贪心算法之矩阵消除游戏

这道题是牛客上的一道题&#xff0c;它呢和我们之前的排座位游戏非常之相似&#xff0c;但是&#xff0c;排座位问题选择行和列是不会改变元素的值的&#xff0c;这道题呢每每选一行都会把这行或者这列清零&#xff0c;所以我们的策略就是先用二进制把选择所有行的情况全部枚举…...

跳跃游戏两则

跳跃游戏 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 思路 这里只…...

机器视觉--相机曝光

在现代工业生产的精密舞台上&#xff0c;机器视觉技术已然成为推动生产自动化、智能化的关键力量。而工业相机作为机器视觉系统的 “眼睛”&#xff0c;其曝光环节更是决定了视觉信息获取的质量与精度&#xff0c;如同为工业生产赋予了一双洞察入微的 “智慧之眼”&#xff0c;…...

基于 CFD 预测的机器学习第 2 部分:在 Benchmark 应用程序上使用 Stochos 预测流场

了解机器学习和 Stochos 如何彻底改变制造业的 CFD 预测。 挑战 预测复杂流体动力学场景中的流场一直是工程师和科学家面临的重大挑战。传统的计算流体动力学 &#xff08;CFD&#xff09; 方法需要大量的计算资源和时间&#xff0c;因此难以处理实时预测和大规模模拟。 此外…...

批量导出数据库表到Excel

这篇文章将介绍如何批量的将多个甚至成千上万的数据库表导出为Excel文件。 准备数据 如下图是数据库里的表&#xff0c;我们需要将它们全部导出为excel文件&#xff0c;这里以SQL Server数据库为例 新增导出 打开的卢导表工具&#xff0c;新建数据库连接&#xff0c;这里以S…...

力扣提升第一天

力扣提升第一天 题目链接&#xff1a;https://leetcode.cn/problems/design-memory-allocator/?envTypedaily-question&envId2025-02-25 一开始解题思路 暴力解决法 我奔着先从简单的写法做起&#xff0c;之后再想办法进行改进&#xff0c;心里已经预料到会出现超出时间…...

uni-app 开发 App 、 H5 横屏签名(基于lime-signature)

所用插件&#xff1a;lime-signature 使用到 CSS 特性 绝对定位transform 旋转transform-origin transform 原点 复习一下定位元素&#xff08;相对定位、绝对定位、粘性定位&#xff09; 代码# <template><view class"signature-page"><view clas…...

【Python】Python顺序语句经典题(四)

Python顺序语句经典练习题例题&#xff08;四&#xff09;。题目来源&#xff1a;Acwing 前三期合集&#xff1a;【Python】Python顺序语句经典题合集-CSDN博客 目录 1.最大值 题目描述 解题思路 AC代码 2.距离 题目描述 AC代码 3.燃料消耗 题目描述 AC代码 4.钞票…...

mysql的字符集和比较规则

mysql的字符集和比较规则 一、字符集&#xff08;Character Set&#xff09;二、比较规则&#xff08;Collation&#xff09;三、客户端与服务器的字符集转换四、注意事项总结 深度解读mysql是怎样运行的 MySQL的字符集和比较规则是其处理字符串存储、传输及比较的核心机制&…...

Vue3 + Vite + TS,使用 配置项目别名属性:server

官网地址传送门 点哇点哇&#xff0c;vite 官网传送门 直接上马 server: {https: false, // 是否开启 httpsopen: true, // 是否自动在浏览器中打开port: 8001, // 端口号host: "0.0.0.0",// 跨域代理proxy: {/api: {target: "http://localhost:3000", …...

03_pyqt5 + vlc 实现视频播放器

1.功能需求如图 按钮: 播放/暂停, 前进/后退, 视频上一个/下一个, 打开视频进度条: 视频进度条显示, 进度条拖拽, 音量控制按键控制: 1,2,3,4缩放画面大小, 2.方案选择 开发语言: python UI界面: pyqt5 qt_designed 设计ui布局 视频编码: python-vlc 方案说明: 视频解码可…...

Grafana使用日志5--如何重置Grafana密码

背景 有时候当账号太多的时候&#xff0c;根本记不住所有的账号密码&#xff0c;这时候就很容易登录失败&#xff0c;这时候怎么办呢&#xff1f; 接下来就让我来给大家演示一下Grafana的账号如果忘记了的话&#xff0c;该怎么找回自己的账号密码 操作 让我们来看一下具体的…...

使用 pytest-mock 进行 Python 高级单元测试与模拟

一、单元测试与模拟的意义 在软件开发中,单元测试用于验证代码逻辑的正确性。但实际项目中,代码常依赖外部服务(如数据库、API、文件系统)。直接测试这些依赖会导致: 测试速度变慢测试结果不可控产生副作用(如真实发送邮件)模拟(Mocking) 技术通过创建虚拟对象替代真…...

索提诺比率(Sortino Ratio):更精准的风险调整收益指标(中英双语)

索提诺比率&#xff08;Sortino Ratio&#xff09;&#xff1a;更精准的风险调整收益指标 &#x1f4c9;&#x1f4ca; &#x1f4cc; 什么是索提诺比率&#xff1f; 在投资分析中&#xff0c;我们通常使用 夏普比率&#xff08;Sharpe Ratio&#xff09; 来衡量风险调整后的…...

prometheus+node_exporter+grafana监控K8S信息

prometheusnode_exportergrafana监控K8S 1.prometheus部署2.node_exporter部署3.修改prometheus配置文件4.grafana部署 1.prometheus部署 包下载地址&#xff1a;https://prometheus.io/download/ 将包传至/opt 解压 tar xf prometheus-2.53.3.linux-amd64.tar.gz 移动到…...

IDEA关闭SpringBoot程序后仍然占用端口的排查与解决

IDEA关闭SpringBoot程序后仍然占用端口的排查与解决 问题描述 在使用 IntelliJ IDEA 开发 Spring Boot 应用时&#xff0c;有时即使关闭了应用&#xff0c;程序仍然占用端口&#xff08;例如&#xff1a;4001 端口&#xff09;。这会导致重新启动应用时出现端口被占用的错误&a…...

kafka的ACL配置的sasl.kerberos.principal.to.local.rules配置解释

kafka配置acl认证的用户名转换规则 1、Kerberos中的介绍2、自定义sasl user name3、自定义ssl 的用户名4、关于kafka配置kerberos以及开启acl的实践 1、Kerberos中的介绍 Kerberos 关于此配置项的解释 https://web.mit.edu/Kerberos/krb5-latest/doc/admin/conf_files/krb5_co…...

山东大学软件学院nosql实验三

实验题目&#xff1a; 用Java做简单查询(2学时) 实验内容 用API方式&#xff0c;做简单查询。 实验要求 在以下要求中选择至少2个&#xff0c;使用Java语言实现数据查询&#xff0c;最终把数据输出到前端界面。 &#xff08;1&#xff09;找出年龄小于20岁的所有学生 &…...

Feign 类型转换问题解析:如何正确处理 `ResponseEntity<byte[]>` 返回值

在微服务架构中,Feign 是一种常见的用于服务间调用的客户端,它允许我们通过声明式接口来调用远程服务。使用 Feign 时,我们通常通过接口方法的返回类型来接收服务的响应体。然而,某些情况下,我们会遇到 Feign 无法正确解析响应体类型的问题,尤其是当服务返回一个如 Respo…...

零样本学习 zero-shot

1 是什么 2 如何利用零样本学习进行跨模态迁移&#xff1f; demo代码 安装clip pip install ftfy regex tqdm pip install githttps://github.com/openai/CLIP.git import torch import clip from PIL import Image# 加载 CLIP 模型 device "cuda" if torch.cuda.i…...

《深度学习实战》第3集:循环神经网络(RNN)与序列建模

第3集&#xff1a;循环神经网络&#xff08;RNN&#xff09;与序列建模 引言 在深度学习领域&#xff0c;处理序列数据&#xff08;如文本、语音、时间序列等&#xff09;是一个重要的研究方向。传统的全连接网络和卷积神经网络&#xff08;CNN&#xff09;难以直接捕捉序列中…...

mac下载MAMP6.8.1

因为mac的小皮面板没有php7.4了 链接&#xff1a;c9cc270e6961c17c.dmg官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘 鹅选一 附上大佬写的教程&#xff1a;MAMP PRO教程 - 牛奔 - 博客园...

动态表头导出EasyExcel

在 Spring Boot 中结合 EasyExcel 实现动态表头导出&#xff08;无实体类&#xff0c;表头和字段&#xff08;前端传表名&#xff0c;字段值动态查询&#xff0c;返回List<Map<String,Object>>&#xff09;由前端传递&#xff09;可以通过以下步骤实现。以下是完整…...

Python常见面试题的详解16

1. 如何强行关闭客户端和服务器之间的连接&#xff1f; 在网络编程中&#xff0c;有时需要强行中断客户端和服务器之间的连接。对于基于 TCP 协议的连接&#xff0c;由于其面向连接的特性&#xff0c;需要采取特定的步骤来确保连接被正确关闭&#xff1b;而 UDP 是无连接协议&a…...