前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Audio Unit播放aac/m4a/mp3等文件

Audio Unit播放aac/m4a/mp3等文件

作者头像
落影
发布2018-04-27 18:12:01
2.9K0
发布2018-04-27 18:12:01
举报
文章被收录于专栏:落影的专栏落影的专栏

前言

相关文章:

使用VideoToolbox硬编码H.264

使用VideoToolbox硬解码H.264

使用AudioToolbox编码AAC

使用AudioToolbox播放AAC

HLS点播实现(H.264和AAC码流)

HLS推流的实现(iOS和OS X系统)

iOS在线音频流播放

Audio Unit播放PCM文件

Audio Unit录音(播放伴奏+耳返)

前面两篇介绍了Audio Unit播放PCM文件边录边播,这次引入AudioConvert实现aac/m4a/mp3格式的播放。

正文

1、格式转换

音频数据的格式转换包括采样率改变,单声道到多声道的转变、音调的升高降低等,audio unit有一个专门格式转换unit(kAudioUnitType_FormatConverter,type of 'aufc')。

AudioUnit不支持vbr的数据,也不支持从一个有损压缩格式转换为pcm或者pcm转换为有损格式,对于有损格式的音频数据转换,需要用CoreAudio的Audio Converter API。

2、AudioFile API 和 Converter

AudioFile API提供了API对音频文件的创建、打开、修改和保存;

Audio Converters 用于音频文件的编解码,还可以用于sample rate的改变、int到float的转变,最常见是将音频文件转成pcm播放;

下面Converter的两个格式:

代码语言:javascript
复制
Source Format
Sample Rate:              44100
Format ID:                 .mp3
Format Flags:                 0
Bytes per Packet:             0
Frames per Packet:         1152
Bytes per Frame:              0
Channels per Frame:           2
Bits per Channel:             0

Target Format
Sample Rate:              44100
Format ID:                 lpcm
Format Flags:                 4
Bytes per Packet:             2
Frames per Packet:            1
Bytes per Frame:              2
Channels per Frame:           1
Bits per Channel:            16
3、具体细节

1、初始化AudioFile,通过AudioFileOpenURL打开音频文件,并读取对应的音频格式(AudioStreamBasicDescription);这里和Audio Unit播放PCM文件不同的是,还需要读取kAudioFilePropertyMaximumPacketSizekAudioFilePropertyAudioDataPacketCount两个属性,分别是单个package的最大size和packet的数量,并通过缓存的大小和package的size创建AudioStreamPacketDescription的数组;

2、初始化AudioUnit,设置AVAudioSession的Category为AVAudioSessionCategoryPlayback;初始化AudioBufferList,设置AudioUnit的playback回调;

3、在AudioUnit的playback回调中,调用AudioConvert的AudioConverterFillComplexBuffer函数并设置好回调方法lyInInputDataProc;在回调的lyInInputDataProc中,通过AudioFileReadPacketData读取音频数据并把读取的AudioStreamPacketDescription回传;

4、AudioConvert转换后的音频数据会填入参数buffList,将对应的数据复制给AudioUnit的playback参数;

遇到的问题

1、API替换

一开始用的是AudioFileReadPackets方法读取音频数据,后面在遇到问题后发现AudioFileReadPackets被替换成AudioFileReadPacketData,参数类似;

2、AudioConverter的转换函数的返回值

调用AudioConverterFillComplexBuffer后,在回调方法lyInInputDataProc中,如果设置 *ioNumberDataPackets = 0,并且返回 noErr, AudioConverter 会进入 Finished 的状态;

返回非零的值,表示数据未完成,比如在demo中返回了NO_MORE_DATANO_MORE_DATA是自定义的非零返回值;

3、AudioConverterNewSpecific返回-50

通过OSStatus,可以看到-50是AVAudioSessionErrorCodeBadParam 参数不一致;

检查代码,发现是在使用AudioConverterNewSpecific() 创建转换器的时候输入流格式与输出流格式的声道数设置不同;(解决方案就是声道数改成一致)

4、AudioConverterFillComplexBuffer返回561015652

通过OSStatus,查到561015652是kAudioConverterErr_RequiresPacketDescriptionsError = '!pkd',意思是没有回调AudioStreamPacketDescriptions参数;

对于音频格式mBytesPerPacket=0的数据,需要AudioStreamPacketDescriptions参数来辅助转换音频数据;

解决方案就是新建AudioStreamPacketDescriptions数组,并且在读取后赋值给outDataPacketDescription(见demo);

总结

AudioUnit和AudioConvert的API虽然简单,却是功能强大。

文章中的介绍更多是自己在学习过程中的一些收获,对于知识点的介绍很多是不够全面和仔细的,对此建议看看参考目录

Extended Audio File ServicesAudio File ServicesAudio Converter Services 的结合,提供统一的接口进行处理,下篇可能会是Extended Audio File相关。

参考

Playing a sound file using the Default Output Audio Unit

Supported Audio File and Data Formats in OS X

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.10.09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 正文
    • 1、格式转换
      • 2、AudioFile API 和 Converter
        • 3、具体细节
        • 遇到的问题
          • 1、API替换
            • 2、AudioConverter的转换函数的返回值
              • 3、AudioConverterNewSpecific返回-50
                • 4、AudioConverterFillComplexBuffer返回561015652
                • 总结
                • 参考
                相关产品与服务
                云点播
                面向音视频、图片等媒体,提供制作上传、存储、转码、媒体处理、媒体 AI、加速分发播放、版权保护等一体化的高品质媒体服务。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档