Swift - 系统声音服务的使用(播放声音,提醒,震动)
(本文代码已升级至Swift4)
1,系统声音服务介绍:
(2)提醒
(3)振动
4,声音或提醒播放完毕后的回调函数
默认情况下每触发一次声音提醒,系统就会执行一次。不管当前是否有其他的声音提醒未播放完毕。这样如果提醒声音时间比较长,在短时间内多次触发,那么就会造成重音(多个声音叠加在一起)。
我们可以设置个状态变量,播放前先根据它来判断是否要播放。同时使用 AudioServicesAddSystemSoundCompletion() 函数添加个声音播放完毕的回调。在开始播放、播放完毕中修改这个状态变量即可。
1,系统声音服务介绍:
系统声音服务提供了一个 Api,用于播放不超过 30 秒的声音。它支持的文件格式有限,具体的说只有 CAF、AIF 和使用 PCM 或 IMA/ADPCM 数据的 WAV 文件。
但此函数没有提供操作声音和控制音量的功能,因此如果是要为多媒体或游戏创建专门声音,就不要使用系统声音服务。

2,系统声音服务支持如下三种类型:
(1)声音:立刻播放一个简单的声音文件。如果手机静音,则用户什么也听不见。
(2)提醒:播放一个声音文件,如果手机设为静音或震动,则通过震动提醒用户。
(3)震动:震动手机,而不考虑其他设置。
3,使用样例(首先类中要引入AudioToolbox)
import AudioToolbox(1)声音播放
@IBAction func systemSound(_ sender: Any) { //建立的SystemSoundID对象 var soundID:SystemSoundID = 0 //获取声音地址 let path = Bundle.main.path(forResource: "msg", ofType: "wav") //地址转换 let baseURL = NSURL(fileURLWithPath: path!) //赋值 AudioServicesCreateSystemSoundID(baseURL, &soundID) //播放声音 AudioServicesPlaySystemSound(soundID) }
(2)提醒
@IBAction func systemAlert(_ sender: Any) { //建立的SystemSoundID对象 var soundID:SystemSoundID = 0 //获取声音地址 let path = Bundle.main.path(forResource: "msg", ofType: "wav") //地址转换 let baseURL = NSURL(fileURLWithPath: path!) //赋值 AudioServicesCreateSystemSoundID(baseURL, &soundID) //提醒(同上面唯一的一个区别) AudioServicesPlayAlertSound(soundID) }
(3)振动
@IBAction func systemVibration(sender: AnyObject) { //建立的SystemSoundID对象 let soundID = SystemSoundID(kSystemSoundID_Vibrate) //振动 AudioServicesPlaySystemSound(soundID) }
4,声音或提醒播放完毕后的回调函数
默认情况下每触发一次声音提醒,系统就会执行一次。不管当前是否有其他的声音提醒未播放完毕。这样如果提醒声音时间比较长,在短时间内多次触发,那么就会造成重音(多个声音叠加在一起)。
我们可以设置个状态变量,播放前先根据它来判断是否要播放。同时使用 AudioServicesAddSystemSoundCompletion() 函数添加个声音播放完毕的回调。在开始播放、播放完毕中修改这个状态变量即可。
import UIKit import AudioToolbox class ViewController: UIViewController { //表示当前是否在播放 var isPlaying = false override func viewDidLoad() { super.viewDidLoad() } @IBAction func btn(_ sender: Any) { if !isPlaying { //建立的SystemSoundID对象 var soundID:SystemSoundID = 0 //获取声音地址 let path = Bundle.main.path(forResource: "msg", ofType: "wav") //地址转换 let baseURL = NSURL(fileURLWithPath: path!) //赋值 AudioServicesCreateSystemSoundID(baseURL, &soundID) //添加音频结束时的回调 let observer = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()) AudioServicesAddSystemSoundCompletion(soundID, nil, nil, { (soundID, inClientData) -> Void in let mySelf = Unmanaged<ViewController>.fromOpaque(inClientData!) .takeUnretainedValue() mySelf.audioServicesPlaySystemSoundCompleted(soundID: soundID) }, observer) //播放声音 AudioServicesPlaySystemSound(soundID) isPlaying = true } } //音频结束时的回调 func audioServicesPlaySystemSoundCompleted(soundID: SystemSoundID) { print("Completion") isPlaying = false AudioServicesRemoveSystemSoundCompletion(soundID) AudioServicesDisposeSystemSoundID(soundID) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } }
站长你好:
这一句始终报错,望指点迷津
AudioServicesAddSystemSoundCompletion(soundID, nil, nil, proc,
UnsafeMutablePointer(unsafeAddressOf(self)))
错误提示:
Cannot invoke initializer for type 'UnsafeMutablePointer<_>' with an argument list of type '(UnsafeRawPointer)'
站长,我想问下有没有播放字符串的框架啊(不传url传的是字符串,传什么播放什么)
謝謝站長花時間寫教學並且分享
感恩囉^^
模拟器有声音,真机没有声音是什么问题..
站长你好,如果不断的触发系统声音,提醒等播放按钮,会出现重音,怎么判断系统声音播放完毕呢?
AudioServicesCreateSystemSoundID(baseURL, &soundID)
soudID 有错误,求解
cannot convert value of type 'SystemSoundID'(aka 'Uint32'')
嗯,感谢站长回复。可能是我没有设置好。
WARNING: 998: Failure to setup sound, err = -50
上面是错误信息
下面是代码
button_Shake.addTarget(self, action: Selector("systemVibration"), forControlEvents: UIControlEvents.TouchUpInside)
func systemVibration() {
let soundID = SystemSoundID(kSystemSoundID_Vibrate)
AudioServicesPlaySystemSound(soundID)
}
直接写的。是不是在模拟器上不能运行啊,我在模拟器上运行的。
点震动报错
2015-12-13 12:41:45.239 test[2173:101795] -[test.Audio_1 systemVibration]: unrecognized selector sent to instance 0x7fabda522620
2015-12-13 12:41:45.245 test[2173:101795] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[test.Audio_1 systemVibration]: unrecognized selector sent to instance 0x7fabda522620'
*** First throw call stack:
很感谢