解决AAC音频编码时间戳的计算问题

news/2024/4/27 9:21:05/文章来源:https://blog.csdn.net/yinshipin007/article/details/129249820

1.主题


音频是流式数据,并不像视频一样有P帧和B帧的概念。就像砌墙一样,咔咔往上摞就行了。一般来说,AAC编码中生成文件这一步,如果使用的是OutputStream流写入文件的话,就完全不需要计算时间。但在音视频同步或者使用Android自带的MediaMuxer来生成音频文件时,就需要计算音频帧的时间戳。

2.参考


本文所涉及到的计算方法和API,为在Android环境下。使用AudioRecord音频录制,MediaCodeC编码AAC格式音频,同时使用MediaMuxer封装AAC格式音频文件。

3.方法


AAC编码有两种计算时间戳的方式。第一种:使用PCM的数据量来计算;第二种:计算出AAC编码相应参数配置下,一帧的持续时间,再配合帧数来计算。

4.AAC编码、MediaMuxer生成文件伪代码

MediaCodeC的AAC编码流程不再赘述,这里用伪代码来代替。主要是为了体现在代码何处设置时间戳:

// MediaCodeC获得可用输入队列

index = codeC.dequeueInputBuffer(......)

// 当获取到可用输出队列时,我们将获取的PCM数据填入

inputBuffer = codec.getInputBuffer(index)

// 将PCM数据(ByteArray)填充到InputBuffer

inputBuffer.put(byteAarray——PCM数据)

codec.queueInputBuffer(index, 0, byteArray的size

, presentationTimeUs, 0)

在以上的伪代码中,presentationTimeUs就是需要我们设置时间戳的地方

填充PCM数据后,在得到MediaCodeC输出后,使用MedaMuxer写入数据,生成AAC文件。

path = 输出路径。后缀aac、或者mp4

mediaMuxer= MediaMuxer(path, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)

mediaMuxer.addTrack(音频轨)

mediaMuxer.start()

// codec拿到可用的输出数据。这些数据就是AAC格式的音频数据

id = codec.dequeueOutputBuffer(bufferInfo, 10000)

if(id >= 0){

outputBuffer = codec.getOutputBuffer(id)

mediaMuxer.writeSamplet(audioTrack, outputBuffer, bufferInfo)

}

需要注意的是:使用MediaMuxer生成AAC音频文件时,不需要添加AAC头信息,直接写入即可。MediaMuxer写入文件时,BufferInfo这个参数就包含了这一帧数据的偏移、以及时间戳等信息。

5.使用PCM的数据量来计算


PCM是没有经过压缩的纯音频数据,我之前写过一篇音频入门的文章初识音频,记录了一些PCM相关的常识问题,感兴趣的可以去看看。PCM作为最原始的音频数据,可以根据大小来计算出时间,先给出公式:

presentationTimeUs = 1000000L * (totalBytes / 2) / sampleRate

这是配置为采样率sampletRate、采样位数为16bit、单声道的PCM文件时间戳计算方式

接下来我们来分析以上公式的计算由来:假设有一段PCM文件,采样率为S,采样位数为n--(一般 采样位数的选择有4bit、8bit、16bit、32bit),声道为单声道。那么在1s内,这段PCM的大小为:

size = S * n * 1,单位为bit

众所周知,1 Byte = 8bit, 1 Short = 16bit。那么单位时间内,PCM的大小为:

以byte为单位 = S * n * 1 / 8

以short为单位 = S * n * 1 / 16

那么根据以上就可得到,配置参数为采样率sampleRate、16bit、声道为1的PCM文件,当传入编码器的总大小达到totalByte时,时间戳的计算方式:

currents (微妙) = totalByte / (sampleRate * 16 * 1 / 8)

= totalByte / 2 / sampleRate * 1000000L

当然如果选择以ShortArray来承载PCM数据的话,那么公式则变为:

currents (微妙) = totalShort / (sampleRate * 16 * 1 / 16)

= totalShort / sampletRate * 1000000L

6.使用AAC帧时间计算

当编码器每输出一次数据,即可视作输出一帧AAC数据。一帧AAC原始数据包括1024个sample,那么AAC音频文件1s内的帧数为:sampleRate / 1024 帧。从而得到一帧AAC的持续时间为:

perFrameTime (微妙) = 1000000L / sampleRate / 1024

原文地址:解决AAC音频编码时间戳的计算问题 - 资料 - 音视频开发中文网 - 构建全国最权威的音视频技术交流分享论坛

★文末名片可以免费领取音视频开发学习资料,内容包括(FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)以及音视频学习路线图等等。

见下方!↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_75057.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

debian 部署nginx https

我是flask 处理请求单进程, 差点意思 , 考虑先flask 在往下走 一:安装nginx 因为我是debian 系统,所以我的建议是直接 sudo apt-get install nginx 你也可以选择在官网下载, 但是我搭建ssl 的时候安装openssl非常的麻…

【无标题】(2019)NOC编程猫创新编程复赛小学组真题含参考

(2019)NOC编程猫创新编程复赛小学组最后6道大题。前10道是选择填空题 略。 这道题是绘图题,没什么难度,大家绘制这2个正十边形要注意:一是不要超出舞台;二是这2个正十边形不要相交。 这里就不给出具体程序了…

数睿通2.0数据服务功能模块发布

文章目录引言API 目录API 权限API 日志结语引言 数睿通 2.0 之前基本完成了数据集成和数据开发两大模块,也因此得到了一些朋友的帮助和支持,在此由衷的表示感谢,你们的支持便是我们更新的最大动力! 目前,数据服务模块…

