2017-02-19 5 views
0

Я создал 3 UIButtons на Main StoryBoard.Воспроизведение нескольких аудиофайлов с использованием AVAudioPlayer

Когда я нажимаю «Button1» или «Button2», каждый воспроизводит аудиофайл («игрок 1», «игрок 2».), И во время воспроизведения звука UIButton установлен в selected.

Я хотел бы, чтобы «Button3» реализовал несколько функций в строке. Это означает, что когда я нажимаю «Button 3», сначала следует играть «игрок 3», после этого «игрок 1» и после этого «игрок 2».

Однако, когда я нажимаю «Button3», «проигрыватель 1» и «проигрыватель 2» воспроизводятся одновременно с задержкой для предыдущего.

Я выяснил, что установка делегата AVAudioPlayer или использование AVQueuePlayer решит проблему, но мне трудно внести изменения.

I created image to make it easier to understand

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") 
     } 
+0

Отметьте этот ответ, чтобы получить лучшую идею: http://stackoverflow.com/a/42273177/4033273 –

+0

@MoinShirazi Использование AppDelegate не предназначено для использования в таких вещах, это против лучших практик. –

ответ

1

EDIT: This is the method для AVAudioPlayer

Так в основном:

1: Добавьте только одного игрока, удалите остальных игроков.

2:Create anNSMutableArray с вашими объектами, которые вы хотите играть.

3: В зависимости от того, какая кнопка нажата, вы можете перенастроить объекты NSMutableArray, чтобы установить правильный порядок по своему усмотрению. (Просто воссоздайте массив, если вы хотите сделать это легко) И начните играть firstObject (url) в массиве, добавив его соответственно вашему плееру.

4: Когда игрок закончил игру, вы можете начать воспроизведение следующего объекта, добавив его к плееру с NSMutableArray так же, как это было сделано выше.

После этих шагов будет избежать того, несколько игроков играют Simultaniously, вместе с другими преимуществами (например, избежать загрузки нескольких URL, в то же время и т.д.)

Вы, возможно, потребуется некоторые переменные, чтобы проверить currentPlayingObject, чтобы определить, какой из них является следующая , возможно, int и убедитесь, что вы не пытаетесь загрузить новый элемент из массива, если это последний элемент, чтобы избежать сбоя при доступе к объекту ObjectAtIndex, который не существует.

+0

umm Я переписал код с наблюдателем уведомления, но я получаю несколько ошибок ... Не могли бы вы показать мне, как он должен выглядеть с кодом выше?Мне также трудно понять, что вы подразумеваете под «изменением элемента/URL-адреса одного и того же игрока и начала его играть»/ – rebecca87

+0

@ rebecca87 Извините, моя ошибка, я принял ваш плеер за AVPlayer. Я обновил ответ. К сожалению, я не кодирую в Swift, но это должно быть очень напряженным, если вы будете следовать тому, что я написал. –

+0

Спасибо за помощь. Я попытаюсь переписать мой код.! – rebecca87