2015-04-01 6 views
28

Ich benutze AVPlayer zum Abspielen lokaler Videodatei (mp4) in Swift. Kann jemand erkennen, wenn das Video mit dem Abspielen fertig ist? DankWie erkennt man, wenn das AVPlayer-Video beendet wird?

+0

ObjC Beispiel, aber Sie können auf die gleiche Weise gehen: http: // stackoverflow.com/questions/6837002/no-avplayer-delegate-wie-zu-verfolgen-wenn-lied-fertig-spielen-objective-c-iphon – kabarga

+0

Warum können Sie nicht eine der Antworten unten akzeptieren? – D4ttatraya

+0

weil diese Antworten saugen, offenbar hat jemand Fehlinformationen verbreitet – Martian2049

Antwort

42

Um die AVPlayerItemDidPlayToEndTimeNotification Ihr Objekt muss ein AVPlayerItem sein.

Um dies zu tun, benutzen Sie einfach die .currentItem Eigentum auf Ihrer AVPlayer

Jetzt erhalten Sie eine Benachrichtigung erhalten, sobald das Video endet!

Siehe mein Beispiel:

let videoPlayer = AVPlayer(URL: url)  

NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerDidFinishPlaying:", 
     name: AVPlayerItemDidPlayToEndTimeNotification, object: videoPlayer.currentItem) 

func playerDidFinishPlaying(note: NSNotification) { 
    print("Video Finished") 
} 

Swift 3

let videoPlayer = AVPlayer(URL: url)  

NotificationCenter.default.addObserver(self, selector: Selector(("playerDidFinishPlaying:")), 
     name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: videoPlayer.currentItem) 

func playerDidFinishPlaying(note: NSNotification) { 
    print("Video Finished") 
} 

Vergessen Sie nicht, den Beobachter in Ihrem deinit

+0

Wissen Sie, was der Unterschied zwischen der Verwendung dieser Methode und der Verwendung der AVPlayer-Methode 'addPeriodicTimeObserver (TimeInterval:)'? – MikeG

+0

addPeriodicTimeObeserver wird verwendet, wenn Sie benachrichtigt werden möchten, wenn das Zeitintervall abgelaufen ist. Wenn Sie beispielsweise alle 0,5 Sekunden benachrichtigt werden möchten, erstellen Sie eine CMTime von 0,5 Sekunden, und der Rückruf wird alle 0,5 Sekunden aufgerufen. – jstn

+0

induziert dieser addObserver bei mehrfacher Verwendung ein Speicherleck? – Martian2049

22

Swift 3.0

012 zu entfernen
+1

Aber es sagt [myClass playerDidFinishPlaying:]: unerkannter Selektor an Instanz gesendet –

+0

'#selector (playerDidFinishPlaying)' – djv

+0

induziert dieser addObserver Speicherverlust, wenn mehrmals verwendet? – Martian2049

2

Swift 3,0

let videoPlayer = AVPlayer(URL: url) 
NotificationCenter.default.addObserver(self, selector:#selector(self.playerDidFinishPlaying(note:)),name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem) 

func playerDidFinishPlaying(note: NSNotification){ 
    //Called when player finished playing 
} 
1

Für SWIFT 3.0

Hier fullurl 'die URL des Videos und stellen Sie sicher, dass es keinen Raum in der URL sein, sollten Sie ersetzen ‚Space 'mit'% 20 ', so dass die URL-Datei funktioniert.

let videoURL = NSURL(string: fullUrl) 
    let player = AVPlayer(url: videoURL! as URL) 

    playerViewController.delegate = self 
    playerViewController.player = player 
    self.present(playerViewController, animated: false) { 

    self.playerViewController.player!.play() 

    NotificationCenter.default.addObserver(self, selector: #selector(yourViewControllerName.playerDidFinishPlaying), name: Notification.Name.AVPlayerItemDidPlayToEndTime, object: self.player?.currentItem) 
    } 

Fügen Sie diese unten angegebene Methode in Ihrem View-Controller hinzu.

func playerDidFinishPlaying(){  
print("Video Finished playing in style") 
} 
+0

induziert dieser addObserver bei mehrfacher Verwendung ein Speicherleck? – Martian2049

4

Für SWIFT 3.0 Dies funktioniert gut

class PlayVideoViewController: UIViewController { 
    override func viewDidLoad() { 
     super.viewDidLoad() 

     NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(PlayVideoViewController.finishVideo), name: NSNotification.Name.AVPlayerItemDidPlayToEndTimeNotification, object: nil) 
    } 

    func finishVideo() 
    { 
     print("Video Finished") 
    } 
} 
2

In Swift 3 und RxSwift 3.5 alles, was Sie tun müssen, ist:

override func viewDidLoad() { 
    super.viewDidLoad() 

    NotificationCenter.default.rx.notification(Notification.Name.AVPlayerItemDidPlayToEndTime) 
     .asObservable().subscribe(onNext: { [weak self] notification in 

      //Your action 

     }).addDisposableTo(disposeBag) 
} 
0

Ich weiß, dass es viele sind von akzeptierten Antworten hier ...

Bu t, könnte eine weitere Route darin bestehen, Ihrem AVPlayer einen Grenzzeitbeobachter hinzuzufügen. Sie müssten die Dauer des Videos haben, die Sie von Ihrem player.currentItem erhalten, und fügen Sie es dann als Ihre gewünschte Zeitgrenze hinzu.

fileprivate var videoEndObserver: Any? 

func addVideoEndObserver() { 
    guard let player = YOUR_VIDEO_PLAYER else { return } 

    // This is just in case you are loading a video from a URL. 
    guard let duration = player.currentItem?.duration, duration.value != 0 else { 
     DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: { [weak self] in 
      self?.addVideoEndObserver() 
     }) 

     return 
    } 

    let endTime = NSValue(time: duration - CMTimeMakeWithSeconds(0.1, duration.timescale)) 
    videoEndObserver = player.addBoundaryTimeObserver(forTimes: [endTime], queue: .main, using: { 
     self.removeVideoEndObserver() 

     // DO YOUR STUFF HERE... 
    }) 
} 

func removeVideoEndObserver() { 
    guard let observer = videoEndObserver else { return } 

    videoPlayer.player?.removeTimeObserver(observer) 
    videoEndObserver = nil 
} 
1

Swift 4,0

Dies funktioniert für mich. Dank @Channel