You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 12:25:42