FFmpeg 使用详解

视频抽帧实现 视频基本内容了解,视频抽帧实践 阅读详情

FFmpeg官方介绍文档:http://ffmpeg.org/doxygen/trunk/

 

 

FFmpeg的架构

FFmpeg包含以下几个库:

  1. libavutil:工具库,用来辅助进行简单的多媒体编程。包括安全的字符串函数,随机数生成器,一些数据结构,扩展的数学函数,基于编码与多媒体的功能。
  2. libavcodec:编解码相关的库,提供通用的编解码框架,并且包含了多种用于音频流,视频流,字幕流的编解码器,并且包含了一些比特流过滤器(filter)。
  3. libavformat:一个为音频流,视频流,字幕流提供通用多路复用(multiplexing/muxing)与反多路复用(demultiplexing/demuxing)框架的库。包含很多适合各种多媒体格式的复用器(muxer)与解复用器(demuxer)。
  4. libavdevice:一个通用框架库,用来从多媒体设备中抓取多媒体流,或将其渲染至多媒体设备,并且支持许多种设备,包括Video4Linux2, VfW, DShow, ALSA等。
  5. libavfilter:通用音视频过滤(filtering)库,包含多种过滤器,源与接收器。
  6. libswscale:此库提供高度优化的图像缩放,颜色空间与像素格式转换操作。
  7. libswresample:此库提供高度优化的音频重采样,缩放(rematrix)与采样格式转换等操作。

 

常用的数据结构

Ps.数据结构中包含的变量与数据结构列表不做赘述,再用到的时候在做介绍,简介见JavaDoc。

AVCodecContext

FFmpeg中主要的扩展数据结构,包含了编解码信息,音频/视频/字幕流信息等,并且提供了一系列函数来访问或修改这些数据。

AVFormatContext

FFmpeg中另外一个重要的数据结构,包含格式化的I/O上下文,主要用来进行I/O相关的操作,默认使用avformat_alloc_context()来初始化,用处与其字面意思一样,由于Java上的FFmpeg本质上还是JNI技术的一种实现,所以原理同C差不多,也是需要先开辟内存。

AVIOContext

包含字节流I/O上下文,用来管理输入输出数据,同样默认需要使用avio_alloc_context()来进行初始化。

AVFrame

这个数据结构包含了已解码的(raw)音频或视频数据。AVFrame必须使用av_frame_alloc()来初始化,需要注意的是这只会初始化AVFrame自身,具体的缓冲区数据需要使用其他方式来管理。在使用过后,AVFrame还需要使用av_frame_free()来释放。

 

音视频的编解码

对于多媒体编程来说,最为重要的就是多媒体数据的编解码,而编解码器(Codec)是音视频编解码的核心部分,主要涉及到了AVCodecContext这个数据结构。

容器的概念

容器(Container)封装了一个多媒体文件所需要的所有多媒体数据,包括音频,视频,字幕等,需要注意的是,容器的封装格式仅仅描述了多媒体文件以什么方式保存,外部表现为文件的后缀名,例如mp3,mp4,mkv等,并没有描述多媒体数据的具体编码方式,所以只看多媒体文件的后缀名,并不能确定其编码方式。

流与帧

流(Stream)是一种有序的数据载体,在FFmpeg中,可以表现为视频流,音频流,字幕流。流中的某一具体数据元素称为帧(Frame)。

FFmpeg的视频解码过程

一般来说,FFmpeg的视频解码分为以下几个步骤:

  1. 注册所有的容器格式以及其相对应的Codec  av_register_all()
  2. 打开文件,将其读入AVFormatContext中      avformat_open_input()
  3. 从文件中提取流信息                                      avformat_find_stream_info()
  4. 从多个数据流中找到需要的流
  5. 查询流所对应的解码器                                  avcodec_find_decoder()
  6. 打开解码器                                                    avcodec_open2()
  7. 为解码帧分配内存                                         av_frame_alloc()
  8. 将数据从流读入至Packet                               av_read_frame()
  9. 对视频帧进行解码                                          avcodec_decode_video2()

音视频Metadata的获取

Ps.以下是FFmpeg-JavaCPP的Metadata获取方式。

