多媒体支持
2011-09-28 15:37
169 查看
您可以利用iPhoneOS的多媒体
高品质的音频录制和回放
生动的游戏声音
实时的声音聊天
用户iPod音乐库内容的回放
在支持的设备上进行视频的回放和录制
本章将介绍iPhoneOS上为应用程序添加音视频功能的多媒体技术。
在iPhoneOS上使用声音
iPhoneOS为应用程序提供一组丰富的声音处理工具。根据功能的不同,这些工具被安排到如下的框架中:
如果希望用简单的Objective-C接口进行音频的播放和录制,可以使用AVFoundation框架。
如果要播放和录制带有同步能力的音频、解析音频流、或者进行音频格式转换,可以使用AudioToolbox框架。
如果要连接和使用音频处理插件,可以使用AudioUnit框架。
如果希望在游戏和其它应用程序中回放位置音频,需要使用OpenAL框架。iPhoneOS对OpenAL1.1的支持是建立在CoreAudio基础上的。
如果希望播放iPod库中的歌曲、音频书、或音频播客,需要使用MediaPlayer框架中的iPod媒体库访问接口。
CoreAudio框架(和其它音频框架对等)中提供所有CoreAudio服务需要使用的数据类型。
本部分将就如何着手实现各种音频功能提供一些指导,如下表所示:
播放用户iPod库中的歌曲、音频播客、以及音频书,请参见
播放警告及用户界面声音效果,或者使具有震动功能的设备发生震动,可以使用系统声音服务,具体请参见
如果要用最少量的代码播放和录制音频,可以使用AVFoundation框架,具体参见
如果需要提供全功能的音频回放,包括立体声定位、音量控制、和同期声(simultaneoussounds),可以使用OpenAL,具体参见
如果要提供最低延迟的音频,特别是需要同时进行音频输入输出(比如VoIP应用程序)时,请使用I/O音频单元,具体请参见“iPhone
OS中的音频单元支持”部分。
如果您播放的声音需要精确的控制(包括同步),可以使用音频队列服务,具体参见
如果需要解析来自网络连接的音频流,请使用音频文件流服务,具体参见
请务必阅读本文接下来的部分,即
OS的设备上音频工作机制的关键信息;而且也请您阅读
当您准备好进一步学习时,请访问iPhoneDevCenter。这个开发者中心包含各种指南文档、实例代码、及更多其它信息。有关如何执行常见音频任务的贴士,请参见
OS音频开发的深入解释,则请参见
基础:硬件编解码器、音频格式、和音频会话
在开始iPhone音频开发之前,了解iPhoneOS设备的一些硬软件架构知识是很有帮助的。
iPhone音频硬件编解码
iPhoneOS的应用程序可以使用广泛的音频数据格式。从iPhoneOS3.0开始,这些格式中的大多数都可以支持基于软件的编解码。您可以同时播放多路各种格式的声音,虽然出于性能的考虑,您应该针对给定的场景选择最佳的格式。通常情况下,硬件解码带来的性能影响比软件解码要小。
下面这些iPhoneOS音频格式可以利用硬件解码进行回放:
AAC
ALAC(AppleLossless)
MP3
通过硬件,设备每次只能播放这些格式中的一种。举例来说,如果您正在播放的是MP3立体声,则第二个同时播放的MP3声音就只能使用软件解码。类似地,您不能通过硬件同时播放一个AAC声音和一个ALAC声音。如果iPod应用程序正在后台播放AAC声音,则您的应用程序只能使用软件解码来播放AAC、ALAC、和MP3音频。
为了以最佳性能播放多种声音,或者为了在iPod程序播放音乐的同时能更有效地播放声音,可以使用线性PCM(无压缩)或者IMA4(有压缩)格式的音频。
如果需要了解如何检测设备硬软件编解码器是否可用,请查阅
常量的讨论。
音频回放和录制格式
下面是一些iPhoneOS支持的音频回放格式:
AAC
HE-AAC
AMR(AdaptiveMulti-Rate,是一种语音格式)
ALAC(AppleLossless)
iLBC(互联网LowBitrateCodec,另一种语音格式)
IMA4(IMA/ADPCM)
线性PCM(无压缩)
?-law和a-law
MP3(MPEG-1音频第3层)
下面是一些iPhoneOS支持的音频录制格式:
ALAC(AppleLossless)
iLBC(互联网LowBitrateCodec,用于语音)
IMA/ADPCM(IMA4)
线性PCM
?-law和a-law
下面的列表总结了iPhoneOS如何支持单路或多路音频格式:
线性PCM和IMA4(IMA/ADPCM)在iPhoneOS上,您可以同时播放多路线性PCM或IMA4声音,而不会导致CPU资源的问题。这一点同样适用于AMR和iLBC语音品质格式,以及?-law和a-law压缩格式。在使用压缩格式时,请检查声音的品质,确保满足您的需要。
AAC、MP3、和ALAC(AppleLossless)AAC、MP3、和ALAC声音的回放可以使用iPhoneOS设备上高效的硬件解码,但是这些编解码器共用一个硬件路径,通过硬件,设备每次只能播放上述格式的一种。
AAC、MP3、和ALAC的回放共用同一硬件路径的事实会对“合作播放”风格的应用程序(比如虚拟钢琴)产生影响。如果用户在iPod程序上播放上述三种格式之一的音频,则您的应用程序—如果要和该音频一起播放声音—需要使用软件解码。
音频会话
CoreAudio的音频会话接口(具体描述请见
您的音频在Ring/Silent切换过程中是否变为无声
在屏幕锁定状态时您的音频是否停止
当您的音频开始播放时,iPod音频是继续播放,还是变为无声
更大的音频上下文包括用户所做的改变,比如用户插入耳机,处理Clock和Calendar这样的警告事件,或者处理呼入的电话。通过音频会话,您可以对这样的事件做出恰当的响应。
音频会话服务提供了三种编程特性,如表7-1所述。
音频会话特性 | 描述 |
---|---|
范畴 | 范畴是标识一组应用程序音频行为的键。您可以通过范畴的设置来指示自己希望得到的音频行为,比如希望在屏幕锁定状态时继续播放音频。 |
中断和路由变化 | 当您的音频发生中断或中断结束,以及当硬件音频路由发生变化时,音频会话会发出 |
硬件特征 | 您可以通过查询音频会话来了解应用程序所在的设备的特征,比如硬件采样率,硬件通道数量,以及是否有音频输入。 |
音频会话带有一些缺省的行为,可以作为开发的起点。但是,除了某些特殊的情况之外,采用缺省行为的音频应用程序并不适合发行。您需要通过配置和使用音频会话来表达自己使用音频的意图,响应OS级别的音频变化。
举例来说,在使用缺省的音频会话时,如果出现Auto-Lock超时或屏幕锁定,应用程序的音频就会停止。如果您希望在屏幕被锁定时继续播放音频,则必须将下面的代码包含到应用程序的
[[AVAudioSessionsharedInstance]setCategory:AVAudioSessionCategoryPlaybackerror:nil]; |
[[AVAudioSessionsharedInstance]setActive:YESerror:nil]; |
范畴确保音频的回放可以在屏幕锁定时继续。激活音频会话会使指定的范畴也被激活。范畴的详细信息请参见
如何处理呼入电话或时钟警告引起的中断取决于您使用的音频技术,如表7-2所示。
音频技术 | 中断如何工作 |
---|---|
系统声音服务 | 当中断开始时,系统声音和警告声音会变为无声。如果中断结束—当用户取消警告或选择忽略呼入电话时,会发生这种情况—它们就又自动变为可用。使用这种技术的应用程序无法影响声音中断的行为。 |
音频队列服务、OpenAL、I/O音频单元 | 这些技术为中断的处理提供最大的灵活性。您需要编写一个中断监听回调函数,具体描述请参见 |
AVAudioPlayer 类 | AVAudioPlayer 类为中断的开始和结束提供了 audioPlayerBeginInterruption: 方法中更新用户界面,音频播放器对象会负责暂停回放。您也可以利用 audioPlayerEndInterruption: 方法来重启音频的回放,并在必要时更新用户界面。音频播放器会负责重新激活您的音频会话。 |
播放音频
本部分将介绍如何用iPod媒体库访问接口、系统声音服务、音频队列服务、AVFoundation框架、和OpenAL来播放iPhoneOS上的声音。
通过iPod媒体库访问接口播放媒体项
从iPhoneOS3.0开始,iPod媒体库访问接口使应用程序可以播放用户的歌曲、音频书,和音频播客。这个API的设计使基本回放变得非常简单,同时又支持高级的检索和回放控制。
如图7-1所示,您的应用程序有两种方式可以取得媒体项,一种是通过媒体项选择器,如图左所示,它是个易于使用、预先封装好的视图控制器,其行为和内置iPod程序的音乐选择接口类似。对于很多应用程序,这种方式就够用了。如果媒体选择器没有提供您需要的某种访问控制,则可以使用媒体查询接口,该接口支持以基于断言(predicate)的方式指定iPod媒体库中的项目。
图7-1使用iPod媒体库访问接口
如上图所示,位于右边的应用程序在取得媒体项之后,可以通过这个API提供的音乐播放器进行播放。
有关如何在应用程序中加入媒体项回放功能的完整解释,请参见iPod媒体库访问接口指南。
使用系统声音服务播放短声音及触发震动
当您需要播放用户界面声音效果(比如触击按键)或警告声音,或者使支持震动的设备产生震动时,可以使用系统声音服务。这个简洁接口的描述请参见
DevCenter中找到
请注意:通过系统声音服务播放的声音不受音频会话配置的控制。因此,您无法使系统声音服务的音频行为和应用程序的其它音频行为保持一致。这也是需要避免使用系统声音服务播放音频的最重要原因,除非您有意为之。
函数使您可以非常简单地播放短声音文件。使用上的简单也带来一些限制。您的声音文件必须是:
长度小于30秒
采用PCM或者IMA4(IMA/ADPCM)格式
包装为
.caf
、
.aif
、或者
.wav
文件
此外,当您使用
AudioServicesPlaySystemSound
函数时:
声音会以当前系统音量播放,且无法控制音量
声音立即被播放
不支持环绕和立体效果
是一个类似的函数,用于播放一个短声音警告。如果用户在声音设置中将设备配置为震动,则这个函数在播放声音文件之外还会产生震动。
请注意:系统和用户界面的声音效果并不提供给您的应用程序。举例来说,将
kSystemSoundID_UserPreferredAlert
常量作为参数传递给
函数将不会播放任何声音。
在用
或
函数时,您需要首先创建一个声音ID对象,如程序清单7-1所示。
程序清单7-1创建一个声音ID对象
//Getthemainbundlefortheapp |
CFBundleRefmainBundle=CFBundleGetMainBundle(); |
//GettheURLtothesoundfiletoplay.Thefileinthiscase |
//is"tap.aiff" |
soundFileURLRef=CFBundleCopyResourceURL( |
mainBundle, |
CFSTR("tap"), |
CFSTR("aif"), |
NULL |
); |
//Createasystemsoundobjectrepresentingthesoundfile |
AudioServicesCreateSystemSoundID( |
soundFileURLRef, |
&soundFileObject |
); |
程序清单7-2播放一个系统声音
-(IBAction)playSystemSound{ |
AudioServicesPlaySystemSound(self.soundFileObject); |
} |
如果iPhoneOS设备支持振动,则运行在该设备上的应用程序可以通过系统声音服务触发振动,振动的选项通过
kSystemSoundID_Vibrate
标识符来指定。
AudioServicesPlaySystemSound
函数可以用于触发振动,具体如程序清单7-3所示。
程序清单7-3触发振动
#import<AudioToolbox/AudioToolbox.h> |
#import<UIKit/UIKit.h> |
-(void)vibratePhone{ |
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); |
} |
通过AVAudioPlayer类轻松播放声音
AVAudioPlayer
类提供了一个简单的
通过音频播放器可以实现如下任务:
播放任意长度的声音
播放文件或内存缓冲区中的声音
循环播放声音
同时播放多路声音(虽然不能精确同步)
控制每个正在播放声音的相对音量
跳到声音文件的特定点上,这可以为需要快进和反绕的应用程序提供支持
取得音频强度数据,用于测量音量
AVAudioPlayer
类可以播放iPhoneOS上有的所有音频格式,具体描述请参见
为了使音频播放器播放音频,您需要为其分配一个声音文件,使其做好播放的准备,并为其指定一个委托对象。程序清单7-4中的代码通常放在应用程序控制器类的初始化方法中。
程序清单7-4配置AVAudioPlayer对象
//inthecorresponding.hfile: |
//@property(nonatomic,retain)AVAudioPlayer*player; |
@synthesizeplayer;//theplayerobject |
NSString*soundFilePath= |
[[NSBundlemainBundle]pathForResource:@"sound" |
ofType:@"wav"]; |
NSURL*fileURL=[[NSURLalloc]initFileURLWithPath:soundFilePath]; |
AVAudioPlayer*newPlayer= |
[[AVAudioPlayeralloc]initWithContentsOfURL:fileURL |
error:nil]; |
[fileURLrelease]; |
self.player=newPlayer; |
[newPlayerrelease]; |
[playerprepareToPlay]; |
[playersetDelegate:self]; |
AVAudioPlayer
类的委托对象的具体描述请参见
程序清单7-5实现AVAudioPlayer类的委托方法
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer*)player |
successfully:(BOOL)flag{ |
if(flag==YES){ |
[self.buttonsetTitle:@"Play"forState:UIControlStateNormal]; |
} |
} |
AVAudioPlayer
对象执行播放、暂停、或者停止操作。您可以通过
playing
属性来检测当前是否正在播放。程序清单7-6显示了播放/暂停切换方法的基本实现,其功能是控制回放和更新
UIButton
对象的标题。
程序清单7-6控制AVAudioPlayer对象
-(IBAction)playOrPause:(id)sender{ |
//ifalreadyplaying,thenpause |
if(self.player.playing){ |
[self.buttonsetTitle:@"Play"forState:UIControlStateHighlighted]; |
[self.buttonsetTitle:@"Play"forState:UIControlStateNormal]; |
[self.playerpause]; |
//ifstoppedorpaused,startplaying |
}else{ |
[self.buttonsetTitle:@"Pause"forState:UIControlStateHighlighted]; |
[self.buttonsetTitle:@"Pause"forState:UIControlStateNormal]; |
[self.playerplay]; |
} |
} |
类使用Objective-C的
[self.playersetVolume:1.0];//availablerangeis0.0through1.0 |
AVAudioPlayer
类的更多信息,请参见
用音频队列服务播放和控制声音
音频队列服务(AudioQueueServices)加入了一些
AVAudioPlayer
类不具有的回放能力。通过音频队列服务进行回放可以:
精确计划声音的播放,支持声音的同步。
精确控制音量—基于一个个的缓冲区。
通过音频文件流服务(AudioFileStreamServices)来播放从流中捕捉的音频。
音频队列服务可以播放iPhoneOS支持的所有音频格式,具体描述请见
有关如何使用这个技术的详细信息,请参见
DevCenter网站的
/Developer/Examples/CoreAudio/SimpleSDK/AudioQueueTools
路径下可以找到AudioQueueTools工程)。
创建一个音频队列对象
创建一个音频队列对象需要下面三个步骤:
创建管理音频队列所需的数据结构,比如您希望播放的音频格式。
定义管理音频队列缓冲区的回调函数。在回调函数中,您可以使用音频文件服务来读取希望播放的文件(在iPhoneOS2.1及更高版本中,您还可以用扩展音频文件服务来读取文件)。
通过
函数实例化回放音频队列。
程序清单7-7是上述步骤的ANSIC代码。
程序清单7-7创建一个音频队列对象
staticconstintkNumberBuffers=3; |
//Createadatastructuretomanageinformationneededbytheaudioqueue |
structmyAQStruct{ |
AudioFileIDmAudioFile; |
CAStreamBasicDescriptionmDataFormat; |
AudioQueueRefmQueue; |
AudioQueueBufferRefmBuffers[kNumberBuffers]; |
SInt64mCurrentPacket; |
UInt32mNumPacketsToRead; |
AudioStreamPacketDescription*mPacketDescs; |
boolmDone; |
}; |
//Defineaplaybackaudioqueuecallbackfunction |
staticvoidAQTestBufferCallback( |
void*inUserData, |
AudioQueueRefinAQ, |
AudioQueueBufferRefinCompleteAQBuffer |
){ |
myAQStruct*myInfo=(myAQStruct*)inUserData; |
if(myInfo->mDone)return; |
UInt32numBytes; |
UInt32nPackets=myInfo->mNumPacketsToRead; |
AudioFileReadPackets( |
myInfo->mAudioFile, |
false, |
&numBytes, |
myInfo->mPacketDescs, |
myInfo->mCurrentPacket, |
&nPackets, |
inCompleteAQBuffer->mAudioData |
); |
if(nPackets>0){ |
inCompleteAQBuffer->mAudioDataByteSize=numBytes; |
AudioQueueEnqueueBuffer( |
inAQ, |
inCompleteAQBuffer, |
(myInfo->mPacketDescs?nPackets:0), |
myInfo->mPacketDescs |
); |
myInfo->mCurrentPacket+=nPackets; |
}else{ |
AudioQueueStop( |
myInfo->mQueue, |
false |
); |
myInfo->mDone=true; |
} |
} |
//Instantiateanaudioqueueobject |
AudioQueueNewOutput( |
&myInfo.mDataFormat, |
AQTestBufferCallback, |
&myInfo, |
CFRunLoopGetCurrent(), |
kCFRunLoopCommonModes, |
0, |
&myInfo.mQueue |
); |
音频队列对象为您提供两种控制回放音量的方法。
您可以通过调用
函数并传入
kAudioQueueParam_Volume
参数来直接设置回放的音量,如程序清单7-8所示,音量的变化会立即生效。
程序清单7-8直接设置回放的音量
Float32volume=1;//linearscale,rangefrom0.0through1.0 |
AudioQueueSetParameter( |
myAQstruct.audioQueueObject, |
kAudioQueueParam_Volume, |
volume |
); |
函数来设置音频队列缓冲区的回放音量。这个函数可以指定音频队列缓冲区进入队列时携带的音频队列设置。通过这个函数做出的改变在音频队列缓冲区开始播放的时候生效。
在上述的两种情况下,对音频队列的音量所做的修改都会一直保持下来,直到再次被改变。
指示回放音量
您可以通过下面的方式得到音频队列对象的当前回放音量:
启用音频队列对象的音量计,具体方法是将其
kAudioQueueProperty_EnableLevelMetering
属性设置为
true
。
查询音频队列对象的
kAudioQueueProperty_CurrentLevelMeter
属性。
这个属性的值是一个
AudioQueueLevelMeterState
结构的数组,每个声道都有一个相对应的结构。程序清单7-9显示了这个结构的内容:
程序清单7-9
AudioQueueLevelMeterState
结构
typedefstructAudioQueueLevelMeterState{ |
Float32mAveragePower; |
Float32mPeakPower; |
};AudioQueueLevelMeterState; |
为了同时播放多路声音,需要为每路声音创建一个回放音频队列对象,并对每个音频队列调用
函数,将第一个音频缓冲区排入队列,使之开始播放。
在基于iPhoneOS的设备中同时播放声音时,音频格式是很关键的。如果要同时播放,您需要使用线性PCM(无压缩)音频格式或特定的有压缩音频格式,具体描述请参见
使用OpenAL播放和定位声音
开源的OpenAL音频API位于iPhoneOS系统的OpenAL
Audio的I/O单元进行回放,从而使延迟最低。
由于所有的这些原因,OpenAL是iPhoneOS设备中游戏程序的最好选择。当然,OpenAL也是一般的iPhoneOS应用程序进行音频播放的良好选择。
iPhoneOS对OpenAL1.1的支持是构建在CoreAudio之上的。更多的信息请参见iPhone
OS系统的OpenALFAQ。如果需要有关OpenAL的文档,请参见
录制音频
在iPhoneOS系统上,可以通过
类和音频队列服务来进行音频录制,而CoreAudio则为其提供底层的支持。这些接口所做的工作包括连接音频硬件、管理内存、以及在需要时使用编解码器。您可以录制
本部分将介绍如何通过
AVAudioRecorder
类和音频队列服务在iPhoneOS系统上录制音频。
通过AVAudioRecorder类进行录制
iPhoneOS上最简单的录音方法是使用
AVAudioRecorder
类,类的具体描述请参见
进行录制时,您需要提供一个声音文件的URL、建立音频会话、以及配置录音对象。进行这些准备工作的一个良好时机就是应用程序启动的时候,如程序清单7-10所示。诸如
soundFileURL
和
recording
这样的变量都在类接口文件中进行声明。
程序清单7-10建立音频会话和声音文件的URL
-(void)viewDidLoad{ |
[superviewDidLoad]; |
NSString*tempDir=NSTemporaryDirectory(); |
NSString*soundFilePath=[tempDirstringByAppendingString:@"sound.caf"]; |
NSURL*newURL=[[NSURLalloc]initFileURLWithPath:soundFilePath]; |
self.soundFileURL=newURL; |
[newURLrelease]; |
AVAudioSession*audioSession=[AVAudioSessionsharedInstance]; |
audioSession.delegate=self; |
[audioSessionsetActive:YESerror:nil]; |
recording=NO; |
playing=NO; |
} |
AVAudioSessionDelegate
、
AVAudioRecorderDelegate
、
AVAudioPlayerDelegate
(如果同时支持声音回放的话)协议。
然后,就可以实现如程序清单7-11所示的录制方法。
程序清单7-11一个基于AVAudioRecorder类的录制/停止方法
-(IBAction)recordOrStop:(id)sender{ |
if(recording){ |
[soundRecorderstop]; |
recording=NO; |
self.soundRecorder=nil; |
[recordOrStopButtonsetTitle:@"Record"forState:UIControlStateNormal]; |
[recordOrStopButtonsetTitle:@"Record"forState:UIControlStateHighlighted]; |
[[AVAudioSessionsharedInstance]setActive:NOerror:nil]; |
}else{ |
[[AVAudioSessionsharedInstance]setCategory:AVAudioSessionCategoryRecorderror:nil]; |
NSDictionary*recordSettings= |
[[NSDictionaryalloc]initWithObjectsAndKeys: |
[NSNumbernumberWithFloat:44100.0],AVSampleRateKey, |
[NSNumbernumberWithInt:kAudioFormatAppleLossless],AVFormatIDKey, |
[NSNumbernumberWithInt:1],AVNumberOfChannelsKey, |
[NSNumbernumberWithInt:AVAudioQualityMax],AVEncoderAudioQualityKey, |
nil]; |
AVAudioRecorder*newRecorder=[[AVAudioRecorderalloc]initWithURL:soundFileURL |
settings:recordSettings |
error:nil]; |
[recordSettingsrelease]; |
self.soundRecorder=newRecorder; |
[newRecorderrelease]; |
soundRecorder.delegate=self; |
[soundRecorderprepareToRecord]; |
[soundRecorderrecord]; |
[recordOrStopButtonsetTitle:@"Stop"forState:UIControlStateNormal]; |
[recordOrStopButtonsetTitle:@"Stop"forState:UIControlStateHighlighted]; |
recording=YES; |
} |
} |
AVAudioRecorder
类的更多信息,请参见
用音频队列服务进行录制
用音频队列服务进行录制时,您的应用程序需要配置音频会话、实例化一个录音音频队列对象,并为其提供一个回调函数。回调函数负责将音频数据存入内存以备随时使用,或者写入文件进行长期存储。
声音的录制发生在iPhoneOS的系统定义级别(system-definedlevel)。系统会从用户选择的音频源取得输入—比如内置的麦克风、耳机麦克风(如果连接到iPhone上的话)、或者其它输入源。
和声音的回放一样,您可以通过查询音频队列对象的
kAudioQueueProperty_CurrentLevelMeter
属性来取得当前的录制音量,具体描述请见
有关如何通过音频队列服务录制音频的详细实例,请参见
DevCenter网站上的
解析音频流
为了播放音频流内容,比如来自网络连接的音频流,可以结合使用音频文件流服务和音频队列服务。音频文件流服务负责从常见的、采用网络位流格式的音频文件容器中解析出音频数据和元数据。您也可以用它来解析磁盘文件中的数据包和元数据。
iPhoneOS可以解析的音频文件和位流格式和MacOSX相同,具体如下:
MPEG-1AudioLayer3,用于.mp3文件
MPEG-2ADTS,用于.aac音频数据格式
AIFC
AIFF
CAF
MPEG-4,用于.m4a、.mp4、和.3gp文件
NeXT
WAVE
在取得音频数据包之后,您就可以以任何iPhoneOS系统支持的格式进行播放,这些格式在
为了获得最好的性能,处理网络音频流的应用程序应该仅使用来自Wi-Fi连接的数据。您可以通过iPhoneOS提供的SystemConfiguration
SCNetworkReachability.h
头文件定义的接口来确定什么网络是可到达和可用的。如果需要实例代码,请参见
为了连接网络音频流,可以使用iPhoneOS系统中的CoreFoundation框架中的接口,比如
CFHTTPMesaage
接口,具体描述请见
音频文件流服务依赖于音频文件服务定义的接口,比如
AudioFramePacketTranslation
结构和
AudioFilePacketTableInfo
结构,具体描述请见
有关如何使用流的更多信息,请参见
/Examples/CoreAudio/Services/
目录下的AudioFileStream例子工程,其中<Xcode>是开发工具所在的目录。
iPhoneOS系统上的音频单元支持
iPhoneOS提供一组音频插件,称为音频单元,可以用于所有的应用程序。您可以通过AudioUnit
OS系统上的其它应用程序不能使用您开发的音频单元。
表7-3列出了iPhoneOS提供的音频单元。
音频单元 | 描述 |
---|---|
转换器单元 | 转换器单元,类型为 kAudioUnitSubType_AUConverter ,用于音频数据的格式转换。 |
iPod均衡器单元 | iPodEQ单元,类型为 kAudioUnitSubType_AUiPodEQ ,提供一个简单的、基于预设的均衡器,可以在应用程序中使用。 |
3D混音器单元 | 3D混音器单元,类型为 kAudioUnitSubType_AU3DMixerEmbedded ,用于混合多个音频流,指定立体声输出移动,操作采样率,等等。 |
多通道混音器单元 | 多通道混音器单元,类型为 kAudioUnitSubType_MultiChannelMixer ,用于将多个音频流混合成为单一的音频流。 |
一般输出单元 | 一般输出单元,类型为 kAudioUnitSubType_GenericOutput ,支持和线性PCM格式互相转换,可以用于开始或结束一个音频单元图。 |
I/O单元 | I/O单元,类型为 kAudioUnitSubType_RemoteIO ,用于连接音频输入和输入硬件,支持实时I/O。如何使用音频单元的实例代码请见 |
语音处理I/O单元 | 语音处理I/O单元,类型为 kAudioUnitSubType_VoiceProcessingIO ,具有I/O单元的特征,同时为了支持双向交流,加入了回响抑制功能。 |
iPhone音频的最佳实践
操作音频的贴士
在操作iPhoneOS系统上的音频内容时,您需要记住表7-4列出的基本贴士。
贴士 | 动作 |
---|---|
正确地使用压缩音频 | 对于AAC、MP3、和ALAC(AppleLossless)音频,解码过程是由硬件来完成的,虽然比较有效,但同时只能解码一个音频流。如果您需要同时播放多路声音,请使用IMA4(压缩)或者线性PCM(无压缩)格式来存储那些文件。 |
将音频转换为您需要的数据格式和文件格式 | MacOSX的 afconvert 工具可以进行很多数据格式和文件类型的转换。请参见“iPhone OS偏好的音频格式”部分和 afconvert 工具的手册页面。 |
评价音频的内存使用问题 | 当您使用音频队列服务播放音频时,需要编写一个回调函数,负责将较短的音频数据片断发送到音频队列的缓冲区。在某些情况下,将整个音频文件载入内存是最佳的选择,这样可以使播放时的磁盘访问尽最少;而在另外一些情况下,最好的方法则是每次只载入足够填满缓冲区的数据。请测试和评价哪种策略对您的应用程序最好。 |
限制音频的采样率和位深度,减少音频文件的尺寸 | 采样率和每个样本的位深度对无压缩音频的尺寸有直接的影响。如果您需要播放很多这样的声音,则应该考虑降低这些指标,以减少音频数据的内存开销。举例来说,相对于使用采样率为44.1kHz的音频作为声音效果,您可以使用采样率为32kHz(或可能更低)的音频,仍然可以得到很合理的品质。 |
选择恰当的技术 | 使用CoreAudio的系统声音服务来播放警告和用户界面声音效果。当您希望使用便利的高级接口来定位立体声场中的声音,或者要求很低的回放延迟时,则应该使用OpenAL。如果需要从文件或网络数据流中解析出音频数据,可以使用音频文件服务接口。如果只是简单回放一路或多路声音,则应该使用 AVAudioPlayer 类。对于具有其它音频功能的应用程序,包括音频流的回放和音频录制,可以使用音频队列服务。 |
低延迟编码 | 如果需要尽可能低的回放延迟,可以使用OpenAL,或者直接使用I/O单元。 |
对于无压缩(最高品质)音频,请使用封装在CAF文件中的、16位、低位在前(littleendian)的线性PCM音频数据。您可以用MacOSX的
afconvert
命令行工具来将音频文件转换为上述格式:
/usr/bin/afconvert-fcaff-dLEI16{INPUT}{OUTPUT} |
工具可以进行广泛的音频数据格式和文件类型转换。您可以通过
afconvert
的手册页面,以及在shell提示符下键入
afconvert-h
命令获取更多信息。
对于压缩音频,当每次只需播放一个声音,或者当不需要和iPod同时播放音频时,适合使用AAC格式的CAF或m4a文件。
当您需要在同时播放多路声音时减少内存开销时,请使用IMA4(IMA/ADPCM)压缩格式,这样可以减少文件尺寸,同时在解压缩过程中对CPU的影响又最小。和线性PCM数据一样,请将IMA4数据封装在CAF文件中。
在iPhoneOS使用视频
录制视频
从iPhoneOS3.0开始,您可以在具有录制支持的设备上录制视频,包括当时的音频。显示视频录制界面的方法是创建和推出一个
对象,和显示静态图片照相机界面完全一样。
在录制视频时,您必须首先检查是否存在照相机源类型(
),以及照相机是否支持电影媒体类型(
kUTTypeMovie
)。根据您为
mediaTypes
属性分配的媒体类型的不同,选择器对象可以直接显示静态图像照相机,或者视频摄像机,还可以显示一个选择界面,让用户选择。
使用
协议,注册为图像选择器的委托。在视频录制完成时,您的委托对象的
imagePickerController:didFinishPickingMediaWithInfo:
方法会备调用。
对于支持录制的设备,您也可以从用户照片库中选择之前录制的视频。
有关如何使用图像选择器的更多信息,请参见
播放视频文件
在iPhoneOS系统上,应用程序可以通过MediaPlayer框架(
MediaPlayer.framework
)来播放视频文件。视频的回放只支持全屏模式,需要播放场景切换动画的游戏开发者或需要播放媒体文件的其它开发者可以使用。当应用程序开始播放视频时,媒体播放器界面就会接管,将屏幕渐变为黑色,然后渐渐显示视频内容。视频播放界面上可以显示或者不显示调整回放的用户控件。您可以通过部分或全部激活这些控件(如图7-2所示),使用户可以改变音量、改变回放点、开始或停止视频的播放。如果禁用所有的控件,视频会一直播放,直到结束。
图7-2带有播放控制的媒体播放器界面
在开始播放前,您必须知道希望播放的URL。对于应用程序提供的文件,这个URL通常是指向应用程序包中某个文件的指针;但是,它也可以是指向远程服务器文件的指针。您可以用这个URL来
类的实例。这个类负责视频文件的回放和管理用户交互,比如响应用户对播放控制(如果显示的话)的触击动作。简单调用控制器的
方法,就可以开始播放了。
程序清单7-12显示一个实例方法,功能是播放位于指定URL的视频。play方法是异步的调用,在电影播放时会将控制权返回给调用者。电影控制器负责将电影载入一个全屏的视图,并通过动画效果将电影放到应用程序现有内容的上方。在视频回放完成后,电影控制器会向委托对象发出一个
程序清单7-12播放全屏电影
-(void)playMovieAtURL:(NSURL*)theURL |
{ |
MPMoviePlayerController*theMovie=[[MPMoviePlayerControlleralloc]initWithContentURL:theURL]; |
theMovie.scalingMode=MPMovieScalingModeAspectFill; |
theMovie.movieControlMode=MPMovieControlModeHidden; |
//Registerfortheplaybackfinishednotification. |
[[NSNotificationCenterdefaultCenter]addObserver:self |
selector:@selector(myMovieFinishedCallback:) |
name:MPMoviePlayerPlaybackDidFinishNotification |
object:theMovie]; |
//Movieplaybackisasynchronous,sothismethodreturnsimmediately. |
[theMovieplay]; |
} |
//Whenthemovieisdone,releasethecontroller. |
-(void)myMovieFinishedCallback:(NSNotification*)aNotification |
{ |
MPMoviePlayerController*theMovie=[aNotificationobject]; |
[[NSNotificationCenterdefaultCenter]removeObserver:self |
name:MPMoviePlayerPlaybackDidFinishNotification |
object:theMovie]; |
//ReleasethemovieinstancecreatedinplayMovieAtURL: |
[theMovierelease]; |
} |
Player框架参考。有关它支持的视频格式列表,请参见
相关文章推荐
- Extjs 扩展Htmleditor,支持 图片上传 文件上传 插入flash 插入多媒体 插入层 插入横线等功能(2)
- 视频经验---1对多媒体的支持能力验证 2格式转换3视频截图4屏幕录制5音视频采集6从文件生成流媒体7从设备生成实时流
- IOS多媒体支持
- Visual C++利用Intel C++ 编译器提升多核性能与多媒体指令支持获取更高的程序效率与缩小程序体积
- cpu支持sse4.1多媒体指令集有什么作用?
- Qt库支持Phonon播放多媒体的编译(Ubuntu)
- Java对多媒体的支持
- WPF,Silverlight与XAML读书笔记第四十二 - 多媒体支持之音、视频和语音
- IOS多媒体支持
- Atitit. 软件---多媒体区---- jmf 2.1.1 Java Media Framework 支持的格式
- HTML5中添加多媒体支持(二)
- 网页完美内嵌多媒体,支持IE,Mozilla、Firefox、NetScape、Opera
- Ziddu:支持中英文的多媒体文件存储服务
- Atitit. 软件---多媒体区---- jmf 2.1.1 Java Media Framework 支持的格式
- 多媒体支持
- HTML5的设计目的是为了在移动设备上支持多媒体
- CentOS5.2 安装多媒体支持
- HTML5中添加多媒体支持(三)
- 多媒体支持
- 疯狂H5笔记 - 多媒体支持