2017-02-03 10 views
3

Я создаю образец игрока для тестового проекта. Я создал NSNotification для вызова функции для воспроизведения следующей звуковой дорожки внутри массива. Проблема в том, что уведомление вызывает эту функцию примерно 8 раз подряд? Я понятия не имею, почему это происходит. Вот мой код и спасибо за помощь!NSNotification срабатывает более одного раза?

let player = AVPlayer() 

var urlPlayerItems = [String]() 

var currentTrack: Int = 0 



    override func viewWillAppear(_ animated: Bool) { 
     super.viewWillAppear(animated) 

     // Checks to see if player reached end 
     NotificationCenter.default.addObserver(self, 
                selector: #selector(PlayerViewController.autoplayNextTrack(notification:)), 
                name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, 
                object: player.currentItem) 

} 

    func playTrack() { 

     if urlPlayerItems.count > 0 { 
      let newMovieURL = URL(string: urlPlayerItems[currentTrack])! 
      asset = AVURLAsset(url: newMovieURL, options: nil) 

      player.play() 
     } 
    } 



    func autoplayNextTrack(notefication: NSNotification) { 
     if (currentTrack + 1) >= urlPlayerItems.count { 
      currentTrack = 0 
     } else { 
      currentTrack += 1 
     } 
     playTrack() 
    } 
+0

попробовать движущуюся addObserver в viewDidLoad или удалить его in viewWillDisappear –

+0

Я пробовал это и до сих пор не работает. Он по-прежнему вызван несколько раз, хотя, когда я удаляю код из autoplayNextTrack, и просто поставить оператор печати вызывает его один раз? – user7097242

+0

Также, когда я комментирую кластер playTrack() в autoplayNextTrack, он не вызывает его более одного раза – user7097242

ответ

3

Помимо того, что наблюдатель не должен быть установлен в несколько раз, я думаю, что вы должны сбросить игрока к нулю перед вызовом функции воспроизведения снова

func autoplayNextTrack(notefication: NSNotification) { 
    player.seekToTime(kCMTimeZero) 
    if (currentTrack + 1) >= urlPlayerItems.count { 
     currentTrack = 0 
    } else { 
     currentTrack += 1 
    } 

    playTrack() 
} 
+0

Полный образец кода с предложениями было бы здорово ... Я пробовал почти все, включая то, что вы только что упоминали, и не мог понять. Спасибо – user7097242

+0

Я только что обновил ответ. @ user7097242 – TheFuquan

+0

Я добавил строку, чтобы искать 0, и теперь это работает Я не понимаю, почему добавление это имеет значение? Не могли бы вы объяснить, потому что я полностью перешел на новое видео.Почему мне нужно искать 0? – user7097242

0

Если Вы добавите наблюдателей в методе viewDidAppear, вы должны убедиться, что вы только добавить их РАЗ. методы viewDidAppear будут вызваны несколько раз.

Простой способ только сделать BOOL и пометить его, когда вы добавили/удалили его.

EDIT: Кроме того, я не вижу способа, по которому вы удаляете наблюдателя в любом месте вашего кода, убедитесь, что вы удаляете его, когда вы хотите прекратить наблюдение.

Пример:

deinit { 
    NSNotificationCenter.defaultCenter().removeObserver(self) 
} 

или в методе viewWillDissapear.

+0

Я пробовал это и до сих пор не работает. Он по-прежнему вызван несколько раз, хотя, когда я удаляю код из autoplayNextTrack, и просто поставить оператор печати вызывает его один раз? – user7097242

+0

Похоже, что ваш трек не может быть воспроизведен для меня. –

+0

Проверьте мой обновленный ответ. Я не уверен, как вы используете всю свою настройку кода и как вы вызываете свои элементы. "if urlPlayerItems.count> 0 {" и т. д. Возможно, сохраните ссылку на свой AVPlayerItem как свойство и добавьте уведомление к фактическому элементу playerItem вместо добавления уведомления на player.currentItem поможет вам решить вашу проблему. Когда вы меняете параметры PlayerItems, вам нужно убедиться, что вы удалили существующие серверы уведомлений с игрового элемента CURRENT перед добавлением уведомлений в новый playerItem –

Смежные вопросы