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…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
