被 SwiftUI 中断后恢复 AVPlayer

Resuming AVPlayer after being interrupted with SwiftUI

提问人:F.SO7 提问时间:4/27/2020 更新时间:12/17/2020 访问量:938

问:

我正在使用 和 构建一个广播流媒体应用程序。我已经构建了我的应用程序,以便在后台继续播放广播,如下所示:AVPlayerAVPlayerItem

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

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

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

谢谢!

iOS Swift iPhone Cocoa-Touch SwiftUI

评论


答:

4赞 Enricoza 5/1/2020 #1

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

正如苹果文档中所说:

首先注册中断通知:

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
        }
    }
}

如果这没有帮助,您可以更好地解释您遇到的问题,使用其他不适用于您的解决方案。

评论

0赞 F.SO7 5/1/2020
谢谢你的回答。据我所知,在开发时不应该使用或其他.不是吗?NotificationCenterSwiftUIMVVM
2赞 Enricoza 5/1/2020
我认为这是不对的。SwiftUI 只是一个以声明式方式构建 UI 的框架。它与业务逻辑无关(如播放或暂停音频)。NotificationCenter 还与新的组合框架兼容(您可以从中提取发布者),因此真的没有理由不使用它,尤其是对于系统通知。此外,我认为没有其他方法可以应对中断。
0赞 Enes Karaosman 5/2/2020
额外:hackingwithswift.com/books/ios-swiftui/ 可能会有所帮助... 您可以在应用程序进入后台或进入前台时收听
4赞 Malsor 12/17/2020 #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()
        }
    }
}