ID3TagEditor

repository·main·Indexed 42 days ago

https://github.com/chicio/id3tageditor

A Swift-based library for reading and modifying ID3 tags within MP3 files. Compatible with iOS, macOS, watchOS, tvOS, and Linux, it supports ID3 versions 2.2, 2.3, and 2.4 via dedicated builders (ID32v2TagBuilder, ID32v3TagBuilder, ID32v4TagBuilder). The library provides both high-level content access through ID3TagContentReader and low-level frame access for detailed data manipulation.

Tokens
2.9K
Snippets
6
Records
10
Agent score
54%

What's inside ID3TagEditor

  1. How ID3 tag builders work

    main

    The ID3Tag object is constructed using a builder pattern. You select a builder based on the desired ID3 version (ID32v2TagBuilder, ID32v3TagBuilder, or ID32v4TagBuilder) and chain methods to add various frame types. Each method accepts a specific frame object (e.g., ID3FrameWithStringContent, ID3FrameWithIntegerContent, ID3FrameGenre, ID3FrameAttachedPicture). Finally, call .build() to produce the ID3Tag instance.

    let id3Tag = ID32v3TagBuilder()
        .title(frame: ID3FrameWithStringContent(content: "title V3"))
        .beatsPerMinute(frame: ID3FrameWithIntegerContent(value: 50))
        .genre(frame: ID3FrameGenre(genre: .metal, description: "Metalcore"))
        .build()
  2. Read ID3 tags from an mp3 file

    main

    You can read ID3 tags using the ID3TagEditor class via two primary methods: read(from:) for file paths or read(mp3:) for raw Data.

    Once you have an ID3Tag object, you have two ways to access the content:

    1. High-level content access: Use ID3TagContentReader to easily access common fields like title and artist without dealing with raw frames.
    2. Low-level frame access: Access the frames property on the ID3Tag directly to get full data, including frame identifiers, size, and specific content types.
    // Option 1: Using ID3TagContentReader for easy access
    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() ?? "")
        }
    } catch {
        print(error)
    }
    
    // Option 2: Accessing raw frames directly
    do {
        let id3TagEditor = ID3TagEditor()
        if let id3Tag = try id3TagEditor.read(from: "<valid path to the mp3 file>") {
            print((id3Tag.frames[.title] as? ID3FrameWithStringContent)?.content ?? "")
            print((id3Tag.frames[.artist] as? ID3FrameWithStringContent)?.content ?? "")
        }
    } catch {
        print(error)
    }
  3. Install ID3TagEditor via Swift Package Manager

    main

    Add ID3TagEditor as a dependency in your Package.swift file. This method supports the Linux platform. After adding the dependency, you can build your project using swift build, run executable targets with swift run, or execute tests with swift test.

    // swift-tools-version:6.0
    
    import PackageDescription
    
    let package = Package(
        name: "Demo Ubuntu",
        dependencies: [
            .package(url: "https://github.com/chicio/ID3TagEditor.git", from: "5.0.0")
        ],
        targets: [
            .target(
                name: "Demo Ubuntu",
                dependencies: ["ID3TagEditor"]
            )
        ]
    )
  4. Explore ID3TagEditor examples and demo project

    main

    To understand how to use the library in practice, you can explore the following resources:

    • Demo Project: A comprehensive example covering all supported targets, available in the Demo directory of the repository.
    • Documentation Examples: Detailed usage patterns and code snippets can be found in the Examples article of the official documentation.
  5. Write ID3 tags to an mp3 file

    main

    To write ID3 tags, you must first create a valid ID3Tag using one of the provided tag builders. You cannot instantiate ID3Tag directly.

    1. Create a Tag with a Builder

    Choose the builder corresponding to the ID3 version you need:

    • ID32v2TagBuilder: For ID3 version 2.2
    • ID32v3TagBuilder: For ID3 version 2.3
    • ID32v4TagBuilder: For ID3 version 2.4

    2. Write the Tag

    Use the ID3TagEditor class to write the tag using one of these methods:

    • write(tag:mp3:): Returns the new mp3 as Data.
    • write(tag:to:andSaveTo:): Overwrites an existing file and saves the result to a new path.
    • write(tag:to:): Overwrites the file at the specified path.
    // 1. Build the tag
    let id3Tag = ID32v3TagBuilder()
        .title(frame: ID3FrameWithStringContent(content: "title V3"))
        .artist(frame: ID3FrameWithStringContent(content: "artist V3"))
        .build()
    
    // 2. Write the tag
    do {
        let id3TagEditor = ID3TagEditor()
        
        // Overwrite existing file
        try id3TagEditor.write(tag: id3Tag, to: "<valid path to the mp3 file that will be overwritten>")
        
        // Overwrite and save to a new path
        try id3TagEditor.write(tag: id3Tag, 
                               to: "<valid path to the mp3 file>",
                               andSaveTo: "<new path where you want to save the mp3>")
        
        // Write from Data and get new Data back
        let newMp3: Data = try id3TagEditor.write(tag: id3Tag, mp3: <valid mp3 file passed as Data>)
    } catch {
        print(error)
    }
  6. Supported ID3 Frames in ID3TagEditor

    main

    ID3TagEditor supports a wide range of official ID3 frames and unofficial iTunes frames. All text frames (identifiers starting with a capital 'T') use UTF-16 encoding. Frames requiring specific formatting, such as recordingDateTime (which requires an ISO88591 string), are also supported. Localized content supports all language identifiers defined in ISO-639-2.

    ### Official ID3 Frames
    - `ID3TagEditor/FrameName/title`
    - `ID3TagEditor/FrameName/album`
    - `ID3TagEditor/FrameName/albumArtist` 
    - `ID3TagEditor/FrameName/artist`
    - `ID3TagEditor/FrameName/composer`
    - `ID3TagEditor/FrameName/conductor`
    - `ID3TagEditor/FrameName/contentGrouping`
    - `ID3TagEditor/FrameName/copyright`
    - `ID3TagEditor/FrameName/encodedBy`
    - `ID3TagEditor/FrameName/encoderSettings`
    - `ID3TagEditor/FrameName/fileOwner`
    - `ID3TagEditor/FrameName/initialKey`
    - `ID3TagEditor/FrameName/lyricist`
    - `ID3TagEditor/FrameName/mixArtist`
    - `ID3TagEditor/FrameName/publisher`
    - `ID3TagEditor/FrameName/subtitle`
    - `ID3TagEditor/FrameName/beatsPerMinute`
    - `ID3TagEditor/FrameName/originalFilename`
    - `ID3TagEditor/FrameName/lengthInMilliseconds`
    - `ID3TagEditor/FrameName/sizeInBytes`
    - `ID3TagEditor/FrameName/genre`
    - `ID3TagEditor/FrameName/discPosition`
    - `ID3TagEditor/FrameName/trackPosition`
    - `ID3TagEditor/FrameName/recordingDayMonth`
    - `ID3TagEditor/FrameName/recordingYear`
    - `ID3TagEditor/FrameName/recordingHourMinute`
    - `ID3TagEditor/FrameName/recordingDateTime`
    - `ID3TagEditor/FrameName/attachedPicture(_:)`
    - `ID3TagEditor/FrameName/unsynchronizedLyrics(_:)`
    - `ID3TagEditor/FrameName/comment(_:)`
    
    ### iTunes Unofficial Frames
    - `ID3TagEditor/FrameName/iTunesGrouping`
    - `ID3TagEditor/FrameName/iTunesMovementName`
    - `ID3TagEditor/FrameName/iTunesMovementIndex`
    - `ID3TagEditor/FrameName/iTunesMovementCount`
    - `ID3TagEditor/FrameName/iTunesPodcastCategory`
    - `ID3TagEditor/FrameName/iTunesPodcastDescription`
    - `ID3TagEditor/FrameName/iTunesPodcastID`
    - `ID3TagEditor/FrameName/iTunesPodcastKeywords`