使用 AVAudioPlayer 播放多个音频文件
Posted
技术标签:
【中文标题】使用 AVAudioPlayer 播放多个音频文件【英文标题】:Playing multiple audio files using AVAudioPlayer 【发布时间】:2017-02-19 06:50:08 【问题描述】:我在 Main StoryBoard 上创建了 3 个 UIButton。
当我按下“Button1”或“Button2”时,每个都会播放一个音频文件(“player 1”,“player 2”。),当音频播放时,UIButton 设置为selected
。
我想让“Button3”连续实现多个功能。 这意味着当我按下“按钮 3”时,应该首先播放“玩家 3”,然后是“玩家 1”,然后是“玩家 2”。
但是,当我按下“Button3”时,“player 1”和“player 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")
【问题讨论】:
检查这个答案你会得到更好的主意:***.com/a/42273177/4033273 @MoinShirazi 使用 AppDelegate 不能用于此类事情,它违反了最佳实践。 【参考方案1】:编辑:This is the method 用于 AVAudioPlayer
所以基本上:
1:只添加一个玩家,移除其余玩家。
2: Create an NSMutableArray
与您想玩的对象。
3:根据按下的按钮,您可以重新排列NSMutableArray
对象以根据需要设置正确的顺序。 (如果你想让它变得简单,只需重新创建数组)并开始播放数组中的firstObject
(url),将它相应地添加到你的播放器中。
4:播放器完成播放后,您可以开始播放下一个对象,将其从NSMutableArray
添加到播放器,方法与上述相同。
遵循上述步骤将避免多个玩家同时玩,以及其他好处(例如避免同时加载多个 URL 等)
您可能需要一些变量来检查 currentPlayingObject 以确定哪个是下一个,可能是int
,并检查如果它是最后播放的项目,您不会尝试从数组中加载新项目,以避免在访问不存在的 objectAtIndex 时崩溃。
【讨论】:
嗯,我已经用通知观察者重写了代码,但是我收到了多个错误...你能告诉我上面的代码应该是什么样子吗?我也很难理解您所说的“更改同一个播放器的项目/网址并开始播放”/ @rebecca87 对不起,我错了,我把你的播放器误认为是 AVPlayer。我已经更新了答案。不幸的是,我没有用 Swift 编写代码,但如果你按照我写的内容进行操作,它应该非常简单。 感谢您的帮助。我会尝试重写我的代码。! NP,它应该非常简单干净,不那么混乱,我也添加了一个关于如何为你创建 NSMutableArray 的链接,(我认为它应该在新的 swift3 中工作) 谢谢,我会检查的:)以上是关于使用 AVAudioPlayer 播放多个音频文件的主要内容,如果未能解决你的问题,请参考以下文章