2015-04-01 102 views
28

我使用AVPlayer在Swift中播放本地視頻文件(mp4)。 有沒有人知道如何檢測視頻完成播放? 謝謝如何檢測AVPlayer視頻何時結束播放?

+0

ObjC示例,但你可以用相同的方式去:http:// stackoverflow。com/questions/6837002/no-avplayer-delegate-how-to-track-when-song-finished-playing-objective-c-iphon – kabarga

+0

爲什麼你不能接受下面的答案之一? – D4ttatraya

+0

因爲那些答案很糟糕,顯然有人一直在傳播錯誤信息 – Martian2049

回答

42

要得到AVPlayerItemDidPlayToEndTimeNotification您的對象需要是AVPlayerItem

要做到這一點,只需用你的AVPlayer

.currentItem財產現在,一旦視頻結束,你會得到一個通知!

見我的例子:

let videoPlayer = AVPlayer(URL: url)  

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

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

斯威夫特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") 
} 

不要忘記取出觀察你deinit

+0

你知道使用這種方法和使用AVPlayer方法'addPeriodicTimeObserver(TimeInterval:)'有什麼區別嗎? – MikeG

+0

addPeriodicTimeObeserver用於在時間間隔到期時要通知您。例如,如果您希望每0.5秒收到一次通知,您將創建一個0.5秒的CMTime,並且每0.5秒會調用一次回調。 – jstn

+0

這個addObserver在多次使用時會誘發內存泄漏嗎? – Martian2049

22

雨燕3.0

let videoPlayer = AVPlayer(URL: url) 

NotificationCenter.default.addObserver(self, selector:#selector(self.playerDidFinishPlaying(note:)),name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem) 

@objc func playerDidFinishPlaying(note: NSNotification){ 
     print("Video Finished") 
    } 
+1

但它說[myClass playerDidFinishPlaying:]:無法識別的選擇器發送到實例 –

+0

'#selector(playerDidFinishPlaying)' – djv

+0

這是否addObserver誘發多次使用內存泄漏? – Martian2049

2

雨燕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

對於SWIFT 3.0

這裏fullUrl'是視頻的網址,並確保有將在URL沒有空間,就應該替換「太空'與'%20',這樣的URL將工作文件。

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) 
    } 

在您的視圖控制器中添加下面給出的方法。

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

這個addObserver在多次使用時會誘發內存泄漏嗎? – Martian2049

4

對於SWIFT 3.0 這是工作的罰款

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

在斯威夫特3和RxSwift 3.5所有你需要做的是:

override func viewDidLoad() { 
    super.viewDidLoad() 

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

      //Your action 

     }).addDisposableTo(disposeBag) 
} 
0

我知道有很多這裏接受的答案...

Bu t,另一條路線可能是將邊界時間觀察者添加到AVPlayer。您必須獲得視頻的持續時間,您可以從player.currentItem中獲得視頻的持續時間,然後將其添加爲期望的時間範圍。

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

雨燕4.0

這一個爲我工作。感謝@Channel

private func playVideo(fileURL: String) { 

      // Create RUL object 
      let url = URL(string: fileURL) 

      // Create Player Item object 
      let playerItem: AVPlayerItem = AVPlayerItem(url: url!) 
      // Assign Item to Player 
      let player = AVPlayer(playerItem: playerItem) 

      // Prepare AVPlayerViewController 
      let videoPlayer = AVPlayerViewController() 
      // Assign Video to AVPlayerViewController 
      videoPlayer.player = player 

      NotificationCenter.default.addObserver(self, selector: #selector(myViewController.finishVideo), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil) 

      // Present the AVPlayerViewController 
      present(videoPlayer, animated: true, completion: { 
        // Play the Video 
        player.play() 
      }) 

    } 

    @objc func finishVideo() 
    { 
      print("Video Finished") 
    }