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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 14:23:15