音视频开发9 FFmpeg 解复用框架--如何将一个影音文件(mp4文件/wav文件) 最终播放起来

本文主要是介绍音视频开发9 FFmpeg 解复用框架--如何将一个影音文件(mp4文件/wav文件) 最终播放起来,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一,播放器框架

二 常用音视频术语

容器/文件(Conainer/File): 即特定格式的多媒体文件, 比如mp4、flv、mkv等。
媒体流(Stream): 表示时间轴上的一段连续数据,如一 段 声音数据 、一段 视频数据 或一段 字幕数据 ,可以是压缩 的,也可以是非压缩的,压缩的数据需要关联特定的编解 码器(有些码流音频他是纯PCM)。一般对于 一个 mp4文件, 通过解复用器,就可以将mp4中的 视频流和 音频流,甚至字符流都分离出来。 
数据帧/数据包(Frame/Packet): 通常,一个媒体流是 由大量的数据帧组成的,对于压缩数据, 帧对应着编解码 器的最小处理单元 ,分属于不同媒体流的数据帧交错存储 于容器之中。
一般来说,压缩后的数据,我们认为是packet
解码后的数据,我们认为是frame的概念。
帧对应着编解码 器的最小处理单元 这句话的理解如下:
对于视频,一个frame实际上就是一张图片了
对于音频,一个frame,对于 aac 是1024个采样点为一帧,mp3 则是1152个采样点为一帧。
编解码器: 编解码器是以帧为单位实现压缩数据和原始数 据之间的相互转换的。

三 常用概念-复用器

四 常用概念-编解码器

五 FFmpeg库简介

FFMPEG有8个常用库:
AVUtil :核心工具库,下面的许多其他模块都会依赖该库做一些基本的音 视频处理操作。
AVFormat :文件格式和协议库,该模块是最重要的模块之一,封装了 Protocol层和Demuxer、Muxer层,使得协议和格式对于开发者来说是透 明的。
AVCodec :编解码库,封装了Codec层,但是有一些Codec是具备自己的 License的,FFmpeg是不会默认添加像 libx264、FDK-AAC 等库的,但是 FFmpeg就像一个平台一样,可以将其他的第三方的Codec以插件的方式 添加进来,然后为开发者提供统一的接口。
AVFilter :音视频滤镜库,该模块提供了包括音频特效和视频特效的处理, 在使用FFmpeg的API进行编解码的过程中,直接使用该模块为音视频数 据做特效处理是非常方便同时也非常高效的一种方式。
AVDevice :输入输出设备库,比如,需要编译出播放声音或者视 频的工具ffplay,就需要确保该模块是打开的,同时也需要SDL的 预先编译,因为该设备模块播放声音与播放视频使用的都SDL库。
SwrRessample :该模块可用于 音频重采样 ,可以对数字音频进行 声道数、数据格式、采样率 等多种基本信息的转换。
SWScale :该模块是将图像进行格式转换的模块,比如,可以将 YUV的数据转换为RGB的数据,缩放尺寸由1280*720变为800*480。
PostProc :该模块可用于进行后期处理,当我们使用AVFilter的时 候需要打开该模块的开关,因为Filter中会使用到该模块的一些基 础函数。

六 FFmpeg函数简介

av_register_all():注册所有组件,4.0已经弃用

avdevice_register_all()对设备进行注册,比如V4L2等。

        
#include <libavdevice/avdevice.h>/*** Initialize libavdevice and register all the input and output devices.*/
void avdevice_register_all(void);

avformat_network_init();初始化网络库以及网络加密协议相关 的库(比如openssl)

#include <libavformat/avformat.h>int avformat_network_init(void);

七 FFmpeg函数简介-封装格式相关

avformat_alloc_context();负责申请一个AVFormatContext 结构的内存,并进行简单初始化

#include <libavformat/avformat.h>/*** Allocate an AVFormatContext.* avformat_free_context() can be used to free the context and everything* allocated by the framework within it.*/
AVFormatContext *avformat_alloc_context(void);## AVFormatContext:它是FFMPEG解封装(flv,mp4,rmvb,avi)功能的结构体, 	

