AAC中的ADTS格式分析
😎 作者介绍:欢迎来到我的主页👈,我是程序员行者孙,一个热爱分享技术的制能工人。计算机本硕,人工制能研究生。公众号:AI Sun(领取大厂面经等资料),欢迎加我的微信交流:sssun902
🎈 本文专栏:本文收录于《FFMPEG》系列专栏,相信一份耕耘一份收获,我会分享FFMPEG相关学习内容,不说废话,祝大家都offer拿到手软
🤓 欢迎大家关注其他专栏,我将分享Web前后端开发、人工智能、机器学习、深度学习从0到1系列文章。
🖥随时欢迎您跟我沟通,一起交流,一起成长、进步!
AAC中的ADTS格式分析
AAC(Advanced Audio Coding)是一种高效的音频编码技术,广泛应用于数字音频的传输和存储。它是由MPEG-4标准定义的有损音频压缩格式,提供了比传统MP3格式更高的音质和更低的比特率。AAC的两种主要文件格式是ADIF(Audio Data Interchange Format)和ADTS(Audio Data Transport Stream)。在本文中,我们将重点分析ADTS格式。
AAC与ADTS简介
AAC提供了多种采样率、声道数和比特率的支持,以适应不同的应用场景。ADTS作为AAC的一种容器格式,允许音频流通过网络传输,具有同步字的比特流特性,可以在流中任何位置开始解码,这使得ADTS非常适合用于实时音频传输。
ADTS格式结构
ADTS文件由多个部分组成,最关键的是头部信息。一个ADTS帧通常由以下几部分组成:
- 同步字(Syncword):固定为0xFFF,用于识别ADTS帧的开始。
- ID和Layer:标识使用的MPEG版本和层级。
- Protection Absent:指示是否启用CRC错误校验。
- Profile:编码所使用的AAC规范类型,如AAC-LC。
- Sampling Frequency Index:采样率的索引。
- Channel Configuration:音频通道数的配置。
- Frame Length:ADTS帧的总长度,包括头部和音频数据。
ADTS头部信息详解
ADTS头部信息是解析ADTS帧的关键,它包括固定头信息和可变头信息两部分:
固定头信息(Fixed Header)
-
Syncword:固定为0xFFF,表示ADTS帧的开始。
-
ID:0表示MPEG-4,1表示MPEG-2。
-
Layer:对于AAC,始终为’00’。
-
Protection Absent:如果设置为1,则表示没有CRC校验;如果设置为0,则表示有CRC校验。
-
Profile:指示AAC的编码配置,如Low Complexity(LC)。
-
Sampling Frequency Index:采样率索引,用于查找具体的采样率。
-
Private Bit:通常为0,无实际作用。
-
Channel Configuration:指示音频的通道配置,如立体声或单声道。
可变头信息(Variable Header)
- Frame Length:ADTS帧的总长度,包括头部和音频数据的长度。
- Buffer Fullness:码率控制信息,0x7FF表示码率可变。
- Number of Raw Data Blocks in Frame:表示ADTS帧中AAC原始数据块的数量。
ADTS与AAC的关系
ADTS为AAC提供了一种有效的传输机制,通过在每个音频帧前添加ADTS头部信息,使得AAC数据可以方便地在网络上传输,并且可以在任何位置开始解码,这对于流媒体服务来说非常重要。
应用场景
ADTS格式广泛应用于在线音乐、视频流、网络广播等领域。由于其高效的编码和灵活的传输特性,ADTS格式的AAC音频文件在移动设备和网络环境中非常受欢迎。
应用场景分析
ADTS格式的灵活性和高效性使其成为多种应用场景的理想选择。以下是一些具体的应用实例:
-
在线音乐服务:流媒体音乐服务如Spotify、Apple Music等,使用ADTS格式提供高质量的音频流,确保用户即使在网络条件不佳的情况下也能享受到流畅的音乐体验。
-
视频流媒体平台:YouTube、Netflix等视频平台在传输视频内容时,通常会包含ADTS编码的音频流,以保证音频质量与视频同步传输。
-
网络广播:网络广播电台利用ADTS格式进行实时音频广播,允许听众在任何时间加入并从当前点开始收听,而无需缓冲整个文件。
-
移动设备:智能手机和平板电脑等移动设备在播放音乐或视频时,ADTS格式的音频文件可以快速加载并减少内存占用。
-
实时通信:VoIP(Voice over Internet Protocol)和其他实时通信应用,如Skype或Zoom,使用ADTS格式来传输清晰的语音数据。
-
车载娱乐系统:现代汽车的娱乐系统经常集成了网络音频流功能,ADTS格式确保了音频内容的高效传输和播放。
示例代码(python大致思路)
以下是一个简单的示例代码,展示如何在一个假设的音频播放器中处理ADTS格式的AAC文件。这段代码是用Python编写的,使用了pydub
库来处理音频数据。
from pydub import AudioSegment# 假设我们有一个ADTS格式的AAC音频文件
adts_file_path = "example.aac"# 使用pydub加载ADTS AAC文件
adts_audio = AudioSegment.from_file(adts_file_path, format="aac")# 播放音频
adts_audio.export("output.mp3", format="mp3")# 获取音频元数据,例如帧长度、采样率、声道数等
frame_length = adts_audio.frame_length # 假设属性,实际使用时需根据库的API获取
sample_rate = adts_audio.frame_rate
channels = adts_audio.channelsprint(f"Frame Length: {frame_length}")
print(f"Sample Rate: {sample_rate}")
print(f"Channels: {channels}")# 可以根据需要对音频进行进一步的处理,如转换格式、剪辑等
在实际应用中,处理AAC音频需要更复杂的逻辑,包括解析ADTS头部信息、处理音频帧等。
CPP
在C++中处理AAC ADTS格式的音频通常需要使用专门的音频处理库,例如FDK-AAC
(Fraunhofer开发者的AAC编码器和库)或libavcodec
(FFmpeg的一部分)。使用libavcodec
解码ADTS AAC音频流的基本示例。
#include <iostream>
#include <vector>
#include <libavcodec/avcodec.h>
extern "C" {
#include <libavformat/avformat.h>
}class ADTSDecoder {
public:ADTSDecoder() {// 初始化FFmpeg库av_register_all();avcodec_register_all();}~ADTSDecoder() {if (codec_context) {avcodec_close(codec_context);av_free(codec_context);}if (format_context) {avformat_close_input(&format_context);}}bool openFile(const std::string& file_path) {// 打开文件if (avformat_open_input(&format_context, file_path.c_str(), nullptr, nullptr) < 0) {std::cerr << "无法打开文件" << std::endl;return false;}// 检索流信息if (avformat_find_stream_info(format_context, nullptr) < 0) {std::cerr << "无法找到流信息" << std::endl;return false;}// 寻找AAC流for (unsigned i = 0; i < format_context->nb_streams; i++) {if (format_context->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&format_context->streams[i]->codecpar->codec_id == AV_CODEC_ID_AAC) {stream_index = i;break;}}if (stream_index == -1) {std::cerr << "找不到AAC流" << std::endl;return false;}// 打开解码器codec_context = format_context->streams[stream_index]->codec;if (avcodec_open2(codec_context, avcodec_find_decoder(codec_context->codec_id), nullptr) < 0) {std::cerr << "无法打开解码器" << std::endl;return false;}return true;}bool decodeAudio() {AVPacket packet;AVFrame *frame = av_frame_alloc();if (!frame) {std::cerr << "无法分配帧" << std::endl;return false;}while (av_read_frame(format_context, &packet) >= 0) {if (packet.stream_index == stream_index) {// 解码音频帧int got_frame = 0;int ret = avcodec_decode_audio4(codec_context, frame, &got_frame, &packet);if (ret < 0) {std::cerr << "解码错误" << std::endl;av_frame_free(&frame);return false;}if (got_frame) {// 处理解码后的音频帧// 示例:仅打印出帧的采样率和声道数std::cout << "采样率: " << frame->sample_rate << "Hz, 声道数: " << frame->channels << std::endl;}}av_packet_unref(&packet);}av_frame_free(&frame);return true;}private:AVFormatContext *format_context = nullptr;AVCodecContext *codec_context = nullptr;int stream_index = -1;
};int main(int argc, char* argv[]) {if (argc < 2) {std::cerr << "使用方法: " << argv[0] << " <adts文件路径>" << std::endl;return 1;}ADTSDecoder decoder;if (!decoder.openFile(argv[1])) {return 1;}if (!decoder.decodeAudio()) {return 1;}return 0;
}
在编译这个程序之前,系统上需要安装FFmpeg库,并且在编译时链接了相应的库。
g++ -o adts_decoder adts_decoder.cpp -lavcodec -lavformat -lavutil -lswresample -lswscale
这个示例程序首先打开一个ADTS AAC文件,然后读取并解码音频帧,打印出每个帧的采样率和声道数。
祝大家学习顺利~
如有任何错误,恳请批评指正~~
以上是我通过各种方式得出的经验和方法,欢迎大家评论区留言讨论呀,如果文章对你们产生了帮助,也欢迎点赞收藏,我会继续努力分享更多干货~
🎈关注我的公众号AI Sun可以获取Chatgpt最新发展报告以及腾讯字节等众多大厂面经。
😎也欢迎大家和我交流,相互学习,提升技术,风里雨里,我在等你~
相关文章:

AAC中的ADTS格式分析
😎 作者介绍:欢迎来到我的主页👈,我是程序员行者孙,一个热爱分享技术的制能工人。计算机本硕,人工制能研究生。公众号:AI Sun(领取大厂面经等资料),欢迎加我的…...

iOS内存管理---MRC vs ARC
系列文章目录 iOS基础—Block iOS基础—Protocol iOS基础—KVC vs KVO iOS网络—AFNetworking iOS网络—NSURLSession iOS内存管理—MRC vs ARC iOS基础—Category vs Extension iOS基础—多线程:GCD、NSThread、NSOperation iOS基础—常用三方库:Mason…...

【数学分析笔记】第1章第1节:集合(2)
这节我自己补了一些内容,要不然听不太懂陈纪修老师讲的 1. 集合与映射 1.3 子集与真子集 假如有 S \textbf{S} S和 T \textbf{T} T两个集合,其中, S \textbf{S} S的所有元素都属于 T \textbf{T} T,则称 S \textbf{S} S是 T \te…...

大话设计模式:七大设计原则
目录 一、单一职责原则(Single Responsibility Principle, SRP) 二、开放封闭原则(Open-Closed Principle, OCP) 三、依赖倒置原则(Dependency Inversion Principle, DIP) 四、里氏替换原则&am…...

利用多商家AI智能名片小程序提升消费者参与度与个性化体验:重塑零售行业的忠诚策略
摘要:在数字化浪潮席卷全球的今天,零售行业正经历着前所未有的变革。消费者对于购物体验的需求日益多样化、个性化,而零售商则面临着如何将一次性购物者转化为品牌忠诚者的巨大挑战。多商家AI智能名片小程序作为一种新兴的数字营销工具&#…...
Scala 闭包
Scala 闭包 Scala 闭包是一个非常重要的概念,它允许我们创建可以在稍后某个时间点执行的功能片段。闭包是一个函数,它捕获了封闭范围内的变量,即使在函数外部,这些变量也可以在函数内部使用。这使得闭包成为处理异步操作、回调和…...
前端JS总结(中)
目录 前言 正文 对象: 分类: 自定义对象: 内置对象: 重点: 常用内置对象: 字符串对象:String 获取字符串长度: 大小写转换: 获取某个字符: 截取字…...

elasticsearch的match_phrase匹配及其可能导致的查询问题
目录 1.match_phrase使用介绍 2.规避可能产生的查询问题 解决方式 一.查询和索引分词器一致,即都使用max_word或者都使用smart 二.使用slop增加匹配的容忍度 3.参考文档 1.match_phrase使用介绍 elasticsearch的match_phrase查询是全文查询,主要用…...

C++快速理解之继承
一、继承和派生 1.是什么? C 中的继承是类与类之间的关系,与现实世界中的继承类似 例如:儿子继承父亲的财产 继承(Inheritance)可以理解为一个类从另一个类获取成员变量和成员函数的过程 例如: 类B继承…...

Node.JS - 基础(Express)
目录 A. 简介 B. 下载,安装 C. 启动服务,查看文件结构 A. 简介 Express 是一个基于 Node.js 平台的极简、灵活的 Web 应用开发框架,它提供了一系列强大的功能来构建 Web 应用程序和 API。 一、Express 的基本特点 简洁的路由系统: Express 的路由系…...

I/O复用
I/O复用使得程序能够同时监听多个文件描述符,这对提高程序的性能至关重要。 举个例子: 就好比你天天玩手机,你妈为了监控你,在你房间安装了一个监控,这个监控可以实时监控你的一举一动,并上传到你妈手机上…...

【验证可用】解决安装SQL Server数据库时,报错“启用 windows 功能 NetFx3 时出错,错误代码:-2146498298......“的问题
目录 背景一. 报错信息1.1 报错的图片信息1.2 报错的文字信息 二. 解决报错2.1 下载 NetFx3.cab 文件2.2 执行命令 三. SQL Server 修复安装 背景 一次在阿里云服务器安装 SQL Server 2012时,系统报错了,导致安装进行不下去…通过在网上查找了多种解决方…...

STM32的SDIO接口详解
目录 1. 定义与兼容性 2. SDIO时钟 3. SDIO命令与响应 4. SDIO块数据传输 5. SDIO控制器的硬件结构 6.代码实现 1.SD初始化 2.测试SD卡的读取 3.测试SD卡的写入 STM32的SDIO(Secure Digital Input/Output,安全数字输入输出)接口是一…...

docker容器常用指令,dockerfile
docker:容器,主要是解决环境迁移的问题,将环境放入docker中,打包成镜像。 docker的基本组成:镜像(image),容器(container),仓库(repository)。镜像相当于类,容器相当于类的实例对象…...

C语言学习笔记 Day11(指针--下)
Day11 内容梳理: 目录 Chapter 7 指针 7.6 指针 & 函数 (1)形参改变实参的值 (2)字符数组作为函数参数 1)合并字符串 2)删掉字符串中空格 (3)指针作为函数返…...

