RealityKit中如何在参考图像未追踪时暂停对应视频?
解决AR参考图像追踪状态对应视频播放/暂停的问题
你的核心问题是用了单个全局AVPlayer实例,所有参考图像的视频都共用它,自然没法单独控制每个视频的状态。要实现精准控制,得给每个检测到的参考图像分配独立的AVPlayer,并建立锚点与播放器的映射关系。
具体实现步骤:
- 添加锚点与播放器的映射字典
在Coordinator里新增一个字典,用ARAnchor的唯一标识符作为key,对应每个视频的AVPlayer:
class Coordinator: NSObject, ARSessionDelegate { var parent: ARViewContainer // 存储每个锚点对应的AVPlayer var anchorPlayerMap: [UUID: AVPlayer] = [:] init(parent: ARViewContainer) { self.parent = parent } // ... 其他代码 }
- 修改视频节点创建逻辑,生成独立播放器
修改createdVideoPlayerNodeFor方法,每次创建新的AVPlayer实例,并存入映射字典:
func createdVideoPlayerNodeFor(_ target: ARReferenceImage, anchorID: UUID) -> ModelEntity { var videoPlane = ModelEntity() guard let targetName = target.name, let validURL = Bundle.main.url(forResource: targetName, withExtension: "mp4") else { return videoPlane } // 为当前参考图像创建独立的AVPlayer let player = AVPlayer(url: validURL) player.play() // 将播放器存入字典,关联锚点ID anchorPlayerMap[anchorID] = player let videoMaterial = VideoMaterial(avPlayer: player) videoPlane = ModelEntity(mesh: .generatePlane(width: Float(target.physicalSize.width), depth: Float(target.physicalSize.height)), materials: [videoMaterial]) print(target.name as Any) return videoPlane }
同时更新didAdd anchors方法,传入锚点的identifier:
func session(_ session: ARSession, didAdd anchors: [ARAnchor]) { for anchor in anchors { guard let validAnchor = anchor as? ARImageAnchor else { continue } let anchorEntity = AnchorEntity(anchor: validAnchor) // 传入锚点ID,绑定对应的播放器 anchorEntity.addChild(createdVideoPlayerNodeFor(validAnchor.referenceImage, anchorID: validAnchor.identifier)) parent.arView.scene.addAnchor(anchorEntity) } }
- 精准处理追踪状态更新
在didUpdate anchors方法中,遍历所有更新的锚点,根据ID找到对应的播放器,控制播放/暂停:
func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) { for anchor in anchors { guard let validAnchor = anchor as? ARImageAnchor, let player = anchorPlayerMap[validAnchor.identifier] else { continue } if validAnchor.isTracked { if player.timeControlStatus != .playing { player.play() print("播放:\(validAnchor.name ?? "未知图像")") } } else { if player.timeControlStatus == .playing { player.pause() print("暂停:\(validAnchor.name ?? "未知图像")") } } } }
- 处理锚点移除的情况(可选但推荐)
当参考图像完全丢失被移除时,暂停对应播放器并清理字典,避免内存泄漏:
func session(_ session: ARSession, didRemove anchors: [ARAnchor]) { for anchor in anchors { guard let validAnchor = anchor as? ARImageAnchor, let player = anchorPlayerMap[validAnchor.identifier] else { continue } player.pause() anchorPlayerMap.removeValue(forKey: validAnchor.identifier) print("移除并暂停:\(validAnchor.name ?? "未知图像")") } }
关键说明:
- 每个参考图像对应独立的AVPlayer,通过锚点的UUID唯一标识,确保精准控制
- 加入了播放状态判断,避免重复调用play/pause导致的异常
- 处理锚点移除逻辑,减少内存占用
内容的提问来源于stack exchange,提问作者user1207524
相关产品推荐
相关产品推荐

