概述
Soundable 是一个微小的库,它使用 AVFoundation
以简单易用的方式在 iOS 应用程序中管理声音播放。您可以播放单个音频、顺序播放和并行播放,所有操作都由 Soundable 库处理,并且当播放结束时,都将具有完成闭包。
待办事项
- 支持
AVAudioSession
以设置类别和管理音频中断。
需求
- iOS 9.0+
- Xcode 10.0+
- Swift 4.2+
安装
CocoaPods
将以下行添加到您的 Podfile
:
pod 'Soundable', '~> 1.0'
Carthage
将此行添加到您的 cartfile
github "ThXou/Soundable" ~> 1.0
然后按照官方文档添加框架到应用中添加框架到应用。
设置
在源文件中导入 Soundable
import Soundable
播放声音
单个声音
Soundable
提供多种播放声音的方式。第一种是通过创建一个 Sound
对象
let sound = Sound(fileName: "guitar-chord.wav")
sound.play()
这将播放位于应用程序主包中的guitar-chord.wav
音轨。如果您应用程序中有多个包,请使用fileName:bundle:
函数创建声音。如果您有一个URL
对象,可以使用
let sound = Sound(url: url)
sound.play()
第二种是使用 Soundable
类的函数
Soundable.play(fileName: "guitar-chord.wav")
对于懒惰的人,只需将文件名放入一个 String
对象中,然后直接调用 tryToPlay
"guitar-chord.wav".tryToPlay()
这是因为库中包含了一个简单的 String
分类,它会尝试播放位于应用程序主包中将指定名称的音频文件。
如果您有一个URL
对象并且也很懒惰,同样可以使用它这样使用
url.tryToPlay()
所有这些函数都有其对应的完成闭包,如果过程中发生错误,它会传递一个 Error
对象
sound.play { error in
if let error = error {
print("error: \(error.localizedDescription)")
}
}
多个声音
并行播放
要并行播放音频,只需调用所有想要并行播放的音频中的play
函数,当音频播放完成后,所有的完成闭包都会被调用。
顺序播放
Soundable
支持顺序播放音频,对于单个声音,有多个方式可以顺序播放音频。第一种(据我观察)是最佳方式。
let sound1 = Sound(fileName: "guitar-chord.wav")
let sound2 = Sound(fileName: "rain.mp3")
let sound3 = Sound(fileName: "water-stream.wav")
let sounds = [sound1, sound2, sound3]
sounds.play()
或者:
[sound1, sound2, sound3].play()
能否播放Sound
对象数组?是的。这是因为库中内嵌了一个简单的Sequence
扩展,它只接受Sound
对象进行播放。
第二种方法是使用Soundable
类函数。
Soundable.play(sounds: [sound1, sound2, sound3])
第三种方法是使用SoundsQueue
对象创建声音队列。
let soundsQueue = SoundsQueue(sounds: [sound1, sound2, sound3])
soundsQueue.play()
至于单个声音,在所有声音序列播放完毕后,也会有一个完成闭包。
停止播放声音
要停止播放和队列,就像播放它们一样简单。如果您使用了Sound
对象创建声音,可以这样操作
let sound = Sound(fileName: "guitar-chord.wav")
sound.play()
...
sound.stop()
您可以使用Soundable
类函数停止特定的声音。
Soundable.stop(sound)
您可以使用Soundable
停止所有当前正在播放的声音,包括声音队列。
Soundable.stopAll()
或者您可以选择性地停止特定组中的所有声音。我将在下一节解释“组”的概念。
停止播放声音或声音队列不会触发完成闭包。
声音组
声音组是一项功能,允许您将声音分组到同一字符串键下,然后您可以停止该组中的所有声音,并继续播放其余部分。
默认情况下,所有声音和声音队列都在SoundableKey.DefaultGroupKey
键下创建。这样,您可以按以下方式将游戏声音分组在"game_sounds"键下,然后仅停止这些声音
Soundable.stopAll(for: "game_sounds")
其余的所有声音将继续播放,直到曲目或队列的末尾。
您可以在每个play
函数中设置声音所属的组,通过设置groupKey
参数。例如,在创建Sound
对象时
let sound = Sound(fileName: "sprite-walk.wav")
sound.play(groupKey: "game_sounds") { error in
// Handle error if any
}
静音声音
如果您不想完全停止声音,但只想静音所有正在播放的声音(即将音量设置为0.0),则可以使用Soundable
静音函数
// To mute
Soundable.muteAll()
Soundable.muteAll(for: "game_sounds")
// To unmute
Soundable.unmuteAll()
Soundable.unmuteAll(for: "game_sounds")
或者,您也可以静音/取消静音单个声音和队列
sound.mute()
sound.unmute()
soundsQueue.mute()
soundsQueue.unmute()
甚至通过声音和队列的isMuted
属性检查静音状态。
如果在静音状态下声音或队列已完成,则仍会调用完成闭包,并将声音和队列的静音状态恢复(即音量再次变为零)。
循环声音
通过在每个play
调用中设置loopsCount
参数来循环播放声音和声音队列,就像使用groupKey
一样
let sound = Sound(fileName: "sprite-walk.wav")
sound.play(groupKey: "game_sounds", loopsCount: 2) { error in
// Handle error if any
}
在触发完成闭包之前,声音或声音队列将播放总共loopsCount + 1
次。
禁用声音
您可以通过设置Soundable
类的soundEnabled
属性来启用/禁用所有当前正在播放的声音和声音队列
Soundable.soundEnabled = false
如果禁用,它将停止所有正在播放的声音和声音队列,并在尝试使用库播放声音时返回错误。禁用声音系统不会触发完成闭包。
鸣谢
代码示例中的声音已从FreeSound数据库下载(https://freesound.org)。