2016-12-21 2 views
0

Я работаю над реализацией видеопроигрывателя в Swift, который обнаружит, что видео перестало играть, а затем воспроизвести второй. Когда второй перестает играть, первое видео должно воспроизводиться снова.Использование NotificationCenter для чередования файлов видео в AVPlayer

Вот где я создал плеер, активы, и игрок пунктов:

//Create URLs 
    let movieOneURL: URL = URL(fileURLWithPath: movieOnePath) 
    let movieTwoURL: URL = URL(fileURLWithPath: movieTwoPath) 

    //Create Assets 
    let assetOne = AVAsset(url: movieOneURL) 
    let assetTwo = AVAsset(url: movieTwoURL) 

    //Create Player Items 
    avPlayerItemOne = AVPlayerItem(asset: assetOne) 
    avPlayerItemTwo = AVPlayerItem(asset: assetTwo) 

    avplayer = AVPlayer(playerItem: avPlayerItemOne) 
    let avPlayerLayer = AVPlayerLayer(player: avplayer) 
    avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 
    avPlayerLayer.frame = UIScreen.main.bounds 
    movieView.layer.addSublayer(avPlayerLayer) 

    //Config player 
    avplayer .seek(to: kCMTimeZero) 
    avplayer.volume = 0.0 

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

NotificationCenter.default.addObserver(self, selector: #selector(self.playerItemDidReachEnd), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: avplayer.currentItem) 

... который называет этот селектор:

func playerItemDidReachEnd(_ notification: Notification) { 
//  avplayer.seek(to: kCMTimeZero) 
     changePlayerAsset() 
//  avplayer.play() 
    } 

... который будет переключаться из актива:

func changePlayerAsset(){ 
    if avplayer.currentItem == avPlayerItemOne { 
     avplayer.replaceCurrentItem(with: avPlayerItemTwo) 
     avplayer.play() 

    } else if avplayer.currentItem == avPlayerItemTwo { 
     avplayer.replaceCurrentItem(with: avPlayerItemOne) 
     avplayer.play() 
    } 
} 

Это работает в первый раз - когда первый фильм закончился, следующий начнет играть.

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

Кто-нибудь есть идея, почему это было бы в случае

ответ

0

Причины вашего обработчика уведомлений не вызывались для второго элемента является этим битом, в конце, где вы зарегистрировать обработчик уведомления: object: avplayer.currentItem. Обработчик получает один раз, когда , что предмет заканчивает игру, но затем, когда следующий элемент заканчивается, уведомление отправляется с другим object - другим элементом, который не соответствует тому, что вы зарегистрировали, и поэтому ваш обработчик не работает Не получится. Если вы измените object на nil, когда вы зарегистрируете обработчик, он будет вызван, когда любой пункт заканчивается, что ближе к тому, что вы после.

Это не отличный способ сделать то, что вы хотите - вручную поменять местами, вероятно, будет стоить и задерживать загрузку каждого предмета каждый раз, когда он собирается играть. Вам будет намного лучше использовать встроенные функции для воспроизведения видео в последовательности и их циклизации, а именно AVQueuePlayer и AVPlayerLooper. Пример использования обоих в ответе this question.

+0

Блестяще, спасибо! – narner

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