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…...

大数据面试SQL(三):每分钟在线直播人数
文章目录 每分钟在线直播人数 一、题目 二、分析 三、SQL实战 四、样例数据参考 每分钟在线直播人数 一、题目 有如下数据记录直播平台主播上播及下播时间,根据该数据计算出平台每分钟的在线直播人数。 这里用主播名称做统计,前提是主播名称唯一…...

python中执行mysql操作并将python脚本共享
mysql下载路径: MySQL :: MySQL Community Downloads [root2 ~]# vim py001.py a3 b4 print(ab) print(a**2b**2) [root2 ~]# python py001.py 7 25 [root2 ~]# python3 >>> import random >>> random <module rando…...

HTTP、HTTPS、SOCKS5三种协议特点
在互联网通信中,HTTP、HTTPS和SOCKS5是三种至关重要的协议,它们各自具有独特的特点和应用场景。本文将详细探讨这三种协议的特点,帮助读者更好地理解它们在网络通信中的作用。 一、HTTP协议特点 HTTP(Hypertext Transfer Protoc…...

在ubuntu、centos、openEuler安装Docker
目录 ubuntu、centos、openEuler安装Docker 1.在 Ubuntu 上安装 Docker 1. 1 更新软件包 1. 2 安装必要的依赖 1.3 添加 Docker 的 GPG 密钥 1.4 添加 Docker 仓库 1.5 更新软件包 1.6 安装 Docker 1.7 启动并启用 Docker 服务 1.8 验证安装 1.9 运行测试容器 1.10…...

公共命名空间的例子3
有这样一个句子 用x语言解释[12*3]。 在x语言中,不符合“先乘除后加减”,这个句子应该怎样解释呢? 第一步,进行词法分析,目的是识别出注释和字符串,其中可能包括任意符号,干扰编译过程。 第二步…...

【云存储】SDS软件定义存储,数据存储的类型与技术方案(块/文件/对象,Ceph、RBD等)
【云存储】SDS软件定义存储,数据存储的类型与技术方案(块/文件/对象,Ceph、RBD等) 文章目录 1、分布式存储架构(软件定义存储SDS,超融合基础架构HCI)2、存储类型(块存储,…...

第31课 Scratch入门篇:小画家(舞台上画画)
小画家(舞台上画画) 故事背景: 在舞台上选择画笔和颜色,进行画画 程序原理: 这节课我们继续练习画笔功能,通过画笔功能我们设计一个小画板,碰到哪种颜色画笔就切换成哪种颜色。 开始编程 1、绘制一大一小的黑色圆形,小的命名为画笔,大的圆形命名为black(黑色) 2、鼠…...

QT UI界面之ListView
文章目录 概述源码怎么用代码qt design 小结 概述 本来把布局文件那块写了一遍,但是看看都跟之前那篇差不多,就换了一个稍微有点难度的,也很常用的listview来写了。来看看,有什么好玩的。 源码 先看下源码,如下&…...

freeRTOS互斥量(mutex)
目录 前言 一、互斥量概述 二、互斥量函数 1.创建 2.其他函数 三、优先级反转示例 1.概念 2.代码示例 四、优先级继承 1.概念 2.代码示例 五、递归锁 1.死锁的概念 2.自我死锁 3.函数 4.递归锁代码示例 前言 在之前的信号量中,我们想要实现互斥的…...

基于GeoTools使用JavaFx进行矢量数据可视化实战
目录 前言 一、JavaFx展示原理说明 二、GeoTools的Maven依赖问题 三、引入Geotools相关的资源包 四、创建JavaFx的Canvas实例 五、JavaFx的Scene和Node的绑定 六、总结 前言 众所周知,JavaFx是Java继Swing之后的又一款用于桌面应用的开发利器。当然࿰…...