iOS:如何正确停止AVPlayer播放的直播流,避免恢复播放时出现延迟
解决方案
针对AVPlayer播放直播流暂停后恢复存在延迟的问题,可采用以下两种方案实现符合需求的效果:
方案1:暂停时销毁播放器实例,恢复时重新拉流
该方案是直播场景最稳妥的实现方式,完全避免旧缓存导致的延迟问题,也不会出现播放状态显示异常的情况。
优化后的代码如下:
class CustomPlayer: ObservableObject { let audioSession = AVAudioSession.sharedInstance() var player: AVPlayer? private let streamUrl: URL init() { // 替换为实际直播流地址 guard let url = URL(string: "https://...") else { streamUrl = URL(fileURLWithPath: "") return } streamUrl = url configAudioSession() startPlay() } /// 配置音频会话 private func configAudioSession() { do { try audioSession.setCategory(.playback, mode: .default) try audioSession.setActive(true) } catch { print("音频会话配置失败: \(error.localizedDescription)") } } /// 启动播放 private func startPlay() { player = AVPlayer(url: streamUrl) player?.play() // 此处同步更新MPNowPlayingInfoCenter的播放状态为播放中即可 } /// 暂停直播 func pauseLive() { player?.pause() // 销毁播放器实例,清除旧缓存 player = nil // 此处同步更新MPNowPlayingInfoCenter的播放状态为暂停即可 } /// 恢复直播 func resumeLive() { startPlay() } }
方案2:恢复时主动跳转到最新直播位置
如果希望避免频繁初始化播放器,可以在恢复播放时主动seek到当前直播流的最新时间点:
func resumeLive() { guard let player = player, let currentItem = player.currentItem else { startPlay() return } // 获取直播流最新可播放时间点 let latestTime = currentItem.seekableTimeRanges.last?.timeRangeValue.end ?? .zero // 跳转到最新位置后播放 player.seek(to: latestTime, toleranceBefore: .zero, toleranceAfter: .zero) { [weak self] _ in self?.player?.play() // 更新播放状态 } }
补充说明
关于NowPlayingInfoCenter的状态更新:仅需在项目的「Signing & Capabilities」中添加Background Modes能力,勾选「Audio, AirPlay, and Picture in Picture」选项,即可正常更新播放状态,无需申请额外特殊权限。
内容的提问来源于stack exchange,提问作者Jonas Lang
相关产品推荐
相关产品推荐

