如何让AVPlayerItem遵循Codable协议?Mac开发编码解码问题
解决AVPlayerItem无法Codable编码解码的问题
你遇到的核心问题是AVPlayerItem本身并不遵循Codable协议,系统没有为它提供默认的编码解码实现,所以直接对它调用encode或decode方法会报错。要解决这个问题,你需要间接存储可序列化的数据源,再通过这些数据重新生成AVPlayerItem,而非直接存储AVPlayerItem实例。
方案一:存储视频数据源(URL/本地路径)
如果你的AVPlayerItem是从本地文件或远程URL创建的,最直接的方式是存储对应的URL:
class ProjectState2: ObservableObject, Codable { enum CodingKeys: CodingKey { case videoURL } // 存储可序列化的URL,而非AVPlayerItem private var videoURL: URL // 计算属性返回AVPlayerItem,同时通过@Published发布变化 @Published var video: AVPlayerItem { didSet { // 当AVPlayerItem变化时,同步更新videoURL if let asset = video.asset as? AVURLAsset { videoURL = asset.url } } } // 用AVMutableComposition初始化的构造方法 init(composition: AVMutableComposition) { // 可根据composition生成对应的标识,比如临时文件路径 self.videoURL = URL(fileURLWithPath: "") self.video = AVPlayerItem(asset: composition) } // Codable初始化方法 required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.videoURL = try container.decode(URL.self, forKey: .videoURL) // 从URL重新生成AVPlayerItem self.video = AVPlayerItem(url: videoURL) } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(videoURL, forKey: .videoURL) } }
方案二:序列化AVMutableComposition
如果你的AVPlayerItem基于AVMutableComposition创建,可以利用AVMutableComposition遵循NSCoding的特性,将其归档为Data存储:
class ProjectState2: ObservableObject, Codable { enum CodingKeys: CodingKey { case compositionData } private var compositionData: Data @Published var video: AVPlayerItem // 用AVMutableComposition初始化 init(composition: AVMutableComposition) { // 将AVMutableComposition归档为Data do { self.compositionData = try NSKeyedArchiver.archivedData(withRootObject: composition, requiringSecureCoding: false) } catch { self.compositionData = Data() // 这里可添加自定义错误处理逻辑 } self.video = AVPlayerItem(asset: composition) } required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.compositionData = try container.decode(Data.self, forKey: .compositionData) // 从Data解档回AVMutableComposition,再生成AVPlayerItem guard let composition = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(compositionData) as? AVMutableComposition else { throw DecodingError.dataCorrupted(.init(codingPath: [CodingKeys.compositionData], debugDescription: "Failed to unarchive AVMutableComposition")) } self.video = AVPlayerItem(asset: composition) } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(compositionData, forKey: .compositionData) } }
注意事项
- 方案二中的异常处理可根据业务需求优化,避免使用强制解包导致崩溃。
- 如果AVMutableComposition包含外部视频片段,需确保解码时这些资源的路径仍有效,或同步存储相关资源的标识信息。
- @Published修饰的
video属性会在重新赋值时自动触发视图更新,需保证数据源变化时video能被正确刷新。
内容的提问来源于stack exchange,提问作者user1542125
相关产品推荐
相关产品推荐

