前端实时AAC音频处理方案

您所在的位置:网站首页 acc音频转换mp3 前端实时AAC音频处理方案

前端实时AAC音频处理方案

2023-12-17 00:24| 来源: 网络整理| 查看: 265

前言

针对现如今移动端设备音频广泛的应用场景,我们在测试相应程序的过程中不可避免的需要对音频能力进行验证,为了能够在云真机测试平台中完成不同场景下的音频测试,就需要实时获取客户端设备中播放的音频,进而能够直接通过 Web 端平台进行测试。

根据应用场景,需要从移动端设备中读取音频数据,即获取到音频裸数据 PCM (Pulse Code Modulation) 数据,然后将 PCM 数据通过一系列方式,最终发送到 Web 端进行播放。

技术选型 编码技术

由于获取到的音频数据是裸数据(PCM数据),如果将其存储在本地磁盘中,音频文件的体积是可接受的,但是我们应用的场景是实时传输,直接传输 PCM 数据必然会有传输数据量过大的问题,因此需要使用压缩编码技术对裸数据进行压缩后传输。常见的编码技术有 AAC、MP3、WAV 和 WMA 等等。

通过参考 音频编码方案之间音质比较(AAC,MP3,WMA等) 文章可以看出,在码率较低等情况下,不同编码方案的音频的音质排序为:AAC+ > MP3PRO > AAC > RealAudio > WMA > MP3。

由于 AAC 是一种高压缩比的音频压缩算法,但它的压缩比要远超过较老的音频压缩算法,如 AC-3、MP3 等。并且其质量可以同未压缩的 CD 音质相媲美。因此最终选择 AAC 编码技术对 PCM 数据进行压缩。

前端解码方案

选择使用 jMuxer 作为解码器,是一个基于 MSE 技术的 JavaScript 开源库,允许 JavaScript 动态构建 和 的媒体流,支持对接收到的 AAC 数据进行解码,并且有着接近原生的解码速度。

AAC音频编码技术

AAC是高级音频编码(Advanced Audio Coding)的缩写,出现于1997年,最初是基于MPEG-2的音频编码技术。由Fraunhofer IIS、Dolby Laboratories、AT&T、Sony等公司共同开发,目的是取代MP3格式。2000年,MPEG-4标准出台,AAC重新集成了其它技术(PS,SBR),为区别于传统的MPEG-2 AAC,故含有SBR或PS特性的AAC又称为MPEG-4 AAC。

AAC 是新一代的音频有损压缩技术,音频文件格式有 ADIF 和 ADTS:

ADIF:Audio Data Interchange Format 音频数据交换格式。这种格式的特征是可以确定的找到这个音频数据的开始,不需进行在音频数据流中间开始的解码,即它的解码必须在明确定义的开始处进行。故这种格式常用在磁盘文件中。 ADTS:Audio Data Transport Stream。是 AAC 音频的传输流格式。这种格式的特征是它是一个有同步字的比特流,解码可以在这个流中任何位置开始。

总的来说,ADTS 可以在任意帧解码,也就是说它每一帧都有头信息。ADIF 只有一个统一的头,所以必须得到所有的数据后解码。

对原始帧加上 ADTS 头进行 ADTS 的封装,就形成了 ADTS 帧。 AAC音频文件的每一帧由 ADTS Header和 AAC Audio Data组成。结构体如下: 1

而本次方案中由于实时传输,将会采用 ADTS 格式的数据帧进行数据传输。一个数据包 ADTS Header 分为:

固定头(fixed header):数据每一帧都相同,可参考 AAC的ADTS头文件信息介绍; 可变头(variable header):在帧与帧之间可变;

有时候可能我们接收到的 AAC 数据包是不合法的,也就是 ADTS Header 不合法,可以将 Header 通过 P23工具 对数据进行验证。

JMuxer 解码

在通过 websocket 获取到 AAC 数据包时,其实拿到的是16进制的数据,在解码的过程中会转换成10进制数据,最后会转成二进制进行解析。

JMuxer 库 同时支持音视频解码。首先介绍以下 JMuxer 常用的参数和方法。

参数 属性属性值说明默认值nodeTag IDvideo/audio 标签 ID-modeaudio/video/both解码模式bothflushingTime时间(毫秒)缓存刷新频率1500maxDelay时间(毫秒)最大延时500clearBuffertrue/false清除Buffertruefps帧数视频帧数durationonReady函数MSE 就绪后回调-onError函数Buffer 异常回调-debugtrue/false是否打印日志false 方法 函数参数说明feeddata object对象参数包含 audio, video 和 duration,如果没有提供 duration,将根据 fps 计算。createStream-写入缓冲区,nodeJS可用reset-重置并重新开始 JMuxerdestroy-实例销毁 整体代码实现

整体 Demo 可参考:github.com/Lewage59/pr…

/** * 音频接受处理器 */ import JMuxer from 'jmuxer'; import Socket from './socket'; const DEFAULT_WS_URL = 'ws://localhost:8080'; export default class AudioProcessor { constructor(options) { const wsUrl = options.wsUrl || DEFAULT_WS_URL /** * node: 'player', * mode: 'audio', * debug: true, * flushingTime: 0, * wsUrl */ this.jmuxer = new JMuxer({ mode: 'audio', flushingTime: 0, onReady() { console.log('Jmuxer audio init onReady!'); }, onError(data) { console.error('Buffer error encountered', data); }, ...options }); this.audioDom = document.getElementById(options.node) this.initWebSocket(wsUrl) } initWebSocket(url) { const that = this this.ws = new Socket({ url, binaryType: 'arraybuffer', onmessage: function(event) { const data = that.parse(event.data); data && that.jmuxer.feed(data); } }); } /** * 音频解析 * @param {*} data AAC Buffer 视频流 * @returns */ parse(data) { let input = new Uint8Array(data) return { audio: input }; } onPlay() { this.audioDom.load() const playPromise = this.audioDom.play() if (playPromise !== undefined) { playPromise.then(() => { this.audioDom.play() }) } } onPause() { this.audioDom.pause() } onReload() { this.audioDom.load() } onDestroy() { this.ws.handleClose() this.audioDom.pause() this.jmuxer = null } }

而有时候前端需要模拟音视频服务进行调试的情况,首先可以可以通过 FFmpeg 将 MP3 音频转换为 AAC 音频格式,再将音频文件分割成数据帧通过 node 服务启动 websocket 进行传输数据帧,具体案例可参考 Node服务端AAC音频传输

写在最后

音视频相关技术在之前其实一直没有接触过,在这次的预研和项目落地的过程中,也对该技术有了新的认识,因此本文主要是对应用层面的讲解,没有深入探讨每个技术的细节,但我相信后续还会对该音视频技术持续关注。

如果对UI自动化测试、远程控制等感兴趣的小伙伴可以关注一下 Sonic 云真机测试平台。

Sonic,一站式开源分布式集群云真机测试平台,致力服务于中小企业的客户端UI测试(永久免费)

参考资料 音频编码方案之间音质比较(AAC,MP3,WMA等) 音视频学习 (七) 掌握音频基础知识并使用 AudioTrack、OpenSL ES 渲染 PCM 数据 AAC 文件解析及解码流程 AAC ADTS格式分析 AAC的ADTS头文件信息介绍


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3