Question

I need a way to change id3 tag version of mp3 files to some id3v2.x programatically, preferably using java though anything that works is better than nothing. Bonus points if it converts the existing tag so that already existing data isn't destroyed, rather than creating a new tag entirely.

Edit: Jaudiotagger worked, thanks. Sadly I had to restrict it to mp3 files and only saving data contained in previous tags if they were id3. I decided to convert the tag to ID3v2.3 since windows explorer can't handle v2.4, and it was a bit tricky since the program was a bit confused about whether to use the copy constructor or the conversion constructor.

MP3File mf = null;
try {
    mf = (MP3File)AudioFileIO.read(new File(pathToMp3File));
} catch (Exception e) {}
ID3v23Tag tag;
if (mf.hasID3v2Tag()) tag = new ID3v23Tag(mf.getID3v2TagAsv24());
else if (mf.hasID3v1Tag()) tag = new ID3v23Tag(mf.getID3v1Tag());
else tag = new ID3v23Tag();
Was it helpful?

Solution 2

You can use different libraries for this purpose, for example this or this.

OTHER TIPS

My application must be able to read id3v1 or id3v11, but shall only write v23, so I needed a little bit longer piece of code:

    AudioFile mf;
    Tag mTagsInFile;
    ...
    mf = ...   // open audio file the usual way
    ...
    mTagsInFile = mf.getTag();
    if (mTagsInFile == null)
    {
        //contrary to getTag(), getTagOrCreateAndSetDefault() ignores id3v1 tags
        mTagsInFile = mf.getTagOrCreateAndSetDefault();
    }

    // mp3 id3v1 and id3v11 are suboptimal, convert to id3v23
    if (mf instanceof MP3File)
    {
        MP3File mf3 = (MP3File) mf;
        if (mf3.hasID3v1Tag() && !mf3.hasID3v2Tag())
        {
            // convert ID3v1 tag to ID3v23
            mTagsInFile = new ID3v23Tag(mf3.getID3v1Tag());
            mf3.setID3v1Tag(null);      // remove v1 tags
            mf3.setTag(mTagsInFile);    // add v2 tags
        }
    }

Basically we have to know that getTagOrCreateAndSetDefault() and similar unfortunately ignores id3v1, so we first have to call getTag(), and only if this fails, we call the mentioned function. Additionally, the code must also deal with flac and mp4, so we make sure to do our conversion only with mp3 files. Finally there is a bug in JaudioTagger. You may replace this line

                String genre = "(" + genreId + ") " + GenreTypes.getInstanceOf().getValueForId(genreId);

in "ID3v24Tag.java" with this one

                String genre = GenreTypes.getInstanceOf().getValueForId(genreId);

Otherwise genre 12 from idv1 will get "(12) Other" which later is converted to "Other Other" and this is not what we would expect. Maybe someone has a more elegant solution.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top