理解ffmpeg
ffmpeg是一个完整的、跨平台的音频和视频录制、转换和流媒体解决方案。
它的官网:https://ffmpeg.org/
这里有一份中文的文档:https://ffmpeg.p2hp.com/
ffmpeg提供了什么?
在centos上,可以通过yum进行安装:
yum install epel-release
rpm -Uvh https://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm
yum install ffmpeg ffmpeg-devel
按照上述命令安装完ffmpeg-devel后,会在 /usr/lib64/ 路径找到对应的库
- libavcodec.so
- libavutil.so
- ...
ffmpeg安装完以后会有三个工具:
- ffmpeg 用于在格式之间转换多媒体文件的命令行工具
- ffplay 基于SDL和FFmpeg库的简单媒体播放器
- ffprobe 一个简单的多媒体流分析器
ffmpeg还提供一系列的库,能提供开发者进行编码开发。
- libavutil 是一个包含用于简化变成的函数的库,包括随机数生成器、数据结构、数学例程、核心多媒体实用程序等等。
- libavcodec 是一个包含音频/视频编解码器的解码器和编码器的库。
- libavformat 是一个包含用于多媒体容器格式的复用器和复用器的库
- libavdevice 是一个包含输入和输出设备的库,用于从许多常见的多媒体输入/输出软件框架中抓取和渲染,包括Video4Linux, Video4Linux2, VfW和ALSA。
- libavfilter 是一个包含媒体过滤器的库。
- libswscacle 是一个执行高度优化的图像播放和色彩空间/像素格式转换操作的库。
- libswresample 是一个执行高度优化的音频重采样、重矩阵化和样本格式转换操作的库。
源码
ffmpeg是开源的,源码可以直接
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
FFmpeg主要是使用C语言编写的,由于FFmpeg需要对音频和视频进行底层处理,包括解码、编码、封装、解封装等操作,因此选择C语言是非常合适的,因为它可以提供对底层操作系统和硬件的直接访问。
libavutil
FFmpeg的Libavutil库提供了许多方法和功能,用于在多媒体处理中进行通用的实用工具和基本功能。以下是一些常见的Libavutil库提供的方法和功能:
- 内存管理:
av_malloc()
和av_mallocz()
:动态分配内存。av_free()
:释放先前分配的内存。av_memcpy_backptr()
:从后向前拷贝内存。av_fast_malloc()
:快速分配内存。
- 字符串操作:
av_strstart()
和av_stristart()
:检查字符串的前缀。av_stristr()
:在字符串中查找子字符串,忽略大小写。av_get_token()
:从输入字符串中提取标记。av_strcasecmp()
和av_strncasecmp()
:比较字符串,忽略大小写。
- 时间和时钟:
av_gettime()
:获取当前时间戳。av_gettime_relative()
:获取相对时间戳。av_usleep()
:微秒级延迟。
- 数学和整数操作:
av_clipl_int32()
和av_clipf()
:对整数和浮点数进行范围限制。av_log2()
:计算以2为底的对数。av_gcd()
:计算最大公约数。av_rescale_q()
:按比例转换数值。
- 字节操作:
av_be2ne16()
和av_be2ne32()
:将大端字节序转换为本地字节序。av_memcpy_backptr()
:从后向前拷贝字节。
- 字节流处理:
avio_*
系列函数:用于读写字节流,如打开、关闭、读取和写入文件。
这只是一小部分Libavutil库提供的方法和功能列表。Libavutil还提供了许多其他有用的函数,用于处理时间戳、计算时间间隔、处理字节流、颜色空间转换等等。
更多方法见:http://ffmpeg.org/doxygen/trunk/group__lavu.html#details
libavcodec
FFmpeg的libavcodec库是用于音频和视频编解码的核心库。它提供了丰富的方法和功能,用于处理不同编解码器的音视频数据。以下是一些常见的libavcodec库提供的方法和功能:
- 编解码器操作:
avcodec_find_encoder()
和avcodec_find_decoder()
:查找编码器和解码器。avcodec_open2()
和avcodec_close()
:打开和关闭编码器和解码器。avcodec_parameters_to_context()
:将编码器参数转换为编码器上下文。
- 编码器和解码器参数设置:
avcodec_parameters_alloc()
和avcodec_parameters_free()
:分配和释放编码器参数对象。avcodec_parameters_copy()
:复制编码器参数。avcodec_parameters_from_context()
:从编码器上下文中获取编码器参数。
- 编码和解码:
avcodec_send_packet()
:发送数据包给编码器或解码器。avcodec_receive_frame()
:接收解码器输出的帧。avcodec_encode_video2()
和avcodec_encode_audio2()
:编码视频和音频数据。avcodec_decode_video2()
和avcodec_decode_audio4()
:解码视频和音频数据。
- 视频和音频帧操作:
av_frame_alloc()
和av_frame_free()
:分配和释放帧对象。av_frame_get_best_effort_timestamp()
:获取最佳时间戳。av_frame_copy()
和av_frame_copy_props()
:复制帧数据和属性。
- 编解码器参数查询:
av_codec_get_name()
:获取编解码器名称。av_codec_get_tag2()
:获取编解码器的四字节标签。
- 错误处理和信息获取:
av_strerror()
:获取错误消息字符串。avcodec_error_to_string()
:将错误代码转换为字符串。avcodec_get_name()
:获取编解码器的名称。avcodec_get_type()
:获取编解码器的类型。
这只是一小部分libavcodec库提供的方法和功能列表。libavcodec库还提供了更多用于处理音视频编解码的功能,如设置编码参数、处理编码器的选项、帧格式转换等。
更多方法见:http://ffmpeg.org/doxygen/trunk/group__libavc.html
libavformat
FFmpeg的libavformat库提供了用于音视频封装和解封装的方法和功能。它支持多种音视频容器格式,如AVI、MP4、MKV等。以下是一些常见的libavformat库提供的方法和功能:
- 格式上下文操作:
avformat_open_input()
和avformat_close_input()
:打开和关闭媒体文件。avformat_find_stream_info()
:获取媒体文件的流信息。avformat_alloc_context()
和avformat_free_context()
:分配和释放格式上下文。
- 流操作:
av_find_best_stream()
:查找最佳的音视频流。av_read_frame()
:读取音视频帧。av_seek_frame()
:在媒体文件中进行帧级别的跳转。av_write_frame()
:写入音视频帧。
- 封装格式操作:
avformat_write_header()
和avformat_write_trailer()
:写入封装格式的头部和尾部。avio_open()
和avio_close()
:打开和关闭封装格式的IO上下文。
- 流信息获取:
avformat_new_stream()
:创建新的音视频流。av_stream_get_end_pts()
:获取流的结束时间戳。av_stream_get_r_frame_rate()
:获取流的帧率。
- 格式参数设置和获取:
avformat_alloc_output_context2()
:分配输出格式上下文。avformat_alloc_output_context2()
:获取输入格式上下文的参数。
- 时间基和时间戳处理:
av_rescale_q()
:按比例转换时间戳。av_guess_frame_rate()
:猜测帧率。
- 错误处理和信息获取:
av_strerror()
:获取错误消息字符串。avformat_version()
:获取libavformat库的版本号。av_dump_format()
:输出媒体文件的格式信息。
这只是一小部分libavformat库提供的方法和功能列表。libavformat库还提供了更多用于音视频封装和解封装的功能,如元数据操作、时间码处理、流选择、封装格式的选项设置等。
更多方法见:http://ffmpeg.org/doxygen/trunk/group__libavf.html
libavdevice
FFmpeg的libavdevice库提供了与音视频设备交互的方法和功能。它允许您进行音频和视频的采集和播放,并提供了与设备的交互接口。以下是一些常见的libavdevice库提供的方法和功能:
- 设备操作:
avdevice_register_all()
:注册所有可用的设备。avdevice_list_devices()
:列出可用的音视频设备。avdevice_get_input_list()
:获取输入设备列表。avdevice_get_output_list()
:获取输出设备列表。avdevice_open()
和avdevice_close()
:打开和关闭设备。
- 设备参数设置:
avdevice_capabilities_create()
和avdevice_capabilities_free()
:创建和释放设备参数对象。avdevice_list_input_sources()
和avdevice_list_output_sinks()
:列出输入源和输出接口。avdevice_list_formats()
:列出设备支持的音视频格式。
- 设备采集和播放:
avdevice_read_packet()
:从设备读取音视频包。avdevice_write_packet()
:向设备写入音视频包。
- 错误处理和信息获取:
av_strerror()
:获取错误消息字符串。avdevice_version()
:获取libavdevice库的版本号。
更多方法见:http://ffmpeg.org/doxygen/trunk/group__lavd.html
libavfilter
FFmpeg的libavfilter库提供了音视频滤镜处理的方法和功能。它允许您对音视频数据进行各种滤镜和效果的处理,如裁剪、缩放、旋转、色彩调整等。以下是一些常见的libavfilter库提供的方法和功能:
- 滤镜图处理:
avfilter_register_all()
:注册所有可用的滤镜。avfilter_graph_alloc()
和avfilter_graph_free()
:创建和释放滤镜图。avfilter_graph_parse2()
:解析滤镜图的字符串描述。
- 滤镜操作:
avfilter_get_by_name()
:通过名称获取滤镜。avfilter_graph_create_filter()
:创建滤镜实例。avfilter_init_str()
:初始化滤镜参数。
- 输入输出处理:
av_buffersrc_add_frame()
:向输入缓冲区添加帧数据。av_buffersink_get_frame()
:从输出缓冲区获取帧数据。
- 滤镜参数设置和查询:
avfilter_inout_alloc()
和avfilter_inout_free()
:创建和释放输入输出结构。avfilter_graph_config()
:配置滤镜图。
- 错误处理和信息获取:
av_strerror()
:获取错误消息字符串。avfilter_version()
:获取libavfilter库的版本号。
libswscale
FFmpeg的libswscale库提供了图像缩放和颜色空间转换的方法和功能。它用于对视频帧进行大小调整、像素格式转换和色彩空间转换等操作。以下是一些常见的libswscale库提供的方法和功能:
- 缩放和图像处理:
sws_getContext()
和sws_freeContext()
:创建和释放图像缩放上下文。sws_scale()
:缩放和转换图像。sws_setColorspaceDetails()
:设置颜色空间细节。
- 图像参数获取和设置:
sws_getCachedContext()
和sws_getContext()
:获取和设置图像缩放上下文的缓存。
- 颜色空间转换:
sws_convertPalette8ToPacked32()
:将8位调色板转换为32位色彩。sws_setColorspaceDetails()
:设置颜色空间细节。
- 错误处理和信息获取:
sws_strerror()
:获取错误消息字符串。swscale_version()
:获取libswscale库的版本号。
libswresample
FFmpeg的libswresample库提供了音频重采样和格式转换的方法和功能。它用于对音频数据进行采样率、通道布局和样本格式的转换。以下是一些常见的libswresample库提供的方法和功能:
- 上下文和重采样操作:
swr_alloc()
和swr_free()
:创建和释放音频重采样上下文。swr_init()
:初始化音频重采样上下文。swr_convert()
:进行音频重采样。
- 参数设置和查询:
swr_config_frame()
:设置输入/输出音频帧的参数。swr_set_compensation()
:设置音频重采样补偿。
- 输入/输出音频帧处理:
swr_alloc_set_opts()
:设置输入/输出音频帧的参数并创建音频重采样上下文。swr_convert_frame()
:进行音频重采样并输出音频帧。
- 延迟处理:
swr_get_delay()
:获取重采样的延迟。swr_inject_silence()
:注入静音样本。
- 错误处理和信息获取:
swresample_strerror()
:获取错误消息字符串。swresample_version()
:获取libswresample库的版本号。
如何读取一个mp4?
我现在有一个mp4文件,要读取这个文件应该怎么操作呢?
我是按照签名说的yum的方式安装ffmpeg-devel,它的
动态库地址为:/user/lib64/
header头文件地址为:/usr/include/ffmpeg/libavcodec/
在程序中直接引用就行
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
以下是一段读取互联网mp4的代码。
#include <iostream>
extern "C"
{
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
}
int main() {
std::cout << "start read url mp4" << std::endl;
// 做注册处理
av_register_all();
avformat_network_init();
AVFormatContext *inputContext = NULL;
// 打开一个url的信息
std::string url = "https://demo.com/BigBuckBunny.mp4";
int ret = avformat_open_input(&inputContext, url.c_str(), NULL, NULL);
if ( ret != 0) {
// 打开文件失败,处理错误
// 可以通过调用 av_strerror() 函数将错误码转换为可读的错误消息
char errorStr[AV_ERROR_MAX_STRING_SIZE];
av_strerror(ret, errorStr, sizeof(errorStr));
printf("Failed to open input file: %s\n", errorStr);
return ret;
}
ret = avformat_find_stream_info(inputContext, NULL);
if (ret < 0) {
char errorStr[AV_ERROR_MAX_STRING_SIZE];
av_strerror(ret, errorStr, sizeof(errorStr));
printf("Failed to avformat_find_stream_info file: %s\n", errorStr);
return ret;
}
// 输出AVFormatContent信息
av_dump_format(inputContext, -1, url.c_str(), 0);
for (int i = 0; i < inputContext->nb_streams; i++) {
AVStream *stream = inputContext->streams[i];
if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
// 处理音频流
}
else if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
// 处理视频流
}
int64_t duration = stream->duration;
std::cout << duration << std::endl;
}
avformat_close_input(&inputContext);
std::cout << "ok" << std::endl;
return 0;
}
输出:
start read url mp4
Input #-1, mov,mp4,m4a,3gp,3g2,mj2, from 'https://demo.com/BigBuckBunny.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: isomavc1mp42
creation_time : 2010-01-10T08:29:06.000000Z
Duration: 00:09:56.47, start: 0.000000, bitrate: 2119 kb/s
Stream #-1:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default)
Metadata:
creation_time : 2010-01-10T08:29:06.000000Z
handler_name : (C) 2007 Google Inc. v08.13.2007.
Stream #-1:1(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1991 kb/s, 24 fps, 24 tbr, 24k tbn, 48 tbc (default)
Metadata:
creation_time : 2010-01-10T08:29:06.000000Z
handler_name : (C) 2007 Google Inc. v08.13.2007.
26304512
14315000
ok
这里的关键的函数调用逻辑如下:
- av_register_all 初始化ffmpeg库
- avformat_network_init 初始化ffmpeg的网络访问,如果我们的输入文件是url,则需要初始化
- avformat_open_input 打开音视频文件,这个时候并没有读取到这个音视频文件的信息
- AVFormatContext 这个是非常重要的结构,表示音视频格式的上下文,一些重要字段
AVInputFormat
:指向输入格式的指针,包含解封装函数等信息。AVStream
:指向音视频流的数组,每个流都有对应的索引。nb_streams
:音视频流的数量。duration
:音视频文件的总时长。bit_rate
:音视频文件的比特率。metadata
:元数据,包含了文件的附加信息,如标题、作者、描述等。
- avformat_find_stream_info 获取音视频文件的流信息
- av_dump_format 打印AVFormatContext的信息
- av_strerror 将错误码转换为可读的错误消息字符串
理解ffmpeg的更多相关文章
- 理解ffmpeg中的pts,dts,time_base
首先介绍下概念: PTS:Presentation Time Stamp.PTS主要用于度量解码后的视频帧什么时候被显示出来 DTS:Decode Time Stamp.DTS主要是标识读入内存中的b ...
- Android IOS WebRTC 音视频开发总结(四九)-- ffmpeg介绍
本文主要介绍ffmpeg,文章来自博客园RTC.Blacker,支持原创,转载必须说明出处,个人微信公众号blacker,更多详见www.rtc.help 说明: ps1:如果直接从webrtc开始学 ...
- FFmpeg深入分析之零-基础 <第一篇>
FFmpeg是相当强大的多媒体编解码框架,在深入分析其源代码之前必须要有基本的多媒体基础知识,否则其源代码会非常晦涩难懂.本文将从介绍一些基本的多媒体只是,主要是为研读ffmpeg源代码做准备,比如一 ...
- iOS: FFmpeg编译和使用 学习
ffmpeg是一个多平台多媒体处理工具,处理视频和音频的功能非常强大.目前在网上搜到的iOS上使用FFMPEG的资料都比较陈旧,而FFMPEG更新迭代比较快: 且网上的讲解不够详细,对于初次接触FFM ...
- iOS开发-FFmpeg深入分析
FFmpeg是相当强大的多媒体编解码框架,在深入分析其源代码之前必须要有基本的多媒体基础知识,否则其源代码会非常晦涩难懂.本文将从介绍一些基本的多媒体只是,主要是为研读ffmpeg源代码做准备,比如一 ...
- FFmpeg深入分析(一)
最近在做一个关于监控的项目,要在iphone 客户端实现播放监控的实时视频以及录像视频.使用到了FFmpeg,看到这篇文章,写的非常不错.转自:http://blog.chinaunix.net/ui ...
- FFmpeg中的时间基(time_base), AV_TIME_BASE
AV_TIME_BASE 经常在FFmpeg的代码中看到一个奇怪的单位 AV_TIME_BASE ,比如 AVFormatContext 结构体中就有这样一个字段: duration ,它在FFmpe ...
- FFmpeg Basics学习笔记(1)ffmpeg基础
1 FFmpeg的由来 FFmpeg缩写中,FF指的是Fast Forward,mpeg是 Moving Pictures Experts Group的缩写.官网:ffmpeg.org 编译好的可执行 ...
- FFmpeg深入分析之零-基础
FFmpeg是相当强大的多媒体编解码框架,在深入分析其源代码之前必须要有基本的多媒 体基础知识,否则其源代码会非常晦涩难懂.本文将从介绍一些基本的多媒体只是,主要是为研读ffmpeg源代码做准备,比如 ...
- ffmpeg初体验
ffmpeg是一个多平台多媒体处理工具,处理视频和音频的功能非常强大.目前在网上搜到的iOS上使用FFMPEG的资料都比较陈旧,而FFMPEG更新迭代比较快: 且网上的讲解不够详细,对于初次接触FFM ...
随机推荐
- 4.测试类mapper报错
1.总结:前几天还有今天一直在弄测试类报错的原因,想着项目是一个大整体,写一个mappe测试类,测试一个mapper,这样后面不会出错: 但是在测试mapper的时候一直,出现mapper值为空的异常 ...
- 【Diary】CSP-S2 2021 游记 & NOIP 备赛发疯日记
Day 0 两个极端的回跳. .....不行啊. 我快输不起了........... ------------------------------- 早上被生物钟强行唤醒,逼自己懒床到6:40. 弹琴 ...
- Java设计模式 —— 单例模式
6 单例模式 6.1 单例模式概述 Singleton Patter:确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例. 单例模式有3个要点: 该类只能有一个实例 该类必须自行创建这个实 ...
- The first week match's mistake-2
旋转排列 (https://www.luogu.com.cn/problem/B3688) 解读一下题目: 要求从给定的数组拿出最后一个数字后 看看变化后的数组的最后一个数字是否是要求的数字 想到用栈 ...
- Docker应用部署(Nginx、Tomcat)
Docker hub官方链接: https://hub.docker.com 部署Nginx 官方已经给出了方法: https://hub.docker.com/_/nginx 运行容器 $ dock ...
- “露天煤矿现场调研和交流案例分享”在CSDN发表,两次审核未通过,判定:全篇涉及广告
我在博客园发布了:露天煤矿现场调研和交流案例分享.后台分享到了CSDN,结果判定为:全篇涉及广告.我要是真能写出来全篇涉及广告的文章,也算我能力比较强,就算是让ChatGPT可能也写不出来吧. 这种坐 ...
- P1350 车的放置 题解
一.题目描述: 给你一个网格棋盘,a,b,c,d 表示了对应边长度,也就是对应格子数. 例如,当 a=b=c=d=2 时,对应了下面这样一个棋盘: 想要在这个棋盘上放 k 棋子,也就是这 k 个棋子没 ...
- 17-js代码压缩
const { resolve } = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); modul ...
- Email发送邮件使用ical4j将时间同步日历中
1.Maven依赖 <!--邮件--> <dependency> <groupId>org.springframework.boot</groupId> ...
- 2022-12-11:行程和用户。以下为输出结果,请问sql语句如何写? +------------+-------------------+ | Day | Cancellation
2022-12-11:行程和用户.以下为输出结果,请问sql语句如何写? ±-----------±------------------+ | Day | Cancellation Rate | ±- ...