色环电阻的阻值如何识别

这种是色环电阻,其外表有一圈圈不同颜色的色环,现在在一些电器和电源电路中还有使用。下面的两种色环电阻它颜色还不一样,一个蓝色,一个土黄色,其实这个蓝色的属于金属膜色环电阻,外表涂的是一层金属膜&…

狂神说:面向对象(三)——多态

多态// 对象能执行什么方法,主要看对象左边的类型,和右边的没有关系多态:同一方法可以根据发送对象的不同而采用不同的行为方式父类:public class Person {public void run(){System.out.println("Person > run");}}…

【并发编程学习篇】深入理解CountDownLatch

一、CountDownLatch介绍 CountDownLatch(闭锁)是一个同步协助类,允许一个或多个线程等待,直到其他线程完成操作集。CountDownLatch使用给定的计数值(count)初始化。await方法会阻塞直到当前的计数值被coun…

只需四步,手把手教你打造专属数字人

伴随ChatGPT的问世,在技术与商业运作上都日渐发展成熟的数字人产业正持续升温。去年9月,北京市发布了国内首个数字人产业专项支持政策,提出将依托国家文化专网将数字人纳入文化数据服务平台。以数字人、ChatGPT为代表的互联网3.0创新应用产业…

kali下安装Volatility

一、About Volatility Volatility是一款开源内存取证框架,能够对导出的内存镜像进行分析,通过获取内核数据结构,使用插件获取内存的详细情况以及系统的运行状态。 Volatility是一款非常强大的内存取证工具,它是由来自全世界的数百位知名安全…

FAST‘23《λ-IO: A Unified IO Stack for Computational Storage》论文解读

FAST’23《λ-IO: A Unified IO Stack for Computational Storage》论文解读 Data:2023-2-27 Ref: Z. Yang et al., “λ-IO: A Unified IO Stack for Computational Storage,” in 21st USENIX Conference on File and Storage Technologies (FAST 23), Santa Clara, CA, Feb.…

数据可视化第二版-03部分-06章-比较与排序

文章目录数据可视化第二版-03部分-06章-比较与排序总结可视化视角-比较与排序代码实现创建虚拟环境1. python版本管理2.切换到指定版本后安装虚拟环境切换路径到文件当前路径柱形图环形柱状图子弹图哑铃图雷达图词云图教材截图数据可视化第二版-03部分-06章-比较与排序 总结 …

Java 多线程 --- 多线程的相关概念

Java 多线程 --- 多线程的相关概念Race Condition 问题并发编程的性质 --- 原子性, 可见性, 有序性上下文切换 (Context Switch)线程的一些故障 --- 死锁, 活锁, 饥饿死锁 (Deadlock)活锁(Livelock)死锁和活锁的区别饥饿(Starvation)背景: 操作系统 — 线程/进程 同步 Race Co…

【unity学习记录】Canvas Group组件

💗 未来的游戏开发程序媛,现在的努力学习菜鸡 💦本专栏是我关于游戏开发的学习笔记 🈶本篇是unity的Canvas Group组件 Canvas Group画布组介绍详解1. Alpha2. Interactable3. Blocks Raycasts4. Ignore Parent Groups介绍 画布组…

6.0.4:GrapeCity Documents for Excel GcExcel Crack

在更短的时间内生成 Excel 电子表格,不依赖于 Excel! 在任何应用程序中转换、计算、格式化和解析电子表格。 快速高效:其轻巧的尺寸意味着 Documents for Excel 针对快速处理大型 Excel 文档进行了优化 使用适用于 Windows、Linux 和 Mac 的…

JVM 学习(2)—简单理解强、软、弱、虚 Java 四大引用

一、Java 引用概述 Java 中出现四种引用是为了更加灵活地管理对象的生命周期,以便在不同场景下灵活地处理对象的回收问题。不同类型的引用在垃圾回收时的处理方式不同,可以用来实现不同的垃圾回收策略。Java 目前将其分成四类,类图如下&…

mysql一两种索引方式hash和btree

1. Hash索引: Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索…

信息安全概论之《密码编码学与网络安全----原理与实践(第八版)》

前言:在信息安全概论课程的学习中,参考了《密码编码学与网络安全----原理与实践(第八版)》一书。以下内容为以课件为主要参考,课本内容与网络资源为辅助参考,学习该课程后作出的总结。 一、信息安全概述 1…

力扣Top100题之两数相加(Java解法)

0 题目描述 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数…

MVCC 当前读 快照读 RC read view RR下事务更新不会丢失

MVCC(multi-version-concurrent-control) MVCC是行锁的一个变种,但MVCC在很多情况下它避免了加锁。不是buffer块,而是buffer中的记录行。 MVCC (Multi-Version Concurrency Control) (注:与MVCC相对的,是基于锁的并发控制&#x…

【无限思维画布】制作思维导图第五步,节点创建与连接,拖拽对齐与双击缩放

正在为无限词典制作单词思维导图功能,实现无限单词导图,无限思维画布。目前制作到第五步,实现节点创建、节点连接、节点拖拽对齐: 节点创建与连接,拖拽对齐Details 第四步,推倒重来。 一开始受vue-mindma…

【Python小程序】这款成语接龙小程序,让小孩儿轻松记住500个成语,在家里常玩,语文直上135,仅此一份,快收藏~(太强大了)

前言 学习路上,那我同行。 哈喽~大家晚上好呀,我是你们的栗子同学。 所有文章完整的素材源码都在👇👇 粉丝白嫖源码福利,请移步至CSDN社区或文末公众hao即可免费。 成语接龙是一个传统的文字游戏。很多孩子都喜欢玩。…