其中比较重要的几个如下解释:

typedef struct AVFormatContext {const AVClass *av_class;   // 一个类,用于保存指向父对象的链接,用于日志记录struct AVInputFormat *iformat;  // 用于指定输入文件的格式以及文件读取的操作函数struct AVOutputFormat *oformat; // 用于指定输出文件的格式以及文件写入的操作函数void *priv_data;            // 指向 AVFormatContext(容器上下文)的私有数据AVIOContext *pb;            // 用于读取和写入媒体数据的 I/O 上下文int nb_streams;             // 流的数量,包括音频、视频、字幕等AVStream **streams;         // 指向 AVStream 结构体的指针,用于存储所有流的信息char *filename;             // 用于存储文件名的字符串int64_t start_time, duration;// 媒体文件的起始时间戳和持续时间int64_t bit_rate;           // 比特率,以 bit/s 计算uint8_t *buffer;            // 用于暂存数据的缓冲区int buffer_size;            // 缓冲区的大小
} AVFormatContext;AVFormatContext 结构体的各个成员变量的作用详见以下介绍。成员变量介绍AVClass *av_class: 一个类,用于保存指向父对象的链接,用于日志记录;
AVClass是FFmpeg中libavutil库中的一个结构体,用于在FFmpeg中实现类及其对象的日志和调试功能。AVClass提供了一种标准的方式来管理类及其对象,在不同的库和插件之间提供了统一的日志记录和调试接口。AVInputFormat *iformat:用于指定输入文件的格式以及文件读取的操作函数;
AVOutputFormat *oformat: 用于指定输出文件的格式以及文件写入的操作函数;void *priv_data: 指向 AVFormatContext(容器上下文)的私有数据;
priv_data成员可以用于存储和传递特定协议下使用的私有数据,常见的使用场景是实现自定义输入或输出协议。AVIOContext *pb:用于读取和写入媒体数据的 I/O 上下文;
AVIOContext 是libavformat库中一个表示访问媒体文件的I/O环境的结构体。它封装了对媒体文件的读取和写入操作,提供了和具体I/O操作系统相关的操作的抽象接口,实现了独立于实际操作系统的媒体文件访问接口。int nb_streams: 流的数量,包括音频、视频、字幕等;
AVStream **streams:指向 AVStream 结构体的指针,用于存储所有流的信息;
AVStream是FFmpeg中libavformat库中的一个数据结构,用于表示媒体文件中的一个音频或视频流。在FFmpeg中,一个媒体文件通常包含多个音视频流,每个流对应着媒体文件中的一个轨道。AVStream通过存储音视频流的各种属性信息,方便解码和编码,对于多媒体处理和视频编辑有着至关重要的作用。
AVStream包含了一个媒体流的所有基本信息,如类型、编解码器、时间戳、时长、帧率、码率等等。常用的成员变量有:
char *filename: 用于存储文件名的字符串;int64_t start_time: 媒体文件的起始时间戳;
int64_t duration: 媒体文件的持续时间;
int64_t bit_rate: 比特率,以 bit/s 计算;
uint8_t *buffer: 用于暂存数据的缓冲区;
int buffer_size: 缓冲区的大小。

avformat_free_context();释放该结构里的所有东西以及该 结构本身

#include <libavformat/avformat.h>/*** Free an AVFormatContext and all its streams.* @param s context to free*/
void avformat_free_context(AVFormatContext *s);

avformat_open_input();打开输入视频文件

在avformat_alloc_context()方法中,我们申请了一个avformatcontext,这个context中现在只有框架,没有实际的内容。
/*** Open an input stream and read the header. The codecs are not opened.* The stream must be closed with avformat_close_input().** @param ps       Pointer to user-supplied AVFormatContext (allocated by*                 avformat_alloc_context). May be a pointer to NULL, in*                 which case an AVFormatContext is allocated by this*                 function and written into ps.*                 Note that a user-supplied AVFormatContext will be freed*                 on failure.* @param url      URL of the stream to open.* @param fmt      If non-NULL, this parameter forces a specific input format.*                 Otherwise the format is autodetected.* @param options  A dictionary filled with AVFormatContext and demuxer-private*                 options.*                 On return this parameter will be destroyed and replaced with*                 a dict containing options that were not found. May be NULL.** @return 0 on success, a negative AVERROR on failure.** @note If you want to use custom IO, preallocate the format context and set its pb field.*/
int avformat_open_input(AVFormatContext **ps, const char *url,const AVInputFormat *fmt, AVDictionary **options);

