[英]Playing multiple audio files using AVAudioPlayer
我在主StoryBoard上创建了3个UIButton。
当我按下“ Button1”或“ Button2”时,每个播放音频文件(“播放器1”,“播放器2”。),并且在播放音频时,UIButton设置为selected
。
我希望“ Button3”可以连续实现多个功能。 这意味着当我按下“按钮3”时,应该先播放“玩家3”,然后再播放“玩家1”,然后再播放“玩家2”。
但是,当我按“ Button3”时,“播放器1”和“播放器2”同时播放,因为前一个播放没有延迟。
我发现设置AVAudioPlayer的委托或使用AVQueuePlayer可以解决问题,但是我发现很难进行更改。
fileprivate var player1:AVAudioPlayer?
fileprivate var player2:AVAudioPlayer?
fileprivate var player3:AVAudioPlayer?
@IBAction func pushButton1(sender: UIButton) {
audioPlayer1(url: url1)
}
@IBAction func pushButton2(sender: UIButton) {
audioPlayer2(url: url2)
}
@IBAction func pushButton3(_ sender: UIButton) {
audioPlayer3(url: url1, url2: url2, url3: url3)
}
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
if (player === player1) {
yourButton1.isSelected = false
} else if (player === player2) {
yourButton2.isSelected = false
} else if (player === player3) {
//"player 1" and "player 2" are played at same time
yourButton3.isSelected = false
player1!.play()
yourButton1.isSelected = true
player2!.play()
yourButton2.isSelected = false
}
}
func audioPlayer1(url: URL) {
do {
try player1 = AVAudioPlayer(contentsOf:url)
player1!.play()
yourButton1.isSelected = true
player1!.delegate = self
} catch {
print(error)
}
}
func audioPlayer2(url: URL) {
do {
try player2 = AVAudioPlayer(contentsOf:url)
player2!.play()
yourButton2.isSelected = true
player2!.delegate = self
} catch {
print(error)
}
}
func audioPlayer3(url: URL, url2: URL, url3: URL) {
do {
try player3 = AVAudioPlayer(contentsOf:url3)
try player1 = AVAudioPlayer(contentsOf: url1)
try player2 = AVAudioPlayer(contentsOf: url2)
player3!.play()
yourButton3.isSelected = true
player3!.delegate = self
player1!.delegate = self
} catch {
print(error)
}
}
}
更改代码
var queue = AVQueuePlayer()
var items = [AVPlayerItem]()
override func viewDidLoad() {
super.viewDidLoad()
player1?.delegate = self
player2?.delegate = self
player3?.delegate = self
let asset1 = AVPlayerItem(url: url1)
let asset2 = AVPlayerItem(url: url2)
let asset3 = AVPlayerItem(url: url3)
let asset4 = AVPlayerItem(url: url4)
items = [asset1, asset2, asset3, asset4]
queue = AVQueuePlayer(items: items)
for item in queue.items() {
NotificationCenter.default.addObserver(self, selector: #selector(playerItemDidReachEnd(notification:)), name: .AVPlayerItemDidPlayToEndTime, object: item)
}
}
@IBAction func pushButton3(_ sender: UIButton) {
//audioPlayer3(url: url1, url2: url2)
sender.isSelected = true
queue.play()
}
func playerItemDidReachEnd(notification: NSNotification) {
if notification.object as? AVPlayerItem == items[0] {
yourButton3.isSelected = false
yourButton1.isSelected = true
}
if notification.object as? AVPlayerItem == items[1] {
yourButton1.isSelected = false
yourButton2.isSelected = true
}
if notification.object as? AVPlayerItem == items[2] {
yourButton2.isSelected = false
yourButton4.isSelected = true
//yourButton1.isSelected = true
}
if notification.object as? AVPlayerItem == items[3] {
yourButton4.isSelected = false
print("item 3")
}
所以基本上:
1:仅添加一个播放器,删除其余的播放器。
2:使用要播放的对象创建一个 NSMutableArray
。
3:根据按下的按钮,可以重新排列NSMutableArray
对象以根据需要设置正确的顺序。 (如果要简化,只需重新创建数组即可)并开始播放数组中的firstObject
(url),并将其相应地添加到播放器中。
4:播放器播放完毕后,您可以开始播放下一个对象,方法与上述相同,从NSMutableArray
将其添加到播放器中。
执行上述步骤将避免让多个玩家同时玩,以及其他好处(例如避免同时加载多个URL等)
您可能需要一些变量来检查currentPlayingObject以确定下一个对象(可能是int
,并检查是否没有尝试从数组中加载新项目(如果它是最后一个正在播放的项目),以避免在访问objectAtIndex时崩溃那不存在。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.