Закройте AVPlayer, когда фильм будет завершен.

Я делаю простое приложение для iPad, чтобы воспроизводить фильм при нажатии кнопки. Фильм воспроизводится, и когда фильм закончится, я хочу закрыть AVPlayerView, чтобы он вернулся на главный экран. В настоящее время, когда видео заканчивается, он остается на последнем кадре. Мой ViewController.Swift на данный момент.

import UIKit
import AVKit
import AVFoundation

class ViewController: UIViewController {
//MARK : Properties 

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}
//MARK: Actions

@IBAction func playButton(_ sender: AnyObject) {

    let movieURL = Bundle.main.url(forResource: "ElephantSeals", withExtension: "mov")!
    let player = AVPlayer(url: movieURL as URL)

    let playerViewController = AVPlayerViewController()

    playerViewController.player = player

    self.present(playerViewController, animated: true) {
        playerViewController.player!.play()
        }
//    player.actionAtItemEnd = playerViewController.dismiss(animated: true)
}
}

Как видите, я думаю, что в actionAtItemEnd что-то есть, но я не уверен, как это реализовать. Спасибо.


person RoryM    schedule 18.10.2016    source источник


Ответы (5)


Это рабочий код в Swift 5.3 и iOS 14.2, попробуйте и дайте мне знать ... :)

import UIKit
import AVKit
import AVFoundation

class ViewController: UIViewController {
    
    let playerViewController = AVPlayerViewController()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
    @IBAction func playButton(_ sender: AnyObject) {
        
        let movieURL = Bundle.main.url(forResource: "ElephantSeals", withExtension: "mp4")!
        let player = AVPlayer(url: movieURL as URL)
        
        playerViewController.player = player
        NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: playerViewController.player?.currentItem)
        
        self.present(playerViewController, animated: true) {
            self.playerViewController.player!.play()
        }
    }
    
    
    @objc func playerDidFinishPlaying(note: NSNotification) {
        self.playerViewController.dismiss(animated: true)
    }
}

Вы можете скачать образец проекта для этого отсюда https://github.com/deepakiosdev/AVPlayerViewControllerDemo

person Dipak    schedule 19.10.2016
comment
Большое спасибо, очень ясно понять. Это сработало для меня! - person RoryM; 20.10.2016
comment
Когда проигрыватель заканчивает воспроизведение, текущее время не устанавливается на ноль, если пользователь попытается воспроизвести видео снова, оно начнется в конце. В вызове playerDidFinishPlaying seek (to: CMTime (секунды: 0,0, предпочтительныйTimescale: 1) в player.currentItem. Кроме того, уведомление .AVPlayerItemDidPlayToEndTime содержит предупреждение Это уведомление может быть отправлено в другом потоке, чем тот, в котором наблюдатель был Таким образом, отклонение AVPlayerViewController должно выполняться в основном потоке. - person Leon; 18.02.2018

Swift 4

let playerController = AVPlayerViewController()

private func playVideo() {
    guard let path = Bundle.main.path(forResource: "p810", ofType:"mp4") else {
        debugPrint("video.m4v not found")
        return
    }
    let player = AVPlayer(url: URL(fileURLWithPath: path))
    playerController.player = player
    NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: playerController.player?.currentItem)

    present(playerController, animated: true) {
        player.play()
    }
}

@objc func playerDidFinishPlaying(note: NSNotification) {
    playerController.dismiss(animated: true, completion: nil)
}
person Ahmed Safadi    schedule 17.05.2018

вот объективный код c

[[NSNotificationCenter defaultCenter] addObserver:self 
selector:@selector(nextVideo:)  name:AVPlayerItemDidPlayToEndTimeNotification object:playerViewController.player.currentItem];
person Trần Thị Diệu My    schedule 23.03.2018

Это можно сделать с помощью NSNotificationCenter.

 NotificationCenter.default.addObserver(self, selector: #selector(ViewController.playerDidFinishPlaying), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object:  videoPlayer!.currentItem)

@objc func playerDidFinishPlaying(note: NSNotification) {
    // here you can do your dismiss controller logic
    AVPlayerViewController.dismiss(animated: true)
    print("Video Finished")
}
person KKRocks    schedule 18.10.2016
comment
Xcode сообщил мне две вещи в первой строке этого кода: NSNotificationCenter был переименован в NotificationCenter. - person RoryM; 19.10.2016

Вызовите AVPlayerViewControllerDelegate.

В viewDidLoad инициализируйте делегат и реализуйте этот метод

func playerViewControllerDidStopPictureInPicture(AVPlayerViewController) {
      AVPlayerViewController.dismiss(animated: true)
}

https://developer.apple.com/reference/avkit/avplayerviewcontrollerdelegate

person Sofeda    schedule 18.10.2016
comment
Этот метод не вызывается, когда воспроизведение видео завершается в обычном режиме. - person Leon; 18.02.2018