media库提供了访问设备的多媒体特性的能力。
音频播放
media库提供了控制播放的支持:
• event sounds: 完整播放的短小的音频
• extended sounds: 可能更长,并且再播放期间可以餐厅,但是一次只能打开一个
Event Sounds
如果你有再1-3秒的短小的音频,你就应该使用event sound APIs. 下面就是一个每秒播放一声beep的节拍器的例子。
local soundID = media.newEventSound( "beep.caf" )
local playBeep = function()
media.playEventSound( soundID )
end
timer.performWithDelay( 1000, playBeep, 0 )
上面的例子演示了一个最好的实践:当你只用media.newEventSound加载一次一个EventSound,并且重复播放它。那个函数返回的是一个sound id,这个可以作为参数传给 media.playEventSound。
当然我们也可以向 media.playEventSound传入声音文件作为参数,但是这将会非常浪费。每次调用的时候,都会从磁盘加载同样的声音文件。
media.newEventSound( soundFile )
从 soundFile加载一个event sound(1-3秒),返回一个sound id。这个id可以传给 media.playEventSound用来播放。目前,音频文件必须放在应用程序的资源文件夹里(参看 System-defined directories)。
media.playEventSound( sound )
播放一个 event sound (1-3 秒)。参数sound既可以是一个event sound id,也可以是一个event sound的文件名。推荐使用短促的音频,尤其要避免动画“打嗝”。返回和 media.newEventSound一样的东西。
local soundID = media.newEventSound( "beep.caf" )
local playBeep = function()
media.playEventSound( soundID )
end
timer.performWithDelay( 7500, playBeep, 0 )
注意:在案桌上,在加载一个音频和准备好之间,有一个延迟。 因此,用文件名参数的playEventSound是不被推荐的,也可能经常导致播放失败。要先用 newEventSound 预加载音频为好。
Completion Listener
为了每次event sound被播放的时候,调用一次completion listener,你可以在 playEventSound 参数里指定listener:
media.playEventSound( "beep.caf", onComplete )
Extended Sounds
要处理更长的音频(比如iphoneOS上的MP3格式,常用来播放背景音乐那种),有几个函数允许你播放,暂停,和停止播放一个音频。然而,你只能一次播放一个这样长的音频。这些函数都会操作已经通过 media.playSound开始播放的音频。
media.playSound( "song.mp3" )
local stopAfter10Seconds = function()
media.stopSound()
end
timer.performWithDelay( 10000, stopAfter10Seconds )
下列函数应该可以用来播放更长时间的音频。你只能一次打开一个音频。
media.playSound( soundFile )
media.pauseSound()
media.stopSound()
注意,一个很长的MP3被初始加载的时候要花费一段时间,可能会导致动画有一个短暂的暂停。一个解决办法,就是利用先加载再立即停止它,在程序中提前“预加载”这个mp3:
media.playSound( 'sound.mp3' )
media.stopSound()
Completion Listener
这些更久的音频,也可以有一个 completion listener。这就要用 playSound 的可选参数。
1
2
3
4
5
6
7
local onComplete --这句很关键
onComplete = function(event)
print( "sound play ended" )
media.playSound( "note2.mp3", onComplete )
end
media.playSound( "note2.mp3", onComplete )
在这例子中,当 note2.mp3被播放完成后, onComplete被调用。然后立即返回重新开始 playSound,所以这是一种循环形式;然而,在声音播放的间隔里,会有小的空隙。
注意:这个例子里, onComplete在前面做了一个局部声明,因为这个函数创建之前,函数体里引用的 onComplete 必须在之前就存在(否则Lua就会把它解释为一个局部变量,这变量没有被赋值,所以什么也不会发生)。
为了使用一个备用路径来播放音频,你也可以使用下面的调用:
1
media.playSound( "note2.mp3", system.DocumentsDirectory )
Loop 参数
设置最后的参数为true,可以导致 extended sound循环播放:
media.playSound( "note2.mp3", true )
它将会循环下去直到你停止它。这比用 onComplete来循环的开销更加的小。所以上一次音频结束到下一次音频开始之间的间隔也更加的少。
音量控制
extended sound的音量(并非 event sounds)目前可以被设置和访问,取值范围在0到1.0之间。例如:
media.setSoundVolume( 0.5 )
print( "volume = " .. media.getSoundVolume() )
这个设置任何时候都可以调整,无论在 extended sound 播放之前还是过程中。
限制:
要注意的是,设置全局音量是一个不同的特性,目前不支持。
另外 event sounds没有音量控制。这是iPhone API上 event sound的一个限制。
支持的音频格式
For the iPhone:
• Event sound应该是:
• 短小(只有几秒而已)
• 线性PCM或IMA4 (IMA/ADPCM) 格式
• 打包在一个 .caf 或 .aif 文件里
• 为了更好品质的event sound,可以使用16位,小顶,压缩 Core Audio Format (.caf) 里的线性PCM音频数据。在mac os x上使用 afconvert命令:
/usr/bin/afconvert -f caff -d LEI16 {INPUT}{OUTPUT}
• 为了让event sound文件更加紧凑,可使用 IMA4格式:
/usr/bin/afconvert -f caff -d ima4 {INPUT}{OUTPUT}
• 如果是更长的音频,可用 media.playSound() 播放.mp3文件
Android: 声音文件名限制
Android机的文件名不能用数字开头。
在Android上,文件名相同但扩展名不同的文件在编译期,被映射为同一个资源名称。现在这个不优雅的错误,会携带一个连接错误:( corona.get)message。唯一的解决办法,就是修改文件名。例如,AudioPlayer范例app使用一个命名方案,简单的把扩展名合并到文件名中:
• note2_aac.aac
• note2_aif.aif
• note2_caf.caf
• note2_mp3.mp3
• note2_ogg.ogg
Audio Recording
Corona包括录音和音频调节的API(比如可以建立一个吉他调引器的应用)
recording = media.newRecording( [file] )
初始化录音机,不管是不是带file参数。如果没有file参数,就不保存到文件。如果有则写入一个文件,文件格式取决于扩展名。然而,不同的平台支持不同的格式。Apple实现支持raw,aif,aac和mp3。儿android实现支持raw和3gp。这些编码类型,还没有经过仔细的测试。
recording:startRecording()recording:stopRecording()
开始和停止录音。
result = recording:isRecording()
如果正在录音就返回true,否则false。
recording:setSampleRate()rate = recording:getSampleRate()
获取/设置录音的采样率。默认是44100。注意,不是所有的平台都支持所有的采样率。有效的采样率有8000,11025,16000,22050,44100。你必须在调用调用 startTuner() 之前调用 setSampleRate()。音乐类的应用通常都想要有一个更高的采样率。然而实际硬件可能会限制它的能力。
音频调节器
recording:startTuner()
启动调节特性。应该在 startRecording 之前被调用(参看上面)。
freq = recording:getTunerFrequency()
返回最后一次计算的Hz频率。只有如果调节器开启,才可以工作。
recording:stopTuner()
停止调节器模块。
volume = recording:getTunerVolume()
获取最后计算的音量数,这个值是 在当前音频缓冲中把取样值缩放到[-1..1]的范围内,产生的样本值的均方。为了获得一个更有意义的取值范围,可以对其做log变化,比如 10*math.log( volume )
注意:
• 调节器操作独立于渲染器。所以调节值变化后无法得到提醒,你只能在 enterFrame事件里轮询调节器。在你调节器的UI设计里,你可能希望忽略低于某个值,或关注它的精确性。
• 包含Google’s Android SDK的模拟器有点慢,所以调节器的实时处理算法在其上工作的并不好,而且模拟器内部缓冲区可能会溢出。所以我们建议你在实际的android设备上测试。