由于原FFmpeg是C编写的,而其JavaCPP实现是运用了JNI技术将其移植至Java,所以在写法上Metadata的获取还是与C有着很大的相似的。PHSS的Metadata读取函数如下:

  1. public Map<String, Object> readMetaData(Path path) throws Exception {
  2. av_register_all();
  3. Map<String, Object> metadataFullMap = new HashMap<>();
  4. Map<String, Object> metadataCurrentMap = new HashMap<>();
  5. AVFormatContext avFormatContext = avformat_alloc_context();
  6. AVDictionaryEntry entry = null;
  7. avformat_open_input(avFormatContext, path.toString(), null, null);
  8. avformat_find_stream_info(avFormatContext, ((PointerPointer) null));
  9. while ((entry = av_dict_get(avFormatContext.metadata(), "", entry, AV_DICT_IGNORE_SUFFIX)) != null) {
  10. metadataFullMap.put(entry.key().getString(), entry.value().getString());
  11. }
  12. for (String key : metadataList) {
  13. if (metadataFullMap.get(key) != null) {
  14. metadataCurrentMap.put(key, metadataFullMap.get(key));
  15. } else {
  16. metadataCurrentMap.put(key, "");
  17. }
  18. }
  19. metadataCurrentMap.put("duration", formatDuration(avFormatContext.duration()));
  20. metadataCurrentMap.put("bitrate", formatBitrate(avFormatContext.streams(0).codecpar().bit_rate()));
  21. metadataCurrentMap.put("sample_rate", avFormatContext.streams(0).codecpar().sample_rate());
  22. metadataCurrentMap.put("bit_depth", avFormatContext.streams(0).codecpar().bits_per_raw_sample());
  23. metadataCurrentMap.put("size", formatSize(path.toFile().length()));
  24. avformat_close_input(avFormatContext);
  25. return metadataCurrentMap;
  26. }

首先是通过av_register_all()函数来注册所有相关的组件,然后使用avformat_alloc_context()函数来新建一个AVFormatContext对象,此对象用来存储多媒体对象的基本构成信息。声明一个AVDictionaryEntry来储存音轨的元数据信息。

使用avformat_open_input()函数来将音轨写入avFormatContext的buffer中,然后使用av_dict_get()函数来将avFormatContext中结构化的metadata数据读入AVDictionaryEntry,然后便可以将AVDictionaryEntry中的元数据读出。

音频封面的获取

由于metadata只包含文字形式的数据,所以需要通过别的方法来获取音频的封面。由于处于FFmpeg的版本更替中,所以封面获取的相关类非常不稳定,因此PHSS暂时选择了FFmpeg-JavaCPP的上层实现,也就是JavaCV来实现音频封面的获取。

  1. public byte[] getArtwork(Path path) throws Exception {
  2. FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(path.toFile());
  3. Java2DFrameConverter converter = new Java2DFrameConverter();
  4. grabber.start();
  5. BufferedImage bufferedImage = converter.getBufferedImage(grabber.grabImage());
  6. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  7. ImageIO.write(bufferedImage, "jpg", outputStream);
  8. grabber.close();
  9. return outputStream.toByteArray();
  10. }

 

FFmpeg的Time base系统以及duration的计算

对于time base(时基)的概念,首先需要介绍关于音视频同步的简单知识。

 

参考文献:

https://protogalaxy.me/ffmpeg%E4%B8%8E%E5%85%B6javacpp%E5%AE%9E%E7%8E%B0%E8%B8%A9%E5%9D%91%E7%BA%AA%E5%BD%95/

https://zh.wikipedia.org/wiki/Java%E6%9C%AC%E5%9C%B0%E6%8E%A5%E5%8F%A3

javacv从入门到精通——第十三章javacv中FFmpegFrameGrabber的start方法执行时间过长,怎么优化? 如何优化javacv中FFmpegFrameGrabber的start方法执行时间 阅读详情

相关推荐

JavaCV与FFmpeg:音视频流处理技巧

JavaCV是一个开源的Java接口,为OpenCV、FFmpeg和其他类似工具提供了封装。它允许Java开发者直接在他们的应用程序中使用这些强大的本地库,而无需深入了解复杂的本地代码。JavaCV特别适用于处理图像和视频数据,提供了一系列的功能,如图像捕获、处理和视频编解码。FFmpeg是一个非常强大的多媒体框架,能处理几乎所有格式的音频和视频。它包括了一系列转码、流处理和播放的工具。在JavaCV中,FFmpeg被用于处理视频流的编码和解码。

qq_38334677的博客 6030

