Reputation: 69
I have a screen with 3 different buttons. When Button1 is tapped an AVQueuePlayer is called. When Button2 or Button3 is tapped, an AVAudioPlayer is called.
The problem arises when Button1 is tapped (initiating the AVQueuePlayer) and then either Button2 or Button3 is tapped (initiating the AVAudioPlayer). The result is that that the audio file currently being played by the AVQueuePlayer and the audio file being played by the AVAudioPlayer play at the same time.
I`m looking for a way to either prevent Button2 or Button3 from being tapped on while the AVQueuePlayer is active, or, have the AVQueuePlayer stop playing if the user taps on either Button2 or Button3.
I found that Instead of using two Player,using only one Player will solve the problem, but I do not know how.
var queue = AVQueuePlayer()
var items = [AVPlayerItem]()
override func viewDidLoad() {
super.viewDidLoad()
let asset1 = AVPlayerItem(url: url1)
let asset2 = AVPlayerItem(url: url2)
let asset3 = AVPlayerItem(url: url3)
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 pushButton1(_ sender: UIButton) {
sender.isSelected = true
queue.play()
}
@IBAction func pushButton2(sender: UIButton) {
if self.lonelyPlayer == nil {
}else {
if (self.lonelyPlayer?.isPlaying)! {
self.lonelyPlayer?.stop()
}
}
audioPlayer(url: url1, buttonId: 1) }
@IBAction func pushButton3(sender: UIButton) {
if self.lonelyPlayer == nil {
}else {
if (self.lonelyPlayer?.isPlaying)! {
self.lonelyPlayer?.stop()
}
}
audioPlayer(url: url2, buttonId: 2)
}
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
if (self.currentPlayer == 1) {
yourButton2.isSelected = false
} else if (self.currentPlayer == 2) {
yourButton3.isSelected = false
}
}
func playerItemDidReachEnd(notification: NSNotification) {
if notification.object as? AVPlayerItem == items[0] {
yourButton1.isSelected = false
yourButton2.isSelected = true
}
if notification.object as? AVPlayerItem == items[1] {
yourButton2.isSelected = false
yourButton3.isSelected = true
}
func audioPlayer(url: URL, buttonId: Int) {
do {
try lonelyPlayer = AVAudioPlayer(contentsOf:url)
lonelyPlayer!.play()
lonelyPlayer!.delegate = self
yourButton2.isSelected = (buttonId == 1)
yourButton3.isSelected = (buttonId == 2)
currentPlayer = buttonId
} catch {
print(error)
}
}
Upvotes: 0
Views: 297
Reputation: 5223
var queue = AVQueuePlayer()
var items = [AVPlayerItem]()
var currentlyPlaying = 0
var isPlaying = false {
didSet{
checkButtons()
}
}
@IBOutlet weak var button1 : UIButton? //connect to button 1
@IBOutlet weak var button2 : UIButton? //connect to button 2
@IBOutlet weak var button3 : UIButton? //connect to button 3
override func viewDidLoad() {
super.viewDidLoad()
let asset1 = AVPlayerItem(url: url1)
let asset2 = AVPlayerItem(url: url2)
let asset3 = AVPlayerItem(url: url3)
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 pushButton1(_ sender: UIButton) {
self.currentlyPlaying = 1
self.isPlaying = true
sender.isSelected = true
queue.play()
}
@IBAction func pushButton2(sender: UIButton) {
self.currentlyPlaying = 2
self.isPlaying = true
if self.lonelyPlayer == nil {
}else {
if (self.lonelyPlayer?.isPlaying)! {
self.lonelyPlayer?.stop()
}
}
audioPlayer(url: url1, buttonId: 1)
}
@IBAction func pushButton3(sender: UIButton) {
self.currentlyPlaying = 3
self.isPlaying = true
if self.lonelyPlayer == nil {
}else {
if (self.lonelyPlayer?.isPlaying)! {
self.lonelyPlayer?.stop()
}
}
audioPlayer(url: url2, buttonId: 2)
}
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
if (self.currentPlayer == 1) {
yourButton2.isSelected = false
} else if (self.currentPlayer == 2) {
yourButton3.isSelected = false
}
self.isPlaying = false
}
func playerItemDidReachEnd(notification: NSNotification) {
if notification.object as? AVPlayerItem == items[0] {
yourButton1.isSelected = false
yourButton2.isSelected = true
}
if notification.object as? AVPlayerItem == items[1] {
yourButton2.isSelected = false
yourButton3.isSelected = true
}
self.isPlaying = false
)
func audioPlayer(url: URL, buttonId: Int) {
do {
try lonelyPlayer = AVAudioPlayer(contentsOf:url)
lonelyPlayer!.play()
lonelyPlayer!.delegate = self
yourButton2.isSelected = (buttonId == 1)
yourButton3.isSelected = (buttonId == 2)
currentPlayer = buttonId
} catch {
print(error)
}
}
func checkButtons() {
if isPlaying {
switch currentlyPlaying {
case 1:
button2.isEnabled = false
button3.isEnabled = false
case 2:
button1.isEnabled = false
button3.isEnabled = false
case 3:
button1.isEnabled = false
button2.isEnabled = false
default:
print("Something went wrong!")
}
} else {
button1.isEnabled = true
button2.isEnabled = true
button3.isEnabled = true
}
}
It disables the buttons when it is playing.
Note: this code hasn't been tested as I was writing it on the bus
EDIT: You can set the queue
as an optional, then use queue.pause
and then queue = nil
to stop it. Remember to reallocate it before using it again!
Upvotes: 0