ID3TagEditor
一个 Swift 库,用于读取和修改任何 mp3 文件中的 ID3 Tag。被列入官方 ID3 标准网站id3.org的实施部分。
安装
有四种方式可以将ID3TagEditor安装到您的项目中
- 手动安装
- 框架
- CocoaPods
- Swift Package Manager(支持Linux平台)
手动安装
要手动安装ID3TagEditor,只需将源文件夹内的所有文件拖放到您的项目中( wyjątkiem pliku info.plist)。
框架
ID3TagEditor也作为一个框架提供。您可以使用安装自定义Cocoa Touch框架的标准程序。将ID3TagEditor.xcodeproj拖放到项目中,并将其添加到项目中的嵌入式二进制文件/链接框架和库部分。查看示例项目以获取框架设置的完整示例。
CocoaPods
ID3TagEditor也作为CocoaPods上的pod提供。将依赖项添加到您的Podfile中(选择您喜欢的发布版本)
target 'MyApp' do
pod 'ID3TagEditor', '~> 4.0'
end
然后运行pod install(或pod update)。
Swift Package Manager
ID3TagEditor 还提供了 Swift 包,用于 Swift 包管理器。在您的 Package.swift
文件中将它添加到依赖项中。之后,您可以使用 swift build
命令构建您的项目,并最终使用 swift run
命令运行您的项目(如果它是可执行目标)。如果需要,您还可以使用 swift test
运行测试。
// swift-tools-version:5.0
import PackageDescription
let package = Package(
name: "Demo Ubuntu",
dependencies: [
.package(url: "https://github.com/chicio/ID3TagEditor.git", from: "4.0.0")
],
targets: [
.target(
name: "Demo Ubuntu",
dependencies: ["ID3TagEditor"]
)
]
)
使用方法
ID3TagEditor 与以下平台兼容
- iOS
- macOS
- Apple Watch
- Apple TV
- Linux(在 Swift 可用的发行版上)
ID3TagEditor 使您能够读取和写入 mp3 文件中的 ID3Tag。
读取
要读取 mp3 文件的 ID3 标签,您可以选择在 ID3TagEditor
类中存在的两种 API 之一
public func read(from path: String) throws -> ID3Tag?
public func read(mp3: Data) throws -> ID3Tag?
从上面的读取 API 获取一个 ID3Tag
之后,您有两个选项来读取内容
- 如果您只想读取内容,您可以通过传递从读取 API 接收到的
ID3Tag
创建一个ID3TagContentReader
实例,然后使用其方法访问帧内容(请参阅文档以获取所有可用方法的列表)。
do {
if let id3Tag = try id3TagEditor.read(from: PathLoader().pathFor(name: "example", fileType: "mp3")) {
let tagContentReader = ID3TagContentReader(id3Tag: id3Tag)
print(tagContentReader.title() ?? "")
print(tagContentReader.artist() ?? "")
// ...read other stuff...
}
} catch {
print(error)
}
- 如果您需要完整的帧数据,您可以访问
ID3Tag
的frames
属性并开始分析收到的各种帧。这样,您将能够访问帧中包含的所有数据,包括其内容和其属性,如大小和 ID3 帧标识符。
do {
let id3TagEditor = ID3TagEditor()
if let id3Tag = try id3TagEditor.read(from: "<valid path to the mp3 file>") {
// ...use the tag...
// For example to read the title, album and artist content you can do something similar
print((id3Tag.frames[.title] as? ID3FrameWithStringContent)?.content ?? "")
print((id3Tag.frames[.artist] as? ID3FrameWithStringContent)?.content ?? "")
print((id3Tag.frames[.album] as? ID3FrameWithStringContent)?.content ?? "")
}
if let id3Tag = try id3TagEditor.read(mp3: "<valid mp3 file passed as Data>") {
// ...use the tag...
// For example to read the title, album and artist content you can do something similar
print((id3Tag.frames[.title] as? ID3FrameWithStringContent)?.content ?? "")
print((id3Tag.frames[.artist] as? ID3FrameWithStringContent)?.content ?? "")
print((id3Tag.frames[.album] as? ID3FrameWithStringContent)?.content ?? "")
}
} catch {
print(error)
}
写入
要将新的 ID3 标签写入 mp3 文件,您可以选择在 ID3TagEditor
类中存在的两种 API 之一
public func write(tag: ID3Tag, to path: String, andSaveTo newPath: String? = nil) throws
public func write(tag: ID3Tag, mp3: Data) throws -> Data
创建有效的 ID3Tag
的唯一方法是使用可用的标签构建器。
ID32v2TagBuilder
,用于创建ID3标签版本2.2的有用构建器。ID32v3TagBuilder
,用于创建ID3标签版本2.3的有用构建器。ID32v4TagBuilder
,用于创建ID3标签版本2.4的有用构建器。
在没有上述构建器之一的情况下,您无法创建ID3Tag
的实例。以下是一个示例代码,该代码将ID3Tag版本3中ID3TagEditor支持的 所有帧写入MP3文件。
do {
let id3Tag = ID32v3TagBuilder()
.title(frame: ID3FrameWithStringContent(content: "title V3"))
.album(frame: ID3FrameWithStringContent(content: "album V3"))
.albumArtist(frame: ID3FrameWithStringContent(content: "album artist V3"))
.artist(frame: ID3FrameWithStringContent(content: "artist V3"))
.composer(frame: ID3FrameWithStringContent(content: "composer V3"))
.conductor(frame: ID3FrameWithStringContent(content: "conductor V3"))
.contentGrouping(frame: ID3FrameWithStringContent(content: "ContentGrouping V3"))
.copyright(frame: ID3FrameWithStringContent(content: "Copyright V3"))
.encodedBy(frame: ID3FrameWithStringContent(content: "EncodedBy V3"))
.encoderSettings(frame: ID3FrameWithStringContent(content: "EncoderSettings V3"))
.fileOwner(frame: ID3FrameWithStringContent(content: "FileOwner V3"))
.lyricist(frame: ID3FrameWithStringContent(content: "Lyricist V3"))
.mixArtist(frame: ID3FrameWithStringContent(content: "MixArtist V3"))
.publisher(frame: ID3FrameWithStringContent(content: "Publisher V3"))
.subtitle(frame: ID3FrameWithStringContent(content: "Subtitle V3"))
.beatsPerMinute(frame: ID3FrameWithIntegerContent(value: 50))
.originalFilename(frame: ID3FrameWithStringContent(content: "filenameV3.mp3"))
.lengthInMilliseconds(frame: ID3FrameWithIntegerContent(value: 9000))
.sizeInBytes(frame: ID3FrameWithIntegerContent(value: 1500))
.genre(frame: ID3FrameGenre(genre: .metal, description: "Metalcore"))
.discPosition(frame: ID3FramePartOfTotal(part: 1, total: 3))
.trackPosition(frame: ID3FramePartOfTotal(part: 2, total: 9))
.recordingDayMonth(frame: ID3FrameRecordingDayMonth(day: 5, month: 8))
.recordingYear(frame: ID3FrameWithIntegerContent(year: 2020))
.recordingHourMinute(frame: ID3FrameRecordingHourMinute(hour: 15, minute: 39))
.attachedPicture(pictureType: .frontCover, frame: ID3FrameAttachedPicture(picture: <picture as Data object>, type: .frontCover, format: .jpeg))
.attachedPicture(pictureType: .backCover, frame: ID3FrameAttachedPicture(picture: <picture as Data object>, type: .backCover, format: .jpeg))
.unsynchronisedLyrics(language: .ita, frame: ID3FrameWithLocalizedContent(language: ID3FrameContentLanguage.ita, contentDescription: "CD", content: "v3 ita unsync lyrics"))
.unsynchronisedLyrics(language: .eng, frame: ID3FrameWithLocalizedContent(language: ID3FrameContentLanguage.eng, contentDescription: "CD", content: "v3 eng unsync lyrics"))
.iTunesGrouping(frame: ID3FrameWithStringContent(content: "ItunesGrouping V3"))
.iTunesMovementName(frame: ID3FrameWithStringContent(content: "MovementName V3"))
.iTunesMovementIndex(frame: ID3FrameWithIntegerContent(value: 6))
.iTunesMovementCount(frame: ID3FrameWithIntegerContent(value: 13))
.iTunesPodcastCategory(frame: ID3FrameWithStringContent(content: "PodcastCategory V3"))
.iTunesPodcastDescription(frame: ID3FrameWithStringContent(content: "PodcastDescription V3"))
.iTunesPodcastID(frame: ID3FrameWithStringContent(content: "PodcastID V3"))
.iTunesPodcastKeywords(frame: ID3FrameWithStringContent(content: "PodcastKeywords V3"))
.comment(language: .ita, frame: ID3FrameWithLocalizedContent(language: ID3FrameContentLanguage.ita, contentDescription: "CD", content: "v2 ita comment"))
.comment(language: .eng, frame: ID3FrameWithLocalizedContent(language: ID3FrameContentLanguage.eng, contentDescription: "CD", content: "v2 eng comment"))
.build()
try id3TagEditor.write(tag: id3Tag, to: "<valid path to the mp3 file that will be overwritten>")
try id3TagEditor.write(tag: id3Tag,
to: "<valid path to the mp3 file>",
andSaveTo: "<new path where you want to save the mp3>")
let newMp3: Data = try id3TagEditor.write(tag: id3Tag, mp3: <valid mp3 file passed as Data>)
} catch {
print(error)
}
支持的帧
以下列出ID3TagEditor支持的所有官方ID3帧。
.title
.album
.albumArtist
.artist
.composer
.conductor
.contentGrouping
.copyright
.encodedBy
.encoderSettings
.fileOwner
,仅适用于ID3 v2.3/v2.4.lyricist
.mixArtist
.publisher
.subtitle
.beatsPerMinute
.originalFilename
.lengthInMilliseconds
.sizeInBytes
,仅适用于ID3 v2.2/v2.3.genre
.discPosition
.trackPosition
.recordingDayMonth
,仅适用于ID3 v2.2/v2.3.recordingYear
,仅适用于ID3 v2.2/v2.3.recordingHourMinute
,仅适用于ID3 v2.2/v2.3.recordingDateTime
,仅适用于ID3 v2.4.attachedPicture(_ pictureType: ID3PictureType)
,支持同一个标签中多个由ID3PictureType
区分的框架.unsynchronizedLyrics(_ language: ID3FrameContentLanguage)
,支持同一个标签中多个由ID3FrameContentLanguage
区分的框架.comment(_ language: ID3FrameContentLanguage)
,支持同一个标签中多个由ID3FrameContentLanguage
区分的框架
此外,ID3TagEditor支持以下iTunes非官方框架
.iTunesGrouping
,仅适用于ID3 v2.3/v2.4.iTunesMovementName
,仅适用于ID3 v2.3/v2.4.iTunesMovementIndex
,仅适用于ID3 v2.3/v2.4.iTunesMovementCount
,仅适用于ID3 v2.3/v2.4.iTunesPodcastCategory
,仅适用于ID3 v2.3/v2.4.iTunesPodcastDescription
,仅适用于ID3 v2.3/v2.4.iTunesPodcastID
,仅适用于ID3 v2.3/v2.4.iTunesPodcastKeyword
,仅适用于ID3 v2.3/v2.4
所有帧都遵循规范进行编码/格式化
- 文本帧(以大写字母“T”开头的标识符的帧)使用UTF-16编码文本
- 支持自定义编码/格式化帧(例如,recordingDateTime必须始终是ISO88591字符串)
- 支持本地化内容帧(如
.unsynchronizedLyrics
)支持所有ISO-639-2中的语言标识符(有关支持语言列表,请参阅ID3FrameContentLanguage
)。
有关详细信息,请参阅id3规范。
文档
您可以在fabrizioduroni.it上找到完整的API文档。
示例
在以下屏幕截图中,您可以找到提取/更新数据示例。在示例项目中,您将为每个支持的标靶找到示例。您还可以在读写验收测试中找到更多使用示例。
贡献者
bonfa |
chicio |
martinjbaker |
joeljfischer |
BLeeEZ |
NCrusher74 |
Scytalion |
aquaflamingo |
Shabinder |
lordzsolt |
jverkoey |
github-actions[bot] |