Core Media OC转Swift遇问题:CMMetadataFormatDescription创建失败
解决CMMetadataFormatDescriptionCreateWithMetadataSpecifications返回无效参数错误
问题背景
我在参考AAPLTimedAnnotationWriter的Objective-C示例,在Swift 5.7(macOS)中实现同类功能时,翻译示例代码第208-218行后,调用CMMetadataFormatDescriptionCreateWithMetadataSpecifications()返回kCMFormatDescriptionError_InvalidParameter错误。
原Objective-C代码
CMFormatDescriptionRef metadataFormatDescription = NULL; NSArray *specs = @[ @{(__bridge NSString *)kCMMetadataFormatDescriptionMetadataSpecificationKey_Identifier : AAPLTimedAnnotationWriterCircleCenterCoordinateIdentifier, (__bridge NSString *)kCMMetadataFormatDescriptionMetadataSpecificationKey_DataType : (__bridge NSString *)kCMMetadataBaseDataType_PointF32}, @{(__bridge NSString *)kCMMetadataFormatDescriptionMetadataSpecificationKey_Identifier : AAPLTimedAnnotationWriterCircleRadiusIdentifier, (__bridge NSString *)kCMMetadataFormatDescriptionMetadataSpecificationKey_DataType : (__bridge NSString *)kCMMetadataBaseDataType_Float64}, @{(__bridge NSString *)kCMMetadataFormatDescriptionMetadataSpecificationKey_Identifier : AAPLTimedAnnotationWriterCommentFieldIdentifier, (__bridge NSString *)kCMMetadataFormatDescriptionMetadataSpecificationKey_DataType : (__bridge NSString *)kCMMetadataBaseDataType_UTF8}]; OSStatus err = CMMetadataFormatDescriptionCreateWithMetadataSpecifications(kCFAllocatorDefault, kCMMetadataFormatType_Boxed, (__bridge CFArrayRef)specs, &metadataFormatDescription);
我的Swift代码(存在问题)
private func createChapterMetadataFormatDescription() -> CMMetadataFormatDescription? { let extra: NSArray = [ ( kCMMetadataFormatDescriptionMetadataSpecificationKey_Identifier: "mdta/com.example.circle.center.coordinate", kCMMetadataFormatDescriptionMetadataSpecificationKey_DataType: kCMMetadataBaseDataType_PointF32 ), ( kCMMetadataFormatDescriptionMetadataSpecificationKey_Identifier: "mdta/com.example.circle.radius", kCMMetadataFormatDescriptionMetadataSpecificationKey_DataType: kCMMetadataBaseDataType_Float64 ), ( kCMMetadataFormatDescriptionMetadataSpecificationKey_Identifier: "mdta/com.example.comment.field", kCMMetadataFormatDescriptionMetadataSpecificationKey_DataType: kCMMetadataBaseDataType_UTF8 ) ] var formatDescription: CMMetadataFormatDescription? = nil if kCVReturnSuccess != CMMetadataFormatDescriptionCreateWithMetadataSpecifications(allocator: kCFAllocatorDefault, metadataType: kCMMetadataFormatType_Boxed, metadataSpecifications: extra, formatDescriptionOut: &formatDescription) { return nil } return formatDescription }
错误原因及修正
核心错误1:用元组替代了字典
Objective-C代码中的@{...}是NSDictionary,但你在Swift里用了元组来构造数组元素,而CMMetadataFormatDescriptionCreateWithMetadataSpecifications要求的是包含字典的数组,类型不匹配直接导致参数无效。
核心错误2:错误的成功状态判断
你用了CoreVideo的kCVReturnSuccess来判断状态,但该API返回的是OSStatus类型,成功值应为noErr(等于0)。
修正后的Swift代码
private func createChapterMetadataFormatDescription() -> CMMetadataFormatDescription? { // 将CFString类型的键转换为Swift String let identifierKey = kCMMetadataFormatDescriptionMetadataSpecificationKey_Identifier as String let dataTypeKey = kCMMetadataFormatDescriptionMetadataSpecificationKey_DataType as String // 构造符合要求的字典数组 let specs: [[String: Any]] = [ [ identifierKey: "mdta/com.example.circle.center.coordinate", dataTypeKey: kCMMetadataBaseDataType_PointF32 ], [ identifierKey: "mdta/com.example.circle.radius", dataTypeKey: kCMMetadataBaseDataType_Float64 ], [ identifierKey: "mdta/com.example.comment.field", dataTypeKey: kCMMetadataBaseDataType_UTF8 ] ] var formatDescription: CMMetadataFormatDescription? = nil let status = CMMetadataFormatDescriptionCreateWithMetadataSpecifications( allocator: kCFAllocatorDefault, metadataType: kCMMetadataFormatType_Boxed, metadataSpecifications: specs as CFArray, formatDescriptionOut: &formatDescription ) // 使用正确的OSStatus成功值判断 guard status == noErr else { return nil } return formatDescription }
额外说明
- 所有CFString类型的常量(如数据类型标识)可直接传入字典,Swift会自动处理桥接
- 字典数组可直接转换为
CFArray传入API,无需显式声明为NSArray
内容的提问来源于stack exchange,提问作者yhf8377
相关产品推荐
相关产品推荐