Spring Boot 多媒体(音频/视频)文件处理FFmpegFrameGrabber 方法(例子:获取视频总时长)

以上是FFmpegFrameGrabber类提供的一些常用方法,通过这些方法可以实现对多媒体文件的读取、解析和处理。备注:业务逻辑需要根据自己的情况更改。

qq_53722480的博客 6260

【FFmpeg学习】Visual Studio 2019 使用 ffmpeg 详细方法

目录 1. 下载FFmpeg编译好的Windows版本 2.VS2019配置ffmpeg 3. Windows控制台使用ffmpeg命令 1. 下载FFmpeg编译好的Windows版本 地址如下: Download FFmpeg 点击如下: 选择 shared 2.VS2019配置ffmpeg 比如:你下载上述的编译好的 ffmpeg 版本路径为: C:\ffmpeg\ffmpeg-4.4.1-full_build-shared 1)右键项...

mike_jun的博客 1万+

StringBoot 通过FFmpegFrameGrabber获取视频首帧作为图片展示

FFmpegFrameGrabber获取视频首帧作为图片展示

qq_46100517的博客 7294

FFmpeg详解

前言:(适用读者:对音视频开发感兴趣的同行)本文力求简单明了介绍ffmpeg入门及背景知识、安装以及简单应用,过程虽然不复杂,但是小巧精致。文中还提供最新源码下载地址,希望对大家有所帮助。(原创作品,转发请注明出处)1、 什么是ffmpegFfmpeg(FastForward Mpeg)是一款遵循GPL的开源软件,在音视频处理方面表现十分优秀,几乎囊括了现存所有的视音频格式的编码,解码、转码、混合...

dosthing的博客 7600

【ffmpeg】ffmpeg命令工具的使用

本文主要阐述了: 1.ffmpeg特点 2.ffmpeg命令行工具的获取 3.ffmpeg.exe的使用 4.ffplay.exe的使用

MichaelKongChina的博客 1337

FFmpeg 详解

FFmpeg 详解

ProgramNovice的博客 2732

LabVIEW实战:基于DAQmx的实时正弦波生成、采集与波形图动态显示

本文详细介绍了如何使用LabVIEW和DAQmx驱动实现实时正弦波的生成、采集与动态显示。通过USB-6008数据采集卡,结合队列缓冲机制和动态波形图显示技术,构建了一个完整的信号处理系统。文章包含硬件连接、软件配置、任务设置及常见问题排查,适合LabVIEW初学者和硬件控制开发者参考。

weixin_30872337的博客 124

【FFMPEG】FFMPEG命令行,FFMPEG参数使用详解

a) 通用选项 -L license -h 帮助 -fromats 显示可用的格式,编解码的,协议的… -f fmt 强迫采用格式fmt -I filename 输入文件 -y 覆盖输出文件 -t duration 设置纪录时间 hh:mm:ss[.xxx]格式的记录时间也支持 -ss position 搜索到指定的时间 [-]hh:mm:ss[.xxx]的格式也支持 -title string 设置标题 -author string 设置作者 -copyright string 设置版权 -comment

欢迎关注【微信公众号】测试开发Guide,从功能测试进阶测试开发 4222

Codex接入CCSwitch:本地代理与模型路由配置指南

在AI编程工具链中,本地代理与模型路由是连接智能体与模型服务的核心桥梁。Codex作为OpenAI推出的编程智能体,虽然具备强大的仓库理解和自主编码能力,但其默认模型链路固定,导致在多模型切换、内网统一管理及成本控制上存在天然瓶颈。CCSwitch正是为解决这一痛点而生的本地代理工具,它通过OpenAI兼容协议将Codex的请求透明转发至DeepSeek、通义千问等第三方模型服务,使模型切换如同点击按钮般简单。本文从本地代理和模型路由器的基础原理切入,系统讲解Codex与CCSwitch的安装配置、模型ID

weixin_33910460的博客 427

Codex驱动AEDT完成无线充电仿真——从双线圈建模到三维电磁场动画

本文介绍了一个利用Codex、PyAEDT和Ansys Electronics Desktop 2025 R2实现双线圈无线充电系统自动建模与仿真的案例。通过简化模型(平面线圈+铁氧体磁芯),完成了从参数化建模、电磁场求解到后处理的全流程自动化,获得了耦合系数(k=0.17)、三维电磁场分布及多周期动态可视化效果。研究发现:线圈间距对传输效率影响最大(10-30mm间距时效率从40.2%降至5.57%),横向偏移15mm会使效率下降35%,而磁芯厚度增加带来的效率提升有限(3→7mm仅提高1.67%)。该框

