2015-04-01 50 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") 
    }