网站首页 > 博客文章 正文
主题
音频是流式数据,并不像视频一样有P帧和B帧的概念。就像砌墙一样,咔咔往上摞就行了。一般来说,AAC编码中生成文件这一步,如果使用的是OutputStream流写入文件的话,就完全不需要计算时间。但在音视频同步或者使用Android自带的MediaMuxer来生成音频文件时,就需要计算音频帧的时间戳。
参考
本文所涉及到的计算方法和API,为在Android环境下。使用AudioRecord音频录制,MediaCodeC编码AAC格式音频,同时使用MediaMuxer封装AAC格式音频文件。
方法
AAC编码有两种计算时间戳的方式。第一种:使用PCM的数据量来计算;第二种:计算出AAC编码相应参数配置下,一帧的持续时间,再配合帧数来计算。
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这个参数就包含了这一帧数据的偏移、以及时间戳等信息。
【音视频学习资料,点击下方链接免费报名,报名后会自动弹出学习资料免费领取地址~】
【免费】FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发-学习视频教程-腾讯课堂
使用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
使用AAC帧时间计算
当编码器每输出一次数据,即可视作输出一帧AAC数据。一帧AAC原始数据包括1024个sample,那么AAC音频文件1s内的帧数为:sampleRate / 1024 帧。从而得到一帧AAC的持续时间为:
perFrameTime (微妙) = 1000000L / sampleRate / 1024
如果你对音视频开发感兴趣,觉得文章对您有帮助,别忘了点赞、收藏哦!或者对本文的一些阐述有自己的看法,有任何问题,欢迎在下方评论区与我讨论!
猜你喜欢
- 2024-12-02 PHP时间戳的秘密--关于PHP时间戳函数各种使用方法
- 2024-12-02 MySQL 中时间函数详解,及加减计算总结和使用!
- 2024-12-02 SQLServer时间戳的误解,与时间没有关系
- 2024-12-02 一种整车域控制器片内及片外时间同步方法
- 2024-12-02 时间戳服务怎么收费?可信时间戳一年多少钱?
- 2024-12-02 PTP时间同步的具体原理
- 2024-12-02 特斯拉UWB数字钥匙,是怎么一步步被黑的
- 2024-12-02 项目多时区处理
- 2024-12-02 java的时间戳的长度为什么是固定的?它是如何做到的
- 2024-12-02 「技术分享」利用卫星校准系统时间
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)