sjjsjjsjjsjjsjj的博客 446

ffmpeg基础使用

参考ffmpeg常用命令ffmpeg参数中文详细解释[总结]FFMPEG视音频编解码零基础学习方法 一、安装 打开https://ffmpeg.zeranoe.com/builds/,该网站中的FFMPEG分为3个版本:Static,Shared,Dev。 前两个版本可以直接在命令行中使用,他们的区别在于:Static里面只有3个应用程序:ffmpeg.exe,ffplay.exe,ffprobe.exe,每个exe的体积都很大,相关的Dll已经被编译到exe里面去了。Shared里面除了3个应用程序

JineD的博客 1万+

基于STM32电压检测和电流检测

1.可测量直流电压0~36V,适用于低电压电子电路中。 2.可测量直流电0~5A范围内,目前采用的ACS712测量量程为5A,该模块有多个量程,可测量到20A 3.实时功率监测 4.电池电量监测(采用电压压降方式计算)

weixin_44453694的博客 6万+

FFMPEG详解

转自:http://3xin2yi.info/wwwroot/tech/doku.php/tech:multimedia:ffmpeg FFMPEG堪称自由软件中最完备的一套多媒体支持库,它几乎实现了所有当下常见的数据封装格式、多媒体传输协议以及音视频编解码器。因此,对于从事多媒体技术开发的工程师来说,深入研究FFMPEG成为一门必不可少的工作,可以这样说,FFMPEG之于多媒体开发工程师的

蜗牛的家 1万+

用Python+Charles搞定小程序付费短剧下载(附完整代码与避坑点)

本文详细介绍了如何利用Python和Charles抓包工具实现小程序付费短剧的自动化下载。通过分析小程序视频接口、破解请求参数,并编写Python脚本,读者可以轻松获取并保存短剧内容。文章还提供了完整的代码示例和常见问题的解决方案,特别适合对视频采集和抓包技术感兴趣的开发者。

weixin_28731231的博客 1188

uniapp - 获取设备麦克风权限+麦克风设备列表,用户可选择切换麦克风设备功能,选择麦克风采集设备后点击录制音频外部声音+可随时暂停/继续录音+记录音频录制时长(支持在线播放试听或下载MP3文件)

uniapp获取麦克风设备列表,uniapp录制声音,Uniapp获取麦克风权限,uniapp苹果ios安卓app获取麦克风设备列表,Uniapp H5获取浏览器麦克风并实现录音,Uniapp实现麦克风权限管理与音频录制全流程,uni-app实战案例:实现H5页面麦克风权限获取与录音功能,uni-app音频录制,uniapp麦克风授权窗口,uniapp获取iOS麦克风权限,实现前端录音并播放,把音频传给后端接口处理,获取麦克风并实现录音功能,前端获取/切换麦克风播放采集音频和采集音量大小,前端调用麦克风实现

🏆 前端领域优质创作者 2982

iOS下使用FFMPEG的一些总结

ffmpeg是一个多平台多媒体处理工具,处理视频和音频的功能非常强大。目前在网上搜到的iOS上使用FFMPEG的资料都比较陈旧,而FFMPEG更新迭代比较快; 且网上的讲解不够详细,对于初次接触FFMPEG的新手(例如我)来说确实不太好使用。为了防止忘记,这里对iOS下使用FFMPEG做一个总结。 1. FFMPEG层次结构的简单理解 要使用FFMPEG,首先需要理解F

lkeplei的专栏 2589

手把手教你学Simulink——基于Simulink的模糊自适应PI调节FOC电流环

本文提出基于模糊自适应PI控制的FOC电流环优化方案,针对传统PI控制参数固化、抗扰性差等问题,通过模糊逻辑在线调整PI参数。方案采用双输入(电流误差及变化率)和三输出(ΔKp/ΔKi/PI调节)结构,实现动态响应时间<30μs(提升38%)、超调<5%(降低71%)、参数摄动下误差<±0.4A(精度提升73%)。详细介绍了Simulink建模步骤,包括模糊规则设计(7语言变量、49条规则)、隶属度函数配置及自适应PI实现逻辑,并提供实机部署建议。仿真结果表明,该方法显著提升系统鲁棒性,特

