【问题标题】:Resuming AVPlayer after being interrupted with SwiftUI被 SwiftUI 中断后恢复 AVPlayer
【发布时间】:2020-08-10 07:50:42
【问题描述】:

我正在使用AVPlayerAVPlayerItem 构建一个广播流媒体应用程序。我已经构建了我的应用程序以像这样在后台继续播放广播:

do {
    try AVAudioSession.sharedInstance().setCategory(.playback)
    try AVAudioSession.sharedInstance().setActive(true)
} catch {
   print(error)
}

AVPlayer 中断后(例如,当用户接到电话时)AVPlayer 不会继续播放。我需要再次主动播放才能收听流媒体。

如何使AVPlayer 在使用SwiftUI 中断后自动恢复? (我找到了一些解决方案,但没有一个适合使用 SwiftUI

谢谢!

【问题讨论】:

    标签: ios swift iphone cocoa-touch swiftui


    【解决方案1】:

    中断后重新开始播放与 SwiftUI 或一般 UI 无关。

    正如苹果documentation

    首先注册到中断通知:

    func registerForNotifications() {
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(handleInterruption),
                                               name: .AVAudioSessionInterruption,
                                               object: AVAudioSession.sharedInstance())
    }
    
    

    然后像这样处理通知:

    func handleInterruption(_ notification: Notification) {
        guard let info = notification.userInfo,
            let typeValue = info[AVAudioSessionInterruptionTypeKey] as? UInt,
            let type = AVAudioSessionInterruptionType(rawValue: typeValue) else {
                return
        }
        if type == .began {
            // Interruption began, take appropriate actions (save state, update user interface)
        }
        else if type == .ended {
            guard let optionsValue =
                userInfo[AVAudioSessionInterruptionOptionKey] as? UInt else {
                    return
            }
            let options = AVAudioSessionInterruptionOptions(rawValue: optionsValue)
            if options.contains(.shouldResume) {
                // Interruption Ended - playback should resume
            }
        }
    }
    
    

    如果这没有帮助,您可以更好地解释您遇到的其他解决方案在您的情况下不起作用的问题。

    【讨论】:

    • 感谢您的回答。据我所知,在使用SwiftUI 或其他MVVM 进行开发时,不应使用NotificationCenter。对不对?
    • 我认为这不对。 SwiftUI 只是一个以声明方式构建 UI 的框架。它与业务逻辑无关(如播放或暂停音频)。 NotificationCenter 还与新的 combine 框架兼容(您可以从中提取发布者),因此没有理由不使用它,尤其是对于系统通知。另外,我认为没有其他方法可以应对干扰。
    • 额外:可能会有所帮助hackingwithswift.com/books/ios-swiftui/…您可以在应用程序进入后台或进入前台时收听
    【解决方案2】:

    SwiftUI

    像这样在播放按钮上调用 .onReceive 函数:

    .onReceive(NotificationCenter.default.publisher(for: AVAudioSession.interruptionNotification)) { event in
        guard let info = event.userInfo,
            let typeValue = info[AVAudioSessionInterruptionTypeKey] as? UInt,
            let type = AVAudioSession.InterruptionType(rawValue: typeValue) else {
                return
        }
        if type == .began {
            // Interruption began, take appropriate actions (save state, update user interface)
        }
        else if type == .ended {
            guard let optionsValue =
                info[AVAudioSessionInterruptionOptionKey] as? UInt else {
                    return
            }
            let options = AVAudioSession.InterruptionOptions(rawValue: optionsValue)
            if options.contains(.shouldResume) {
                // Interruption Ended - playback should resume
                player.play()
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-09
      • 2020-05-20
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-15
      相关资源
      最近更新 更多