Giter Club home page Giter Club logo

id3-json's Introduction

Build Status

ID3-JSON

This project's goal is to provide an easy way to read and write ID3 tags with a consistent input and output. The existing tools I've found require a lot of work to parse their output and work in inconsistent ways, so I'm making another one.

The main client of this project is going to be a Vim plugin: https://github.com/AndrewRadev/id3.vim. That said, there's no particular reason not to use it for whatever. I'd like to keep the tool general-purpose, so if you're looking for some specific functionality, please open a github issue.

The project is backed by the excellent id3 crate built in Rust. Really, the tag parsing and writing logic is all there -- the code here mostly just translates the data to/from JSON (though I do make some assumptions, see Quirks below).

Installation

If you have the Rust toolchain installed, you can install it from crates.io:

$ cargo install id3-json

But you can also use the precompiled binary for your operating system from the releases tab in github: https://github.com/AndrewRadev/id3-json/releases:

Basic usage

Running the program with --help should provide a message along these lines.

id3-json 0.2.1

USAGE:
    id3-json [FLAGS] <music-file.mp3>

FLAGS:
    -r, --read       Reads tags from the file and outputs them to STDOUT as JSON.
                     If neither `read` nor `write` are given, will read by default.

    -w, --write      Write mode, expects a JSON on STDIN with valid tag values.
                     If also given `read`, will print the resulting tags afterwards

        --tag-version <ID3v2.{2,3,4}>
                     On write, sets the tags' version to 2.2, 2.3, or 2.4.

    -V, --version    Prints version information

ARGS:
    <music-file.mp3>    Music file to read tags from or write tags to

The input to write to a tag should be a valid json with "title", "artist", etc as keys. The output will be a JSON object that has a "data" key and inside has all these fields set. Here's some example output, pretty-printed using the jq tool:

% id3-json tests/fixtures/attempt_1.mp3 | jq .
{
  "data": {
    "album": "Echoes From The Past",
    "artist": "Christiaan Bakker",
    "comment": "http://www.jamendo.com Attribution 3.0 ",
    "date": null,
    "genre": "(255)",
    "title": "Elevator Music Attempt #1",
    "track": null
  },
  "version": "ID3v2.4"
}

Here's how we can update the title and track number, and remove the genre. The tool will print the tags after the change (because of --read):

% echo '{ "title": "[updated]", "track": 1, "genre": null }' | id3-json tests/fixtures/attempt_1.mp3 --write --read | jq .
{
  "data": {
    "album": "Echoes From The Past",
    "artist": "Christiaan Bakker",
    "comment": "http://www.jamendo.com Attribution 3.0 ",
    "date": null,
    "genre": null,
    "title": "[updated]",
    "track": 1
  },
  "version": "ID3v2.4"
}

Quirks

The numbers given to the "year" field in set_year seem to be i32, but for simplicity, I assume years are going to be positive numbers.

If the tags are ID3v2.4, the tool will read and write the "date" field as "date recorded" (TDRL). See the relevant github issue for the conversation: #1. Seems like both picard and easy tag use that field, which is why I chose it.

It's still a bit up in the air, I might end up dealing with both "date recorded" and "date released" as separate fields, though I can't help but wonder how many people care and would be happy to just have "date". For a tag that's not v2.4, it'll return "year" from the TYER tag instead.

It's possible to have multiple comments with a "description", "lang", and "text". See the frame::Comment structure for details. However, at least in my personal music library, it seems almost all mp3 files contain a single comment with "" for the description. Some of them have another one that's labeled as "ID3v1 comment".

For simplicity's sake I've decided to have id3-json read and write that one comment with a description of "". All other comments should be preserved, so if anything else reads them, it should still work as expected.

Potential future changes

For now, this interface works for me, but if other people need to use it without some of my design choices, a --raw or --full option could be implemented to just read and write the frames as-is with minimal processing and leave it to the client of the tool to decide how to manage them.

Batch processing is another direction I could take this, returning a JSON array with an entry for each filename (or an object with filenames as keys?) and, when writing, expecting a corresponding array/object.

A lot of other metadata could also be read/written, the specific fields I've chosen are just what I used to use from a different utility.

Music used for testing:

id3-json's People

Contributors

andrewradev avatar

Stargazers

Péter Finta avatar Rowe Morehouse avatar  avatar tea avatar 莊喬 avatar  avatar

Watchers

 avatar James Cloos avatar  avatar

id3-json's Issues

year is shown as null in ID3v2.4 tagged file

id3-json -r 10.\ the\ masochism\ tango.mp3 | jq . outputs this:

{
  "data": {
    "album": "An Evening Wasted With Tom Lehrer",
    "artist": "Tom Lehrer",
    "comment": null,
    "genre": "Comedy",
    "title": "The Masochism Tango",
    "track": 10,
    "year": null
  }
}

while picard shows this:

screenshot picard showing the date as 1990-04-12

It happens with this file: testfile.zip (it's in the public domain)

% ./id3-json -V
id3-json 0.1.2

I'm not very familiar with id3 tags, but the issue appears to be that v2.4 replaced the year tags (TORY and TYER) with time tags (TDOR and TDRL). Maybe they should be used if the year tags are not found?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.