2024年能否用Swift编辑MP3文件Metadata以记录创作者信息?
在Swift中为MP3文件添加/编辑创作者元数据(2024年方案)
问题背景
我的应用允许用户创建录音并保存为MP3文件,希望在文件中添加创作者信息。MP3文件的元数据存储在文件开头的ID3标签中。
我已经可以通过以下代码读取MP3的元数据:
import AVFoundation let asset = AVAsset(url: URL(fileURLWithPath: "/path/to/mp3/file.mp3")) let metadata = asset.commonMetadata for item in metadata { if let value = item.value { switch item.commonKey?.rawValue { case "title": print("Title: \(value)") case "artist": print("Artist: \(value)") default: break } } }
但我发现AVKit和AVFoundation均不支持直接添加或编辑MP3元数据,早年的一些方法也不可靠,我更倾向于避免使用第三方框架,想了解2024年是否有原生方案,或其他可靠的方式保留创作者信息。
2024年可行方案
1. 利用AVAssetExportSession间接嵌入元数据
虽然AVFoundation没有直接编辑ID3标签的API,但可以通过重新导出MP3文件的方式嵌入元数据。需要注意的是,这种方式可能会触发音频重新编码(取决于预设参数),存在质量损失或效率问题。示例代码如下:
import AVFoundation func exportMP3WithCreatorMetadata(inputURL: URL, outputURL: URL, creatorName: String) throws { let asset = AVAsset(url: inputURL) // 创建创作者元数据项 let creatorMetadata = AVMutableMetadataItem() creatorMetadata.commonKey = .commonKeyArtist creatorMetadata.value = creatorName as NSString creatorMetadata.identifier = AVMetadataIdentifier.commonIdentifierArtist creatorMetadata.extendedLanguageTag = "und" // 通用语言标识 // 初始化导出会话 guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetPassthrough) else { throw NSError(domain: "ExportError", code: -1, userInfo: [NSLocalizedDescriptionKey: "无法创建导出会话"]) } exportSession.outputURL = outputURL exportSession.outputFileType = .mp3 exportSession.metadata = [creatorMetadata] // 执行异步导出 exportSession.exportAsynchronously(completionHandler: { switch exportSession.status { case .completed: print("导出完成,创作者元数据已添加") case .failed: print("导出失败:\(exportSession.error?.localizedDescription ?? "未知错误")") case .cancelled: print("导出已取消") default: break } }) }
提示:AVAssetExportPresetPassthrough尝试直接复制原始音频数据,但部分场景下仍会触发重新编码,建议根据实际需求测试适配。
2. 手动实现ID3标签编辑(无第三方依赖)
如果需要完全控制ID3标签且不想依赖第三方库,可以基于ID3规范手动处理文件字节流。核心步骤包括:
- 检查MP3文件开头是否存在ID3v2标识(前3字节为
ID3) - 解析标签头,定位到对应字段(比如艺术家信息对应
TPE1帧) - 修改字段内容并更新标签大小
- 若没有ID3标签,创建新的ID3v2标签并插入到文件开头
这种方式需要对ID3规范有一定了解,实现复杂度较高,但能避免第三方依赖和重新编码的问题。
3. 文件扩展属性(仅自应用内可用)
如果不需要其他音乐播放器识别创作者信息,可以将数据存储在文件的扩展属性中,实现简单且不修改MP3文件内容:
import Foundation // 设置创作者扩展属性 func setCreatorExtendedAttribute(for fileURL: URL, creator: String) throws { guard let data = creator.data(using: .utf8) else { throw NSError(domain: "AttributeError", code: -1, userInfo: [NSLocalizedDescriptionKey: "数据转换失败"]) } try FileManager.default.setExtendedAttribute(data, forPath: fileURL.path, name: "com.yourapp.recording.creator") } // 获取创作者扩展属性 func getCreatorExtendedAttribute(for fileURL: URL) throws -> String? { let data = try FileManager.default.extendedAttribute(forPath: fileURL.path, name: "com.yourapp.recording.creator") return String(data: data, encoding: .utf8) }
局限:仅能在你的应用内读取该信息,其他音乐播放器无法识别。
总结
- 若需要标准ID3标签且避免第三方库,优先尝试
AVAssetExportSession方案(需注意编码问题),或手动实现ID3标签编辑(适合有底层开发经验的场景); - 若仅需自应用内读取创作者信息,文件扩展属性是最简单的方案。
内容的提问来源于stack exchange,提问作者user6631314
相关产品推荐
相关产品推荐