(24)(24.2) Minim OSD快速安装指南(二)
文章目录 前言 6 MinimOSD-extra NG 7 替代硬件 前言 本文简要介绍了如何连接电路板。有关更多详细说明,请参阅 MinimOSD 项目维基(MinimOSD Project wiki)。 6 MinimOSD-extra NG 该项目位于此处(here);文档位于此处(here);支撑线位于此…...

GD32 MCU碰到IIC总线卡死怎么办?
大家在使用MCU IIC通信时,若碰到设备复位或者总线干扰等情况,可能会导致IIC总线卡死,表现上总线上SDA或者SCL其中一根线为低电平,IIC总线一直处于busy状态。此时若代码上一直等待总线空闲,则可能导致软件死机ÿ…...

算法——动态规划:0/1 背包问题
文章目录 一、问题描述二、解决方案1. DP 状态的设计2. 状态转移方程3. 算法复杂度4. 举例5. 实现6. 滚动数组6.1 两行实现6.2 单行实现6.3 优缺点 三、总结 一、问题描述 问题的抽象:给定 n n n 种物品和一个背包,第 i i i 个物品的体积为 c i c_i …...

又是奇瑞,“统一下班时间”过去不久,最近又整新活了...
奇瑞 345 345 可不是奇瑞的汽车型号,而是奇瑞 7 月份会议文章中提出的新策略。 简单来说,要提高加班效率,实现 3 个人干 5 个人活,拿 4 个人的工资,要把员工当成家人一样看待,要对他们的健康幸福负责。 前面…...

ubuntu24.04lts cmake编译 opencv4.5.4 contrib的一些问题
编译之前一定要安装好必须的库,否则即使提示编译成功,调用opencv后也可能会有问题 sudo apt-get update sudo apt-get upgradesudo apt-get install -y g sudo apt-get install -y cmake sudo apt-get install -y make sudo apt-get install…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...

HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...