天天看点

IOS 音频开发

iPhone OS 主要提供以下了几种播放音频的方法:

System Sound Services

AVAudioPlayer 类

Audio Queue Services

OpenAL

1. System Sound Services

System Sound Services 是最底层也是最简单的声音播放服务,调用 AudioServicesPlaySystemSound 这个方法就可以播放一些简单的音频文件,使用此方法只适合播放一些很小的提示或者警告音,因为它有很多限制:

■ 声音长度要小于 30 秒

■ In linear PCM 或者 IMA4 (IMA/ADPCM) 格式的

■ 打包成 .caf, .aif, 或者 .wav 的文件

■ 不能控制播放的进度

■ 调用方法后立即播放声音

■ 没有循环播放和立体声控制

另外,它还可以调用系统的震动功能,方法也很简单。具体的代码可以参考官方的示例 SysSound

, 但是官方的示例只有一些简单的用法,从文档中我们发现可以通过 AudioServicesAddSystemSoundCompletion 方法为音频播放添加 CallBack 函数,有了 CallBack 函数我们可以解决不少问题,比如可以克服 System Sound Services 本身不支持循环播放的问题。以下代码可以实现一个在程序中循环播放的背景音乐:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<code>static</code> <code>void</code> <code>completionCallback (SystemSoundID  mySSID) {</code>

<code>    </code><code>// Play again after sound play completion</code>

<code>    </code><code>AudioServicesPlaySystemSound(mySSID);</code>

<code>}</code>

