迅速。 AVPlayer。歌曲播放完毕后如何追踪?

时间:2015-01-06 19:19:53

标签: ios swift avplayer

当歌曲在Swift中播放AVPlayer时,用什么东方方式跟踪?

当avplayer完成播放时是否有任何函数被调用,或者我应该将计时器与avplayer类引用结合起来?

8 个答案:

答案 0 :(得分:53)

这样的工作:

func play(url: NSURL) {
    let item = AVPlayerItem(URL: url)

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

    let player = AVPlayer(playerItem: item)
    player.play()
}

func playerDidFinishPlaying(note: NSNotification) {
    // Your code here
}

当你完成(或deinit)时,不要忘记删除观察者!

答案 1 :(得分:12)

您需要创建一个实现AVAudioPlayerDelegate协议的对象,并将其用作AVAudioPlayer对象的委托。然后将它们链接在一起,例如:

audioPlayer = try! AVAudioPlayer(contentsOf: audioFileUrl)
audioPlayer.delegate = self

委托可以实现响应某些事件的方法。当音频播放完毕时,这个会触发:

func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
    // ...
}

答案 2 :(得分:7)

Swift 3的另一个版本

NotificationCenter.default.addObserver(self, selector: #selector(self.playerDidFinishPlaying(sender:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: item)

func playerDidFinishPlaying(sender: Notification) {

    // Do Something
}

答案 3 :(得分:7)

对于Swift 4.2

func play(url: URL) {
    let item = AVPlayerItem(url: url)
    NotificationCenter.default.addObserver(self, selector: #selector(self.playerDidFinishPlaying(sender:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: item)

    let player = AVPlayer(playerItem: item)
    player.play() 
}

@objc func playerDidFinishPlaying(sender: Notification) {
    // Your code here
}

答案 4 :(得分:3)

对于Swif3,您需要更改如下:

func play(url: NSURL) {
let item = AVPlayerItem(URL: url)
  NotificationCenter.default.addObserver(self,selector:Selector("playerDidFinishPlaying"), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: item)

let player = AVPlayer(playerItem: item)
player.play() 
}

func playerDidFinishPlaying() {
// Your code here
} 

答案 5 :(得分:2)

这里有一个更完整的解决方案:

import UIKit
import AVFoundation
import MediaPlayer


class ViewController: UIViewController,AVAudioPlayerDelegate {

    var player: AVAudioPlayer = AVAudioPlayer()

    @IBAction func play(_ sender: UIButton) {
        player.play()
        player.currentTime=14*60-10
        print(player.currentTime)
    }
    @IBAction func pause(_ sender: UIButton) {
        player.pause()
    }
    @IBAction func replay(_ sender: UIButton) {
        player.currentTime=0
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        do{
            let audioPath = Bundle.main.path(forResource: "elon", ofType: "mp3")
            player = try AVAudioPlayer(contentsOf: URL.init(fileURLWithPath: audioPath!))
            player.prepareToPlay()
            player.delegate = self
        }
        catch{
            print(error)
        }
    }

    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool){
        print(flag)
        print("here")
        if flag == true{

        }
    }


}

答案 6 :(得分:0)

import AVFoundation

var AVPlayerCustom:AVAudioPlayer = AVAudioPlayer()


class PlayerModule: NSObject, AVAudioPlayerDelegate {

    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        print("Finish")
    }

    func playWithData(data: Data, proc: Int) {
        //print(data)

        do {

            AVPlayerCustom = try AVAudioPlayer(data: data)

            AVPlayerCustom.delegate = self as! AVAudioPlayerDelegate

            AVPlayerCustom.prepareToPlay()
            AVPlayerCustom.play()


        }
        catch {
            print("error1")
        }
    }
}

答案 7 :(得分:0)

SwiftUI

在 SwiftUI 中,我无法使用 @objc 函数或委托。 @objc 公开的函数在结构中不起作用。一种方法是创建一个类或更简单的方法来使用 AVAudioPlayer 实例属性 isPlaying。 请参阅Apple documentation

这是我用来检查音频是否完成播放以相应地更新播放/暂停按钮的代码。首先,我将值保留在 @State 属性中:

    @State private var playing: Bool = false

然后在 onAppear 中,我使用预定的计时器来检查播放器是否仍在播放。无论如何,我需要计时器来更新音频的进度。

    .onAppear {
        [...]

        Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
                if !audioPlayer.isPlaying {
                    playing = false
                }
        }

所以播放/暂停按钮会在曲目播放完毕后自动更新

Button(action: {
            if audioPlayer.isPlaying {
                playing = false
                self.audioPlayer.pause()
            } else if !audioPlayer.isPlaying {
                playing = true
                self.audioPlayer.play()
            }
        }) {
            Image(systemName: playing ?
                    "pause.circle.fill" : "play.circle.fill")
                .resizable()
                .frame(width: 50, height: 50)
                .aspectRatio(contentMode: .fit)
        }