2015-04-01 23 views
28

Tôi đang sử dụng AVPlayer để phát tệp video cục bộ (mp4) trong Swift. Có ai biết cách phát hiện khi video kết thúc bằng cách phát không? Cảm ơnCách phát hiện khi nào video AVPlayer kết thúc phát?

+0

Ví dụ ObjC nhưng bạn có thể làm theo cùng một cách: http: // stackoverflow.com/questions/6837002/no-avplayer-delegate-how-to-track-khi-song-thành-chơi-mục tiêu-c-iphon – kabarga

+0

Tại sao bạn không thể chấp nhận một trong các câu trả lời dưới đây? – D4ttatraya

+0

bởi vì những câu trả lời hút, dường như ai đó đã lây lan misinformations – Martian2049

Trả lời

42

Để nhận được AVPlayerItemDidPlayToEndTimeNotification đối tượng của bạn cần phải là AVPlayerItem.

Để làm như vậy, chỉ cần sử dụng .currentItem tài sản trên của bạn AVPlayer

Bây giờ bạn sẽ nhận được thông báo khi video kết thúc!

Xem ví dụ của tôi:

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

Đừng quên để loại bỏ các Observer tại của bạn deinit

+0

bạn có biết sự khác biệt giữa việc sử dụng phương pháp này và sử dụng phương pháp AVPlayer 'addPeriodicTimeObserver (TimeInterval:)'? – MikeG

+0

addPeriodicTimeObeserver được sử dụng khi bạn muốn được thông báo khi khoảng thời gian tăng. ví dụ, nếu bạn muốn được thông báo sau mỗi 0,5 giây, bạn sẽ tạo một CMTime là 0,5 giây và cuộc gọi lại sẽ được gọi mỗi 0.5 giây. – jstn

+0

addObserver này có gây ra rò rỉ bộ nhớ khi được sử dụng nhiều lần không? – Martian2049

22

Swift 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

Nhưng nó nói [myClass playerDidFinishPlaying:]: unrecognized chọn gửi đến dụ –

+0

'#selector (playerDidFinishPlaying)' – djv

+0

addObserver này gây ra rò rỉ bộ nhớ khi sử dụng nhiều lần? – 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

Đối với SWIFT 3.0

Dưới đây fullurl 'là URL của video và chắc chắn rằng sẽ không có không gian trong URL, Bạn nên thay thế 'Space 'với'% 20 'sao cho URL đó sẽ hoạt động.

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

Thêm phương thức này dưới đây vào bộ điều khiển chế độ xem của bạn.

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

addObserver này có gây ra rò rỉ bộ nhớ khi được sử dụng nhiều lần không? – Martian2049

4

Đối với SWIFT 3.0 này đang làm việc tốt

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

Trong Swift 3 và RxSwift 3.5 tất cả các bạn phải làm là:

override func viewDidLoad() { 
    super.viewDidLoad() 

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

      //Your action 

     }).addDisposableTo(disposeBag) 
} 
0

Tôi biết có rất nhiều các câu trả lời được chấp nhận tại đây ...

Bu t, một tuyến đường khác có thể là thêm một người quan sát thời gian biên giới vào AVPlayer của bạn. Bạn sẽ phải có thời lượng của video mà bạn có thể nhận được từ số player.currentItem và sau đó thêm nó làm ranh giới thời gian mong muốn của bạn.

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

một này làm việc cho tôi. Nhờ @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") 
    } 
Các vấn đề liên quan