swift。影音播放器。如何跟踪歌曲何时播放完毕?
swift. AVPlayer. How to track when song finished playing?
在 Swift 中使用 AVPlayer 播放完歌曲时最简单的跟踪方式是什么?
有没有avplayer播放结束时调用的函数,或者我应该把timer和avplayer结合起来class参考?
像这样的东西有效:
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
中)不要忘记移除观察者!
您需要创建一个实现 AVAudioPlayerDelegate
协议的对象,并将其用作 AVAudioPlayer
对象的委托。然后link把他们放在一起,例如:
audioPlayer = try! AVAudioPlayer(contentsOf: audioFileUrl)
audioPlayer.delegate = self
委托可以实现响应特定事件的方法。当音频播放完毕时触发:
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
// ...
}
对于 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
}
Swift3
的另一个版本
NotificationCenter.default.addObserver(self, selector: #selector(self.playerDidFinishPlaying(sender:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: item)
func playerDidFinishPlaying(sender: Notification) {
// Do Something
}
这里有一个更完整的解决方案:
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{
}
}
}
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")
}
}
}
对于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
}
SwiftUI
在 SwiftUI 中,我无法使用 @objc
函数或委托。
@objc
公开的函数在结构中不起作用。一种方法是创建一个 class 或更简单的使用 AVAudioPlayer
实例 属性 isPlaying
。
见 Apple documentation.
这是我用来检查音频是否播放完毕以相应地更新 play/pause 按钮的代码。首先,我将值保存在 @State
属性:
@State private var playing: Bool = false
然后在onAppear
我使用预定的计时器来检查玩家是否还在玩。反正我需要定时器来更新音频的进度。
.onAppear {
[...]
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
if !audioPlayer.isPlaying {
playing = false
}
}
因此 play/pause 按钮会在曲目播放完毕后自动更新
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)
}
在 Swift 中使用 AVPlayer 播放完歌曲时最简单的跟踪方式是什么?
有没有avplayer播放结束时调用的函数,或者我应该把timer和avplayer结合起来class参考?
像这样的东西有效:
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
中)不要忘记移除观察者!
您需要创建一个实现 AVAudioPlayerDelegate
协议的对象,并将其用作 AVAudioPlayer
对象的委托。然后link把他们放在一起,例如:
audioPlayer = try! AVAudioPlayer(contentsOf: audioFileUrl)
audioPlayer.delegate = self
委托可以实现响应特定事件的方法。当音频播放完毕时触发:
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
// ...
}
对于 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
}
Swift3
的另一个版本NotificationCenter.default.addObserver(self, selector: #selector(self.playerDidFinishPlaying(sender:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: item)
func playerDidFinishPlaying(sender: Notification) {
// Do Something
}
这里有一个更完整的解决方案:
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{
}
}
}
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")
}
}
}
对于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
}
SwiftUI
在 SwiftUI 中,我无法使用 @objc
函数或委托。
@objc
公开的函数在结构中不起作用。一种方法是创建一个 class 或更简单的使用 AVAudioPlayer
实例 属性 isPlaying
。
见 Apple documentation.
这是我用来检查音频是否播放完毕以相应地更新 play/pause 按钮的代码。首先,我将值保存在 @State
属性:
@State private var playing: Bool = false
然后在onAppear
我使用预定的计时器来检查玩家是否还在玩。反正我需要定时器来更新音频的进度。
.onAppear {
[...]
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
if !audioPlayer.isPlaying {
playing = false
}
}
因此 play/pause 按钮会在曲目播放完毕后自动更新
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)
}