<code>- (</code><code>void</code><code>) playSound {</code>

<code>    </code><code>// Get the main bundle for the app</code>

<code>    </code><code>CFBundleRef mainBundle;</code>

<code>    </code><code>SystemSoundID soundFileObject;</code>

<code>    </code><code>mainBundle = CFBundleGetMainBundle ();</code>

<code>    </code> 

<code>    </code><code>// Get the URL to the sound file to play</code>

<code>    </code><code>CFURLRef soundFileURLRef  = CFBundleCopyResourceURL (</code>

<code>                                                         </code><code>mainBundle,</code>

<code>                                                         </code><code>CFSTR (</code><code>"background"</code><code>),</code>

<code>                                                         </code><code>CFSTR (</code><code>"wav"</code><code>),</code>

<code>                                                         </code><code>NULL</code>

<code>                                                         </code><code>);</code>

<code>    </code><code>// Create a system sound object representing the sound file</code>

<code>    </code><code>AudioServicesCreateSystemSoundID (</code>

<code>                                      </code><code>soundFileURLRef,</code>

<code>                                      </code><code>&amp;soundFileObject</code>

<code>                                      </code><code>);</code>

<code>    </code><code>// Add sound completion callback</code>

<code>    </code><code>AudioServicesAddSystemSoundCompletion (soundFileObject, NULL, NULL,</code>

<code>                                           </code><code>completionCallback,</code>

<code>                                           </code><code>(</code><code>void</code><code>*) self);</code>

<code>    </code><code>// Play the audio</code>

<code>    </code><code>AudioServicesPlaySystemSound(soundFileObject);</code>

  2. AVAudioPlayer 类

AVAudioPlayer 是 AVFoundation.framework 中定义的一个类,所以使用要先在工程中引入 AVFoundation.framework。我们可以把 AVAudioPlayer 看作是一个高级的播放器,它支持广泛的音频格式,主要是以下这些格式:

■ AAC

■ AMR(AdaptiveMulti-Rate, aformatforspeech)

■ ALAC(AppleLossless)

■ iLBC(internetLowBitrateCodec, anotherformatforspeech)

■ IMA4(IMA/ADPCM)

■ linearPCM(uncompressed)

■ μ-lawanda-law

■ MP3(MPEG-1audiolayer3 

AVAudioPlayer 可以播放任意长度的音频文件、支持循环播放、可以同步播放多个音频文件、控制播放进度以及从音频文件的任意一点开始播放等,更高级的功能可以参考 AVAudioPlayer 的文档。一个AVAudioPlayer对象只能播放一个音频文件,如果要同时播放多个音频,即产生混音则要再创建一个AVAudioPlayer对象来播放,AVAudioPlayer可以播放本地音频和网络音频,但无论是哪种,它都要将整个音频文件数据预先加载到内存中完毕后,才能开始播放,对于本地的大音频文件和网络上的大音频文件(网络上太大的音频文件貌似也播放不成功,苹果对此有限制)或网速不好的情况下会出现缓存很久的情况,这体验显然要注意(所以采用AVAudioPlayer制作本地音乐播放器也会有卡的问题,更别说网络音乐播放器了,只能在一些其他应用中播放一些比较小的音效),因此,最好能采用流式播放 要使用 AVAudioPlayer 的对象播放文件,你只需为其指定一个音频文件并设定一个实现了 AVAudioPlayerDelegate 协议的 delegate 对象。这里举一个简单的例子,和上一个例子一样,实现一直循环播放的背景音乐:

<code>- (</code><code>void</code><code>) playBackgroundSoundEffect {</code>

<code>    </code><code>NSString *soundFilePath =</code>

<code>    </code><code>[[NSBundle mainBundle] pathForResource: @</code><code>"background"</code>

<code>                                    </code><code>ofType: @</code><code>"wav"</code><code>];</code>

<code>    </code><code>NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];</code>

<code>    </code><code>AVAudioPlayer *newPlayer =</code>

<code>    </code><code>[[AVAudioPlayer alloc] initWithContentsOfURL: fileURL</code>

<code>                                           </code><code>error: nil];</code>

<code>    </code><code>[fileURL release];</code>

<code>    </code><code>self.player = newPlayer;</code>

<code>    </code><code>[newPlayer release];</code>

<code>    </code><code>[self.player prepareToPlay];</code>

<code>    </code><code>[self.player setDelegate: self];</code>

<code>    </code><code>self.player.numberOfLoops = -1;   </code> <code>// Loop playback until invoke stop method</code>

<code>    </code><code>[self.player play];</code>

  可以看到,只要将 AVAudioPlayer 的 numberOfLoops 属性设为负数,音频文件就会一直循环播放直到调用 stop 方法。

AVAudioPlayer 同样支持 Callback,这是 AVAudioPlayerDelegate 的一个可选 delegate 方法:

- (void) audioPlayerDidFinishPlaying: (AVAudioPlayer *) player successfully: (BOOL) flag { 

    if (player == self.player &amp;&amp; flag == YES) { 

        NSLog(@"Playback finish.");

    } 

另外,你可以随时控制 AVAudioPlayer 对象的播放、暂停以及停止,通过判断对象的状态,分别调用 play、pause 和 stop 方法即可:

- (IBAction) playOrPause: (id) sender { 

    // if playing, pause 

    if (self.player.playing) { 

        [self.player pause]; 

    // if stopped or paused, start playing 

    } else { 

        [self.player play]; 

虽 然 AVAudioPlayer 可以播放很多格式,但是我们在实际开发过程中还是最好使用一些没有压缩的格式,比如 WAVE 文件,这样可以减少系统处理单元的资源占用,以便更好的完成程序的其他功能。另外,在使用 AVAudioPlayer 连续播放 mp3 这类经过压缩的音频文件时,在连接处可能出现一定的间隔时间。

iOS4 后台播放音乐最简单的方法

打开你的XXX-Info.plist增加一项

Required background modes 默认是数组,在其下增加一个元素 App plays audio

然后在你播放音乐的代码前增加一行

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

注意模拟器是不能展示后台效果的,不要实现了功能还以为没实现,请用真机测试

3.MPMusicPlayerController 引入MediaPlayer.framework

   MPMusicPlayerController只能播放本地ipod中的歌曲,无法播放其他地方和网络上的资源,播放本地时能实现不卡播放的效果,但一般在那种纯音乐播放器中用的比较多(酷狗、酷我等)

  播放在App中的音频时,使用AVAudioPlayer;

  播放音乐库中的文件时,使用MPMusicPlayerController;

  虽然MPMusicPlayerController 能够播放本地音频文件,但其主要用途还是集成现有的音乐库多媒体文件

4. Audio Queue Services

如果以上两种音频播放的解决方案都无 法满足你的需求,那么我想你肯定需要使用 Audio Queue Services。使用 Audio Queue Services 对音频进行播放,你可以完全实现对声音的控制。例如,你可以在声音数据从文件读到内存缓冲区后对声音进行一定处理再进行播放,从而实现对音频的快速/慢速 播放的功能。

因为 Audio Queue Services 相对复杂很多,Apple 官方已经把它整理为一本书了,具体可以参考 Audio Queue Services Programming Guide 和 SpeakHere 的程序示例。

播放流音频源代码:http://code4app.com/ios/在线音频播放器/4ffc45006803fa9e19000000

 播放本地音乐采用SpeakHere中的音频队列模式播放,可以减少预加载时间,播放在线音乐采用Audio Streamer 这是老外写的一个在线音频流类  上述code4app的那个例子即可采用  发现服务器不用特殊部署,只要是一个音乐文件就行

5. OpenAL

OpenAL 是一套跨平台的开源的音频处理接口,与图形处理的 OpenGL 类似,它为音频播放提供了一套更加优化的方案。它最适合开发游戏的音效,用法也与其他平台下相同。

iPhone 支持 OpenAL 1.1,我没有在实际开发中使用过,具体的文档可以参考 OpenAL 的网站 http://openal.org和 oalTouch 的程序示例。

网络上志同道合,我们一起学习网络安全,一起进步,QQ群:694839022