ios - 关闭音频播放?
问题描述
我AVPlayer
用来播放来自URL
. 一切正常,但我不知道如何在不同的地方停止当前的音频播放我ViewController
不想打电话player.pause()
,viewWillDisappear()
因为我想在特定情况下停止它,但我仍然想在应用程序处于非活动状态时的背景。
当应用程序处于非活动状态时,我在 Xcode 应用程序设置中为后台播放打开了这个
第二个问题:我可以改进这门课还是一切都好?
protocol AVPlayerServiceDelegate {
func playerDidUpdateCurrentPlayingTime(_ time: CMTime)
}
class AVPlayerService {
static let instance = AVPlayerService()
private var audioPlayer: AVPlayer!
public weak var delegate: AVPlayerServiceDelegate?
func setupPlayer(forURL url: URL) {
let playerItem: AVPlayerItem = AVPlayerItem(url: url)
audioPlayer = AVPlayer(playerItem: playerItem)
audioPlayer.play()
audioPlayer.addPeriodicTimeObserver(forInterval: CMTimeMakeWithSeconds(1, preferredTimescale: 1), queue: DispatchQueue.main) { (CMTime) -> Void in
if self.audioPlayer.currentItem?.status == .readyToPlay {
self.delegate?.playerDidUpdateCurrentPlayingTime(self.audioPlayer.currentTime())
}
}
}
var isPlaying: Bool {
return audioPlayer.isPlaying
}
var isPaused: Bool {
return audioPlayer.isPaused
}
var rate: Float {
return audioPlayer.rate
}
func seek(to time: CMTime) {
audioPlayer.seek(to: time)
}
func seekToBeginning() {
audioPlayer.seek(to: CMTimeMake(value: 0, timescale: 1))
}
func replay() {
audioPlayer.seek(to: CMTimeMake(value: 0, timescale: 1))
audioPlayer.play()
}
func pause() {
if let audioPlayer = audioPlayer {
audioPlayer.pause()
}
}
func play() {
audioPlayer.play()
}
func freshInstance() {
audioPlayer = AVPlayer()
}
var assetDuration: CMTime {
get {
return audioPlayer.currentItem!.asset.duration
}
}
}
解决方案
您需要一种机制来与player
对象对话以便对其执行操作。
有很多方法可以解决它。
就个人而言,我会为播放器创建一个专门的类来处理实例化它、加载音频资源、播放、暂停等。
然后我要么让这个类成为一个单例,这样我就可以从任何地方访问它,或者注入它并将它传递给将使用它的其他类。
基本示例:
class MyAudioPlayer {
static let shared = MyAudioPlayer()
private var player: AVAudioPlayer?
func load(_ url: URL) {
player = try? AVAudioPlayer(contentsOf: url)
}
func play(url: URL) {
load(url: url)
player?.play()
}
func pause() {
player?.pause()
}
func stop() {
player?.stop()
}
}
从应用程序内的任何位置发送操作:
MyAudioPlayer.shared.play(someURL)
MyAudioPlayer.shared.pause()
至于在后台播放,即使应用程序未处于活动状态也需要(也许在AppDelegate
)
try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback,
with: .duckOthers)
try? AVAudioSession.sharedInstance().setActive(true)
UIApplication.shared.beginReceivingRemoteControlEvents()
推荐阅读
- python - 如何将带有数字的列更改为反映与前一行列值按另一列值分组相关的变化的列?
- c# - C# WinForms 在所有表单中使用类的实例,每次都没有传递
- ios - 如何在 @IBAction 中调用 URL 数组?
- flutter - Flutter 提供程序不更新变量值
- java - Java Spring Boot - 将 Actuator Health Endpoint 的端口更改为自定义端口
- reactjs - 从选择组件内部编辑行或设置状态
- dart - 模式对象有什么用?
- javascript - 在 JSON 中添加字段不在接口 Vuejs 中
- django - 将外部数据与 Django 的数据库支持模型集成的设计模式
- reactjs - 带有 ReferenceField 问题的 React-Admin 条件样式