SwiftUI中AVPlayerItemDidPlayToEndTime通知未触发问题求助
AVPlayerItemDidPlayToEndTime通知不触发的修复方案
核心问题分析
你的代码存在两个关键错误导致通知无法触发:
- 观察者与处理函数归属不匹配:你将通知观察者注册为View实例(
self),但处理函数playerDidFinishPlaying属于VideoPlayerCoordinator类,通知无法正确分发到目标函数。 - 初始化顺序错误:你先注册通知,之后才初始化
coordinator,导致通知绑定的观察者实例不存在,同时未指定目标playerItem,进一步降低通知触发的准确性。
修正后的代码实现
1. 调整View的.onAppear逻辑(先初始化协调器再注册通知)
.onAppear { let playerItem = AVPlayerItem(url: videoURL!) let videoOutput = AVPlayerItemVideoOutput(pixelBufferAttributes: nil) playerItem.add(videoOutput) let player = AVPlayer(playerItem: playerItem) self.player = player // 优先初始化coordinator,确保实例已创建 self.coordinator = VideoPlayerCoordinator(videoOutput: videoOutput, playerItem: playerItem) // 注册通知:观察者设为coordinator,object指定当前playerItem NotificationCenter.default.addObserver( self.coordinator!, selector: #selector(VideoPlayerCoordinator.playerDidFinishPlaying), name: .AVPlayerItemDidPlayToEndTime, object: playerItem ) player.play() }
2. 优化Coordinator的通知处理函数(增强鲁棒性)
@objc func playerDidFinishPlaying(_ notification: Notification) { guard let finishedItem = notification.object as? AVPlayerItem else { return } print("视频播放结束:\(finishedItem)") // 此处添加播放结束后的业务逻辑,比如重置播放状态、触发回调等 }
3. 添加通知移除逻辑(避免内存泄漏)
在View的.onDisappear中移除观察者:
.onDisappear { guard let coordinator = coordinator, let playerItem = coordinator.playerItem else { return } NotificationCenter.default.removeObserver( coordinator, name: .AVPlayerItemDidPlayToEndTime, object: playerItem ) }
额外注意事项
- 确保
player和playerItem被正确持有(比如用@State或@ObservedObject修饰),避免实例提前释放导致通知无法触发。 - 如果视频开启了循环播放模式,
AVPlayerItemDidPlayToEndTime通知不会触发,需检查播放设置。
内容的提问来源于stack exchange,提问作者Hope
相关产品推荐
相关产品推荐

