理解ffmpeg

news/2024/11/8 19:36:33/

ffmpeg是一个完整的、跨平台的音频和视频录制、转换和流媒体解决方案。

它的官网:https://ffmpeg.org/

这里有一份中文的文档:https://ffmpeg.p2hp.com/

ffmpeg提供了什么?

在centos上,可以通过yum进行安装:

yum install epel-releaserpm -Uvh https://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpmyum 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库提供的方法和功能:

  1. 内存管理:

  • 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库提供的方法和功能:

  1. 编解码器操作:

  • 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库提供的方法和功能:

  1. 格式上下文操作:

  • 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库提供的方法和功能:

  1. 设备操作:

  • 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库提供的方法和功能:

  1. 滤镜图处理:

  • 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库提供的方法和功能:

  1. 缩放和图像处理:

  • 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库提供的方法和功能:

  1. 上下文和重采样操作:

  • 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     : mp42minor_version   : 0compatible_brands: isomavc1mp42creation_time   : 2010-01-10T08:29:06.000000ZDuration: 00:09:56.47, start: 0.000000, bitrate: 2119 kb/sStream #-1:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default)Metadata:creation_time   : 2010-01-10T08:29:06.000000Zhandler_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.000000Zhandler_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 将错误码转换为可读的错误消息字符串


http://www.ppmy.cn/news/786731.html

相关文章

EtherCAT转TCP/IP网关ethercat最大通讯距离

天啊&#xff01;你们听说了吗&#xff1f;数据互联互通问题终于迎来了突破性进展&#xff01;作为生产管理系统的关键部分&#xff0c;数据互联互通一直是个大问题。然而&#xff0c;ETHERCAT和TCP/IP是两个不同的协议&#xff0c;它们之间的通讯一直是个大 问题。但是&#x…

OpenCV 入门教程:图像的基本操作和处理

OpenCV 入门教程&#xff1a;图像的基本操作和处理 导语一、图像的基本操作1.1 获取图像的大小1.2 访问图像的像素1.3 修改图像的像素值 二、图像的基本处理2.1 图像的灰度化2.2 图像的平滑处理2.3 图像的边缘检测 总结 导语 在计算机视觉和图像处理领域&#xff0c;对图像进行…

MacOS 查看服务器端口的命令

开发时会遇到服务器监听端口是否正常的情况&#xff0c;MacOS 系统下&#xff0c;快速查看服务器端口是否打开正常和Windows区别不小&#xff0c;使用这个命令可以满足需求。 终端中输入命令&#xff1a; nc -vz -w 2 IP 端口 ##访问不通 guoxiaoguangMacBook-Pro16 ~ % nc -vz…

变址寄存器(VZ)

前言&#xff1a; 规范&#xff1a;在修饰32位操作时不管变址的数有没有超过16位都应该使用32位变址的格式。 提示&#xff1a;变址操作超16位的可以是对十进制数或者十六进制数进行操作&#xff0c;其它超16位的可以自己具体分析查找。 变址寄存器的编号和定义&#xff1a; 变…

稳压二极管串联电阻计算

稳压二极管是稳压电路的一种方式&#xff0c;但是提供负载的动力与二极管自身的功率有关 例如ZMM 5V 功率1W 最小的反向稳压管的电流5mA 最大的反向稳压管电流 IzmaxP/U 1W/5v200mA 当稳压管流向最大电流200mA 则流过串联电阻的电流是200mA Rmin(Vin-Vz)/Izmax 当稳压…

mac 测试某个IP的某个端口的状态

nc -vz -w 2 IP PORT nc -vz -w 2 192.168.2.78 80

ping IP+端口

ping IP ping 192.168.1.1MacOS中ping IP端口 nc -vz -w 2 192.168.1.1 8080windows下 telnet 192.168.1.1 8080