You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 09:31:06