AVFoundation报错:avc1编码不支持Quality压缩属性求助
如何提前验证AVAssetWriterInput视频设置键有效性,以及设置不一致导致崩溃的原因
一、提前验证视频设置键有效性的方法
1. 用官方API直接校验兼容性
苹果提供了专门的兼容性校验API,能在初始化AVAssetWriterInput前检查设置是否合法,完全避免崩溃:
let targetSettings: [String: Any] = [ AVVideoWidthKey: 1000, AVVideoHeightKey: 1000, AVVideoCodecKey: AVVideoCodecType.h264, AVVideoCompressionPropertiesKey: [ AVVideoQualityKey: 0.4 ] ] let compatibilityStatus = AVAssetWriterInput.outputSettingsCompatibilityForMediaType(.video, outputSettings: targetSettings) switch compatibilityStatus { case .compatible: // 设置合法,安全初始化 let videoWriterInput = AVAssetWriterInput(mediaType: .video, outputSettings: targetSettings) case .incompatible: // 设置无效,需要调整参数 print("当前设备不支持该输出设置") case .unknown: // 无法确定兼容性,建议降级到基础设置 print("无法验证设置兼容性,将使用兼容模式") }
2. 动态查询编码器支持的属性
如果需要更精准的属性支持情况,可以通过Video Toolbox查询当前编码器的所有支持属性:
func getSupportedCompressionKeys(for codec: AVVideoCodecType) -> [String]? { guard let codecID = CMVideoCodecType(codec) else { return nil } var session: VTCompressionSession? let status = VTCompressionSessionCreate( allocator: kCFAllocatorDefault, width: 1000, height: 1000, codecType: codecID, encoderSpecification: [kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder: true] as CFDictionary, imageBufferAttributes: nil, compressedDataAllocator: kCFAllocatorDefault, outputCallback: nil, refcon: nil, compressionSessionOut: &session ) guard status == noErr, let validSession = session else { return nil } defer { VTCompressionSessionInvalidate(validSession) } var supportedKeys: CFArray? VTSessionCopySupportedPropertyDictionaryKeys(validSession, &supportedKeys) return supportedKeys as? [String] } // 使用示例 if let supportedKeys = getSupportedCompressionKeys(for: .h264) { if supportedKeys.contains(AVVideoQualityKey) { // 当前编码器支持Quality键 } else { // 不支持,改用比特率等参数 } }
二、设置有效性不一致的原因
- 硬件编码器差异:不同Intel Mac型号的视频编码器硬件不同,部分旧款或特定型号的编码器不支持
AVVideoQualityKey这种高层抽象参数——这个键是苹果封装的简化接口,底层会自动转换为比特率,但并非所有编码器都兼容这种转换逻辑。 - 系统隐性差异:即使系统版本同为13.5,不同硬件的系统补丁、编码器固件可能存在差异,导致属性支持范围不同。
- 编码器优先级问题:部分设备可能优先使用软件编码器而非硬件编码器,而软件编码器的支持属性和硬件编码器存在区别。
三、替代解决方案
如果AVVideoQualityKey不被支持,改用更底层、兼容性更好的比特率参数:
let videoWriterInput = AVAssetWriterInput( mediaType: .video, outputSettings: [ AVVideoWidthKey: 1000, AVVideoHeightKey: 1000, AVVideoCodecKey: AVVideoCodecType.h264, AVVideoCompressionPropertiesKey: [ AVVideoAverageBitRateKey: 5_000_000, // 5Mbps,可根据需求调整 AVVideoMaxKeyFrameIntervalKey: 30 ] ] )
内容的提问来源于stack exchange,提问作者Morten J
相关产品推荐
相关产品推荐

