SwiftUI中AVPlayer/AVPlayerItem错误捕获与UI展示方案咨询
在SwiftUI中捕获AVPlayer/AVPlayerItem错误并展示到UI
你开发的基于SwiftUI的HTTP直播流音乐应用,需要捕获AVPlayer/AVPlayerItem的底层错误(比如HTTP流中断)并在UI中展示,可通过以下步骤实现:
核心思路
AVPlayerItem发生错误时会通过NotificationCenter发送AVPlayerItemFailedToPlayToEndTime通知,我们可以监听这个通知,将错误信息同步到SwiftUI的状态变量中,进而更新UI。
具体实现步骤
- 添加错误状态变量:用
@State定义存储错误信息的变量,控制错误提示的显示。 - 监听错误通知:在视图的
onAppear方法中注册AVPlayerItemFailedToPlayToEndTime通知的监听,onDisappear中移除监听,避免内存泄漏。 - 处理错误信息:在通知回调中解析错误内容,更新状态变量。
- UI展示错误:根据错误状态变量,在界面上显示对应的错误提示。
修改后的完整代码
struct PlayerView: View { @State var audioPlayer: AVPlayer! @State var buttonSymbol: String = "pause.circle.fill" @State private var playbackError: String? // 存储错误信息的状态变量 let url: URL! // 用于存储通知监听的令牌,方便移除监听 private var notificationToken: NSObjectProtocol? var body: some View { VStack { Text("Sound") // 错误提示UI,有错误时显示 if let error = playbackError { Text("播放出错:\(error)") .foregroundColor(.red) .padding(.vertical) } HStack { Button(action: { guard let player = audioPlayer else { return } if player.rate != 0.0 { buttonSymbol = "play.circle.fill" player.pause() } else { buttonSymbol = "pause.circle.fill" player.play() } }) { Image(systemName: buttonSymbol) .font(.largeTitle) } .buttonStyle(PlainButtonStyle()) .disabled(playbackError != nil) // 出错时禁用播放按钮 } } .onAppear { let audioSession = AVAudioSession.sharedInstance() do { try audioSession.setCategory(AVAudioSession.Category.playback, mode: .default, policy: AVAudioSession.RouteSharingPolicy.longFormAudio, options: []) } catch let error { playbackError = "音频会话设置失败:\(error.localizedDescription)" return } let item = AVPlayerItem(url: self.url) self.audioPlayer = AVPlayer(playerItem: item) // 监听AVPlayerItem错误通知 notificationToken = NotificationCenter.default.addObserver( forName: .AVPlayerItemFailedToPlayToEndTime, object: item, queue: .main ) { notification in if let error = notification.userInfo?[AVPlayerItemFailedToPlayToEndTimeErrorKey] as? Error { self.playbackError = error.localizedDescription // 可根据错误类型做额外处理,比如重置播放器 self.audioPlayer = nil } } audioSession.activate(options: []) { (success, error) in if let error = error { self.playbackError = "音频会话激活失败:\(error.localizedDescription)" return } self.audioPlayer?.play() } } .onDisappear { // 移除通知监听,避免内存泄漏 if let token = notificationToken { NotificationCenter.default.removeObserver(token) } audioPlayer?.pause() audioPlayer = nil } } }
关键代码说明
playbackError状态变量:用于存储错误信息,当它不为空时,SwiftUI会自动更新UI显示错误提示。- 通知监听:通过
NotificationCenter监听AVPlayerItemFailedToPlayToEndTime通知,指定监听对象为当前创建的AVPlayerItem,确保只接收该播放器项的错误。 - 错误处理:在通知回调中从
userInfo里取出AVPlayerItemFailedToPlayToEndTimeErrorKey对应的错误对象,转换为可读信息并更新状态变量。 - UI交互优化:出错时禁用播放按钮,避免用户无效操作,同时显示红色的错误提示文字。
内容的提问来源于stack exchange,提问作者Evel Knievel
相关产品推荐
相关产品推荐

