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

FFmpeg 基础模块:容器相关的 API 操作

目录

AVFormat 模块

AVFormat 前处理部分

AVFormat 读写处理部分

小结

思考


FFmpeg 目录中包含了 FFmpeg 库代码目录、构建工程目录、自测子系统目录等,具体内容如下:

现在你知道 FFmpeg 的源代码目录中都包含了哪些内容,在之后使用 FFmpeg 的 API 做开发遇到问题时,就可以通过查看源代码来了解更多、更详细的内部实现了。

AVFormat 模块

从 FFmpeg 的目录结构中可以看出,libavformat 主要是用来做封装格式处理的模块,如果不做转码,只做切片或者封装格式转换的话,基本上用 AVFormat 模块就可以,下面我们来看一下 AVFormat 模块都有哪些常用接口提供给我们使用。

avformat_version、avformat_configuration、avformat_license 这三个接口都是用来调试的,确定使用的 FFmpeg 版本、编译配置信息以及 License。因为 FFmpeg 本身是 LGPL 的,但是FFmpeg 可以引入其他第三方库,比如 libfdkaac 是 nonfree 的,就有可能存在专利收费的法律风险。

如果引入了 libx264 这样的编码器,FFmpeg 会自动切换成 GPL 的 License,这个时候如果你想要基于 FFmpeg 做定制或者开发,就需要注意 GPL 的 License 法律风险,相关情况最好还是咨询一下开源 License 法律援助律师,尽量避免给自己的项目和公司带来不必要的麻烦。

GPL 是 GNU 公共许可证的缩写。它通常会具有 “传染性”,当某一项目使用了 GPL 下的软件部分的话,那么该项目将被 “感染”变成了 GPL 协议下产品,也就是你需要将其开源和免费。LGPL 是  GNU 宽松公共许可证的缩写,它是 GPL 的一个为主要为类库使用设计的开源协议。和 GPL 不同,LGPL 允许商业软件通过类库引用方式使用 LGPL 类库而不需要开源商业软件的代码。——关于开源许可 GPL 与 LGPL

AVFormat 前处理部分

当我们做音视频内容处理的时候,首先接触到的应该是 AVFormatContext 模块相关的操作,也就是我们这里说的 AVFormat 部分,但是操作 AVFormat 的时候,会有一个前处理部分,主要包含网络初始化、模块遍历、申请上下文空间、打开文件,还有分析音视频流等操作。下面我们逐个了解一下 AVFormat 前处理部分的接口与作用。

  1. avformat_network_init 和 avformat_network_deinit 两个接口,是网络相关模块的初始化和撤销网络相关模块初始化。
  2. av_muxer_iterate 和 av_demuxer_iterate 两个接口,是 muxer 和 demuxer 的遍历接口,如果你想查找自己需要的 muxer 或者 demuxer 是否在当前使用的 FFmpeg 库中,用这两个接口可以全面地查找。
  3. avformat_alloc_context 和 avformat_free_context 两个接口可以用来申请与释放 AVFormatContext 上下文结构。
  4. avformat_new_stream 接口用来创建新的 AVStream。
  5. av_stream_add_side_data 接口用来向 AVStream 中添加新的 side data 信息,例如视频旋转信息,通常是可以存储在 side data 里面的。
  6. av_stream_new_side_data 接口用来申请新的 side data。
  7. av_stream_get_side_data 接口用来获取 side data。
  8. avformat_alloc_output_context2 接口用来申请将要输出的文件的 AVFormatContext,可以通过 avformat_free_context 释放申请的 AVFormatContext。
  9. av_find_input_format 接口可以根据传入的 short_name 来获得对应的 AVFormat 模块,例如 MP4。
  10. avformat_open_input 接口主要用处是打开一个 AVInputFormat,并挂在 AVFormatContext 模块上,这个接口里面会调用 avformat_alloc_context,可以通过接口 avformat_close_input 来关闭和释放 avformat_open_input 里对应的 alloc 操作。
  11. av_find_best_stream 接口用来找到多个视频流或多个音频流中最优的那个流。
  12. avformat_find_stream_info 接口主要用来建立 AVStream 的信息,获得的信息大多数情况下是比较准确的。使用 avformat_find_stream_info 接口来获得 AVStream 信息的话,会比较消耗时间。因为里面需要通过 try_decode 进行解码操作,来获得更精准的 AVStream 信息,所以有些固定场景不使用 avformat_find_stream_info,是为了节省时间方面的开销。