avformat_close_input(); 关闭解复用器。关闭后就不再需要 使用avformat_free_context 进行释放。
avformat_find_stream_info() :获取 音视频 文件信息
av_read_frame(); 读取 音视频 ,这里更加合理的命令应该是av_read_packet();因为这里读取的并不是yuv或者pcm的frame数据,而是打包了的h264或者aac数据,是一包数据,但是由于ffmpeg历史原因,这里一直是av_read_frame();
avformat_seek_file(); 定位文件
av_seek_frame(): 定位文件

八 FFmpeg解码函数简介-解码器相关

avcodec_alloc_context3(): 分配解码器上下文
avcodec_find_decoder(): 根据ID查找解码器
avcodec_find_decoder_by_name(): 根据解码器名字
avcodec_open2(): 打开 码器
avcodec_decode_video2(): 解码一帧视频数据
avcodec_decode_audio4(): 解码一帧音频数据
avcodec_send_packet(): 发送编码数据包
avcodec_receive_frame(): 接收解码后数据
avcodec_free_context(): 释放解码器上下文,包含了 avcodec_close()
avcodec_close(): 关闭解码器

这篇关于音视频开发9 FFmpeg 解复用框架--如何将一个影音文件(mp4文件/wav文件) 最终播放起来的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1006721

相关文章

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

通过C#和RTSPClient实现简易音视频解码功能

《通过C#和RTSPClient实现简易音视频解码功能》在多媒体应用中,实时传输协议(RTSP)用于流媒体服务,特别是音视频监控系统,通过C#和RTSPClient库,可以轻松实现简易的音视... 目录前言正文关键特性解决方案实现步骤示例代码总结最后前言在多媒体应用中,实时传输协议(RTSP)用于流媒体服

MyBatis框架实现一个简单的数据查询操作

《MyBatis框架实现一个简单的数据查询操作》本文介绍了MyBatis框架下进行数据查询操作的详细步骤,括创建实体类、编写SQL标签、配置Mapper、开启驼峰命名映射以及执行SQL语句等,感兴趣的... 基于在前面几章我们已经学习了对MyBATis进行环境配置,并利用SqlSessionFactory核

C#图表开发之Chart详解

《C#图表开发之Chart详解》C#中的Chart控件用于开发图表功能,具有Series和ChartArea两个重要属性,Series属性是SeriesCollection类型,包含多个Series对... 目录OverviChina编程ewSeries类总结OverviewC#中,开发图表功能的控件是Char

鸿蒙开发搭建flutter适配的开发环境

《鸿蒙开发搭建flutter适配的开发环境》文章详细介绍了在Windows系统上如何创建和运行鸿蒙Flutter项目,包括使用flutterdoctor检测环境、创建项目、编译HAP包以及在真机上运... 目录环境搭建创建运行项目打包项目总结环境搭建1.安装 DevEco Studio NEXT IDE

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类

流媒体平台/视频监控/安防视频汇聚EasyCVR播放暂停后视频画面黑屏是什么原因?

视频智能分析/视频监控/安防监控综合管理系统EasyCVR视频汇聚融合平台,是TSINGSEE青犀视频垂直深耕音视频流媒体技术、AI智能技术领域的杰出成果。该平台以其强大的视频处理、汇聚与融合能力,在构建全栈视频监控系统中展现出了独特的优势。视频监控管理系统EasyCVR平台内置了强大的视频解码、转码、压缩等技术,能够处理多种视频流格式,并以多种格式(RTMP、RTSP、HTTP-FLV、WebS

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD