注意:在将标题标记为重复项之前,请仔细阅读标题(和问题)。问题是关于AVAudioPlayer
而不是AVPlayer
。
根据AVAudioPlayer
的文档
open func play() -> Bool /* sound is played asynchronously. */
我需要在音频开始时准确地向用户显示一个弹出窗口。这不是我们打电话给play()
的时候。
有一个委托人呼叫,要求玩家停止游戏但不开始游戏:(。
我找不到关于如何确切知道音频何时开始的任何方法。有什么办法可以检查吗?
答案 0 :(得分:0)
我正面临着同样的问题,只是决定基于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
}
}