我们可以通过 probesize、analyzeduration 来设置读取的音视频数据的阈值,avformat_find_stream_info 里面也会遍历这个阈值,所以通过设置 probesize 和 analyzeduration 也可以节省一些时间。

如果有多个类似 AAC 或者 H264 这样的 codec 的话,avformat_find_stream_info 内部会使用最先遍历到的 codec,其实我们可以在使用 avformat_find_stream_info 之前指定解码器,预期的结果会更准确一些。

AVFormat 读写处理部分

看完 AVFormat 前处理部分的操作,接下来我们进入 AVFormat 读写处理的部分。

  1. av_read_frame 接口用来从 AVFormatContext 中读取 AVPacket,AVPacket 里面存储的内容在之前有讲过,这里就不重复讲解了。
  2. 当拖动进度条的时候,我们可以调用 avformat_seek_file(旧版是 av_seek_frame)接口,seek 到自己想要指定的位置,但前提是对应的封装格式得支持精确 seek,seek 支持以下四种模式。
AVSEEK_FLAG_BACKWARD //往回seek
AVSEEK_FLAG_BYTE //以字节数的方式seek
AVSEEK_FLAG_ANY //可seek到任意帧
AVSEEK_FLAG_FRAME //以帧数量的方式seek
  1. avformat_flush 接口主要是用来清空当前 AVFormatContext 中的 buffer。
  2. avformat_write_header 接口主要用在“写”操作的开头部分,通常指传输协议的开始,写封装格式头部。avformat_write_header 里会调用到 avformat_init_output,通常 avformat_write_header 函数的最后一个参数可以传入 Option,Option 可以控制容器模块中的 Option,关于如何查看封装容器格式的 Option 参数,我们之前的时候讲过,你可以回顾一下。

写 MP4 文件有很多 Option,可以通过 ffmpeg -h muxer=mp4 看到生成 MP4 的一些列参数,也就是 Option。

  1. avformat_init_output 接口主要用来做容器格式初始化部分的操作,例如打开文件,或者有一些容器格式内部的信息需要初始化的时候。
  2. av_interleaved_write_frame 接口支持在写入 AVPacket 的时候,根据 dts 时间戳交错写入数据。使用这个接口有一个需要注意的地方,就是数据会先写入到 buffer 里用来交错存储数据,这个 buffer 会不断变大,如果有必要的话,可以考虑自己调用 avio_flush 或者写 NULL 把 buffer 写到磁盘。

我们在存储音视频数据的时候,如果是顺序读取音视频数据的话,音视频数据交错存储比较好,因为这样可以给内存、硬盘或者网络节省很多开销。

  1. av_write_frame 接口是不按照交错的形式存储 AVPacket,不过在写入文件的时候是直接写入到磁盘,不会有 buffer,所以可以考虑自己先做交错再用这个接口,不过我一般选择使用 av_interleaved_write_frame,因为比较方便,不需要自己做数据交错排列的操作。
  2. av_write_trailer 接口是写数据到封装容器的收尾部分。可以关闭和释放在此之前申请的内存,另外,MP4 文件如果需要把 moov 移动到 MP4 文件头部,也是在这个接口里面完成的。

小结

FFmpeg 中有很多重要的模块,比如 AVFormat 模块、AVcodec 模块、AVfilter 模块等。其中 AVFormat 是用来做封装格式处理的模块。这个模块的内部提供了很多常用的接口,比如前处理部分的 avformat_find_stream_info 等接口,读写处理部分的 avformat_write_header、av_interleaved_write_frame 等接口,了解这些接口的用途和可能出现的问题及解决办法,可以让我们在实践中更好地使用它们去做容器封装和解封装方面的操作。

