如何在 AVAudioPlayer 开始播放音频时准确获取通知?
Posted
技术标签:
【中文标题】如何在 AVAudioPlayer 开始播放音频时准确获取通知?【英文标题】:How to get notification exactly when AVAudioPlayer starts playing audio? 【发布时间】:2019-05-07 09:49:45 【问题描述】:注意:在将其标记为重复之前,请仔细阅读标题(和问题)。问题是关于AVAudioPlayer
而不是AVPlayer
。
所以根据AVAudioPlayer
的文档
open func play() -> Bool /* sound is played asynchronously. */
我需要在音频开始时准确地向用户显示一个弹出窗口。这不是我们打电话给play()
的时候。
当播放器停止播放但没有开始播放时,有一个委托调用:(。
我找不到任何方法来准确知道音频何时开始。有什么方法可以检查吗?
【问题讨论】:
if self.avPlayer?.currentItem?.status == AVPlayerItem.Status.readyToPlay if (self.player?.currentItem?.isPlaybackLikelyToKeepUp) == true // 你可以在这里管理 @Mr.Ahtazaz 请仔细阅读标题。它不是 AVPlayer,它是 AVAudioPlayer。 @Sh_KhanAVPlayer
和 AVAudioPlayer
是两个不相关的类
@iur 您可以先尝试将观察者放在属性上,例如 currentTime
@mag_zbc 我也考虑过。在文档中有一个关于playing
属性Important. Do not poll this property to determine when playback has completed, instead implement the specified delegate method.
的注释,所以我不确定我们是否可以使用它来检查播放器是否开始播放。
【参考方案1】:
我也面临同样的问题,只是决定创建一个基于 AVPlayer 的新类:
import AVFoundation
import UIKit
class AudioManager
private init()
public static let shared = AudioManager()
var player: AVPlayer?
var item: AVPlayerItem?
var layer: AVPlayerLayer?
var currentUrl: URL?
var pauseTime: CMTime?
var endOfTrackObserver: Any?
func startPlayContentOf(url: URL?)
NotificationCenter.default.addObserver(self,
selector: #selector(self.playerItemDidReachEnd(notification:)),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: self.player?.currentItem)
guard let newAudioUrl = url else return
let newAudioItem = AVPlayerItem(url: newAudioUrl)
if let currentUrl = self.currentUrl, currentUrl == newAudioUrl
//same track
if let playing = self.player?.isPlaying, playing == true
self.pauseTime = self.player?.currentTime()
self.pause()
else
self.player = AVPlayer(playerItem: newAudioItem)
self.player?.volume = 3
self.player?.seek(to: self.pauseTime ?? CMTime.zero)
self.layer = AVPlayerLayer(player: self.player)
self.layer?.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
self.layer?.backgroundColor = UIColor.clear.cgColor
guard let layer = self.layer else return
UIApplication.shared.keyWindow?.rootViewController?.view.layer.insertSublayer(layer, at: 0)
self.play()
else
//new track
self.pauseTime = nil
self.pause()
self.player = AVPlayer(playerItem: newAudioItem)
self.player?.volume = 3
self.layer = AVPlayerLayer(player: self.player)
self.layer?.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
self.layer?.backgroundColor = UIColor.clear.cgColor
guard let layer = self.layer else return
UIApplication.shared.keyWindow?.rootViewController?.view.layer.insertSublayer(layer, at: 0)
self.play()
self.currentUrl = newAudioUrl
func playOrPause()
guard self.player != nil else return
if self.player!.isPlaying
self.player!.pause()
else
self.player?.replaceCurrentItem(with: self.item)
self.player!.play()
func pause()
guard self.player != nil else return
self.player!.pause()
func play()
guard self.player != nil else return
self.player!.play()
@objc func playerItemDidReachEnd(notification: Notification)
self.pauseTime = nil
【讨论】:
以上是关于如何在 AVAudioPlayer 开始播放音频时准确获取通知?的主要内容,如果未能解决你的问题,请参考以下文章