MHD0815的博客 79

ffmpeg php 使用教程_php中的ffmpeg详解

本文主要和大家分享php中的ffmpeg详解,希望能帮助到大家。ffmpeg-php扩展php视频缩略图,较常用的是ffmpeg-php1: 安装 ffmpegffmpeg的下载链接 http://ffmpeg.org/download.html解压安装包tar -jxvf ffmpeg-x.x.tar.bz2进入目录cd ffmpeg-x.x编译安装./configure --enable-s...

weixin_39688870的博客 1593

AIGC算法工程师 面试八股文

1、简述DDPM的算法原理 2、什么是重参数化技巧?Diffusion Models和VAE中的重参数化技巧是如何使用的? VAE中的重参数化技巧 Diffusion Models中的重参数化技巧 3、什么是马尔可夫过程?DDPM中的马尔可夫链是如何定义的? 马尔可夫过程 DDPM马尔可夫链 4、为什么DDPM前向过程中前期加噪少,后期加噪多? 5、VAE和Diffusion Models中的变分推断是什么? 6、Negative Prompt实现的原理是什么?

沉迷单车的追风少年 1万+

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

【FFMPEG】gstreamer插件调用ffmpeg 详解

https://blog.youkuaiyun.com/datamining2005/article/details/77676849 Gstreamer调用FFMPEG解析 ----Gstreamer 是如何操作ffmpeg的,以及ffmpeg是如何demux的(AVI 容器格式为例) AVI容器格式较为简单,所以这里用AVI为例,分析gstreamer如何通过ffmpeg来对多媒体文件demux,获得原...

Linux Android Web 2656

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

ffmpeg的使用

3、自动生成其它目录 : 指定了 --prefix 选项 , 那么其它生成 bin 可执行文件目录 , lib 函数库目录 等类型的文件输出目录会在 --prefix 配置的目录基础上生成。2) 路径配置 : 使用 ./configure --prefix=PREFIX 命令 , 指定输出文件的根目录为 ./android/arme64-v8a;把报错及解决方法记录一下。3) 函数库目录 : 自动生成的函数库数据目录为 PREFIX/lib , 即 ./android/arme64-v8a/lib;

zhuowalun8427的博客 1298

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

FFmpeg使用手札

文章目录环境搭建1. 快速搭建(不考虑版本兼容)2. 安装ffmpeg-cuda加速3. ffmpeg-python环境搭建一些报错记录 & 原因 & 解决方法1. 报错:encoder 'aac' is experimental and might produce bad results2. resize时的参数值必须是偶数3. 增加参数指定处理音频流的方式4. -vf 参数中,iw,ih分别指输出视频的帧宽和帧高5. module 'ffmpeg' has no attribute 'p

翻山越岭的那一边 3540

FFMPEG使用参数详解

目前又开始测MPEG1和MPEG2的解码,在准备编码好的测试序列过程中,需要通过编码器来进行原始视频序列的编码操作,以生成我们需要的测试数据。由于IPP example提供的Encoder不支持MPEG1,经过查询,决定MPEG1的编码使用FFMPEG。FFMEPG是个啥子东西呢,这里简单说一下:FFmpeg是用于录制、转换和流化音频和视频的完整解决方案,一套领先的音/视频编解码类库。FF

AXDC_QA_Team的专栏 4万+

ffmpeg使用详解

1、Mac安装请点击这里 2、使用介绍: 显示ffmpeg使用的基本信息命令:ffmpeg -h 显示ffmpeg使用的高级信息命令:ffmpeg -h long 显示ffmpeg使用的所有信息命令:ffmpeg -h full 也可以打印到文件中查看详细的内容:ffmpeg -h long > ffmpeg_h_long.log 粗略查找: win用: ffmpeg -encoders | findstr x264 mac用: ffmpeg -encoders | grep x264 查找流中

jjw_zyfx的博客 9003

ffmpeg 命令行详解

ffmpeg命令行使用素材生成音视频文件(视频裁剪、编解码、水印、overlay、画中画、拉流、录制)

u011780419的专栏 3033
上一篇: JavaCV 例程学习笔记 (openCV java版,实际例程用scala编写)第一章
下一篇: JavaCV, JavaCPP,和JavaCPP Presets的关系
Code_LT
博客等级 码龄10年 307粉丝 182原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值