关于 AVFormat 模块中 API 接口更多的使用方式,比如说参数相关的内容,你还需要多看一看 avformat.h 头文件中的注释和参数说明。如果你还是掌握不住这些接口的使用方式的话,也可以根据我的建议,先把源代码下来,去看一下 API 里实现的过程来加深理解。

思考

我们介绍最后一个接口 av_write_trailer 的时候,提到它支持把 MP4 的 moov 移动到文件的头部,在 FFmpeg 的命令行参数里面使用的是 -movflags faststart,那么如果我用 API 的话,需要在哪个接口里面传递这个参数呢?

相关文章:

FFmpeg 基础模块:容器相关的 API 操作

目录 AVFormat 模块 AVFormat 前处理部分 AVFormat 读写处理部分 小结 思考 FFmpeg 目录中包含了 FFmpeg 库代码目录、构建工程目录、自测子系统目录等,具体内容如下: 现在你知道 FFmpeg 的源代码目录中都包含了哪些内容,在之后使用 FFm…...

SpringMVC+统一表现层返回值+异常处理器

一、统一表现层返回值 根据我们不同的处理方法,返回的数据格式都会不同,例如添加只返回true|false,删除同理,而查询却返回数据。 Result类 为此我们封装一个result类来用于表现层的返回。 public class Result {//描述统一格式…...

2023年地理信息系统与遥感专业就业前景与升学高校排名选择

活动地址:毕业季进击的技术er 地理信息系统(GIS,Geographic Information System),又称“地理信息科学”(Geographic Information Science),是一种具有信息系统空间专业形式的数据管理…...

第五章:最新版零基础学习 PYTHON 教程—Python 字符串操作指南(第二节 - Python 字符串—Python 字符串 len()的语法)

Python len() 函数返回字符串的长度。 目录 Python len() 语法 Python len() 示例 示例 1:带有元组和字符串的 Len() 函数...

ubuntu22.04使用共享文件设置

从ubuntu20.04开始,设置共享文件就很麻烦 第一步: 安装samba: sudo apt install samba第二步; 创建一个共享文件夹 我以桌面Desktop为例子 第三步: 设置密码: sudo smbpasswd -a ygc第四步: sudo vim …...

pycharm配置python3.8版本专门用于undecteded_chromedriver测试

pycharm配置python3.8版本专门用于undecteded_chromedriver测试 作者:虚坏叔叔 博客:https://pay.xuhss.com 早餐店不会开到晚上,想吃的人早就来了!😄 一、Pycharm及python环境的配置 1.安装python-3.8.7rc1-amd64.e…...

基于SpringBoot的民宿在线预定平台

目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 民宿信息管理 民宿资讯管理 民宿分类管理 用户注册 民宿信息 我的订单 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实…...

CTFHUB SSRF

目录 web351 ​编辑 web352 web353 web354 sudo.cc 代表 127 web355 host长度 web356 web357 DNS 重定向 web358 bypass web359 mysql ssrf web360 web351 POST查看 flag.php即可 web352 <?php error_reporting(0); highlight_file(__FILE__); $url$_…...

FreeRTOS入门教程(队列详细使用示例)

文章目录 前言一、队列基本使用二、如何分辨数据源三、传输大块数据总结 前言 上篇文章我们已经讲解了队列的概念和队列相关的API函数&#xff0c;那么本篇文章的话就开始带大家来学习使用队列。 一、队列基本使用 这个例子将会创建三个任务&#xff0c;其中两个任务用来发送…...

【Kafka专题】Kafka收发消息核心参数详解

目录 前置知识课程内容一、从基础的客户端说起&#xff08;Java代码集成使用&#xff09;1.1 消息发送者源码示例1.2 消息消费者源码示例1.3 客户端使用小总结 *二、从客户端属性来梳理客户端工作机制*2.1 消费者分组消费机制2.2 生产者拦截器机制2.3 消息序列化机制2.4 消息分…...

matlab 使用激光雷达检测、分类和跟踪车辆

目录 1、算法概述2、加载数据3、地平面分割4、语义分割5、聚类和边界盒拟合6、可视化设置7、循环遍历数据8、面向跟踪的包围盒9、 总结10、 支持功能11、 参考</...

代码随想录训练营二刷第四十八天 | 139.单词拆分 背包问题总结

代码随想录训练营二刷第四十八天 | 139.单词拆分 背包问题总结 一、139.单词拆分 题目链接&#xff1a;https://leetcode.cn/problems/word-break/ 思路&#xff1a;单词拼字符串&#xff0c;完全背包。定义dp[i]&#xff0c;为true表示可以拆分为一或多个单词。可能会出现ab…...

【数据挖掘】2017年 Quiz 1-3 整理 带答案

目录 Quiz 1Quiz 2Quiz 3Quiz 1 Answer Problems 1-2 based on the following training set, where A , B , C A, B, C A,B,</...

吃鸡高手必备工具大揭秘!提高战斗力,分享干货,一站满足!

大家好&#xff01;你是否想提高吃鸡游戏的战斗力&#xff0c;分享顶级的游戏作战干货&#xff0c;方便进行吃鸡作图和查询装备皮肤库存&#xff1f;是否也担心被骗&#xff0c;希望查询游戏账号是否在黑名单上&#xff0c;或者查询失信人和VAC封禁情况&#xff1f;在这段视频中…...

集群化环境前置准备

目录 部署 1. 配置多台Linux虚拟机 1.1 首先&#xff0c;关机当前CentOS系统虚拟机&#xff08;可以使用root用户执行init 0来快速关 机&#xff09; 1.2 新建文件夹 1.3 克隆 1.4 同样的操作克隆出&#xff1a;node2和node3 1.5 开启node1&#xff0c;修改主机名为node1&…...

nodejs开发环境搭建

Nodejs是一个开源的、跨平台JavaScript运行时环境&#xff0c;其使用V8引擎对JavaScript脚本执行解释&#xff0c;在前后端分离的应用架构设计中&#xff0c;其既能支持web页面服务应用的开发、也能支持后端接口服务应用的开发&#xff0c;类似于Java语言的J2EE运行时环境&…...

C语言qsort函数

排序qsort int int cmp(const void *a, const void *b) {return *(int *)a - *(int *)b;//先强转成int型&#xff0c;后解引用取值比较大小 }字符串数组 char a[] “hello world” //字符串数组&#xff0c;存放的是字符 int cmp(const void *a, const void *b) {return *(…...

如何使用 Hotshot 通过文字生成 GIF 动画

Hotshot 是一个基于人工智能的工具&#xff0c;可用于通过文字生成 GIF 动画。该工具使用最新的图像生成技术来创建逼真的动画&#xff0c;即使是复杂的文字描述也能做到。 hotshot访问地址 使用 Hotshot 生成 GIF 动画 要使用 Hotshot 生成 GIF 动画&#xff0c;您需要首先…...

吃鸡高手必备!这些技巧帮你提高战斗力!

大家好&#xff01;作为一名吃鸡玩家&#xff0c;我们都想提高自己的战斗力&#xff0c;享受顶级游戏作战干货&#xff0c;装备皮肤库存展示和查询&#xff0c;并避免被骗游戏账号。在这里&#xff0c;我将为大家介绍一些实用的技巧和工具&#xff0c;让你成为吃鸡高手&#xf…...

XV6 操作系统实验

环境搭建 ubuntu 新建一个文件setup.sh&#xff0c;内容如下 #获取工具链 git clone --recursive https://github.com/riscv/riscv-gnu-toolchain #安装必要依赖 sudo apt-get update sudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev li…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...