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

iOS音频元数据读取与编辑技术问询(含AVMetadataItem问题)

关于音频元数据读取与编辑的问题解答

嘿,刚好我之前处理过类似的音频元数据场景,来帮你逐个梳理这些问题:

1. 有没有相关的官方文档?

当然有!苹果的AVFoundation框架文档里专门有元数据相关的章节,重点看AVMetadataItem、AVAssetMetadata的官方说明,里面会提到commonKey和格式特定key的区别。另外你看到的TPE1、TRCK这些是ID3标签的帧标识,苹果文档里也有对应映射表,比如TPE1对应AVMetadataKey.commonKeyArtist,TRCK对应AVMetadataID3MetadataKeyTrackNumber。

2. 为什么会有commonKey为nil的项,是不是遗漏了什么?

你遇到的情况很常见:苹果的commonKey是对不同格式元数据(比如ID3、iTunes Metadata)的统一封装,但有些元数据项可能因为文件格式、编辑工具(比如iTunes)的写法,没有被自动映射到commonKey,这时候就需要直接检查格式特定的key。

比如你要找的曲目编号1/2,对应的是ID3的TRCK帧,你可以通过以下方式获取:

for metadataItem in audioAsset.metadata {
    // 检查commonKey的逻辑保留
    if metadataItem.commonKey == AVMetadataKey.commonKeyArtist {
        print("artistName IN METADATA \(metadataItem.value)")
    }
    
    // 检查ID3格式的曲目编号key
    if metadataItem.identifier == AVMetadataIdentifier.id3MetadataTrackNumber {
        if let trackValue = metadataItem.value as? String {
            print("Track number: \(trackValue)") // 这里就能拿到1/2啦
        }
    }
    
    // 极端情况:如果上面的identifier没匹配到,直接检查原始ID3帧标识
    if metadataItem.key as? String == "TRCK" {
        // 同样可以获取曲目编号
    }
}

3. 编辑元数据的最佳方式是什么?

AVAsset本身是只读的,所以要修改元数据并持久化到文件,需要通过AVAssetExportSession导出新文件的方式,步骤大概是:

  • 把原Asset的元数据复制为可变数组(AVMutableMetadataItem)
  • 创建或修改对应的元数据项,设置正确的key、value、标识符等
  • 配置导出会话,把修改后的元数据传入,导出到新文件

举个修改曲目编号的例子:

// 1. 复制原元数据为可变数组
var mutableMetadata = audioAsset.metadata.map { $0.copy() as! AVMutableMetadataItem }

// 2. 创建新的曲目编号元数据项
let trackItem = AVMutableMetadataItem()
trackItem.key = AVMetadataID3MetadataKeyTrackNumber as NSString
trackItem.value = "1/2" as NSString
trackItem.locale = Locale.current
trackItem.identifier = AVMetadataIdentifier.id3MetadataTrackNumber
trackItem.extendedLanguageTag = "und" // 通用语言标识

// 3. 替换原有曲目编号(如果存在),否则添加
if let existingIndex = mutableMetadata.firstIndex(where: { $0.identifier == AVMetadataIdentifier.id3MetadataTrackNumber }) {
    mutableMetadata[existingIndex] = trackItem
} else {
    mutableMetadata.append(trackItem)
}

// 4. 导出新文件
guard let exportSession = AVAssetExportSession(asset: audioAsset, presetName: AVAssetExportPresetPassthrough) else {
    print("Failed to create export session")
    return
}
exportSession.outputURL = URL(fileURLWithPath: "/path/to/your/output/file.mp3") // 替换成你的输出路径
exportSession.outputFileType = audioAsset.preferredExportFileType
exportSession.metadata = mutableMetadata

exportSession.exportAsynchronously {
    switch exportSession.status {
    case .completed:
        print("Metadata updated successfully!")
        // 这里可以处理新生成的文件
    case .failed, .cancelled:
        print("Export error: \(exportSession.error?.localizedDescription ?? "Unknown error")")
    default:
        break
    }
}

注意:不同音频格式对应的元数据key不一样,比如M4A文件用的是iTunes Metadata,对应的曲目编号key是AVMetadataKey.itunesMetadataKeyTrackNumber,导出时要匹配文件格式选择正确的key。

4. 在编辑文件的UIViewController中能否添加元数据值?

完全可以!你只需要在UI里收集用户输入的信息(比如曲目编号、艺术家名等),然后按照上面的编辑流程,把用户输入的内容转换成对应的AVMutableMetadataItem,再执行导出操作就行。比如在VC里添加一个输入框让用户输入曲目编号,点击保存按钮时触发元数据修改和导出逻辑。

内容的提问来源于stack exchange,提问作者Reimond Hill

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:24:58