Loading...

mp3agic - an id3 library for Java

:heavy_exclamation_mark: This post is older than a year. Consider some information might not be accurate anymore. :heavy_exclamation_mark:

mp3agic is a Java library for reading and writing id3 tags of mp3 files. Ripping your CDs and fetching cd information from MusicBrainz may not be the desired result, especially on compilations. mp3agic allows you to correct the id3 meta-data the Java way.

I got the situation that the artist was Various and the title contains the title and artist. For example:

01 - Wake Me Up - Wham.mp3	[ 4.35 MB ]
-------------------------------------------------------------------------------
Time: 04:05	MPEG1, Layer III	[ 128 kb/s @ 44100 Hz - Stereo ]
-------------------------------------------------------------------------------
ID3 v2.3:
title: Wake Me Up - Wham		artist: Various
album: MyMix	                        year: 1989
track: 1/22

Well you can rely on shell magic and regular expression, or just write a simple JUnit test, that parses the title and set the correct artist tag. Using the library from Michael Patricios was pretty simple and straightforward.

public class RenameTest {
    private static final Logger LOGGER = LoggerFactory.getLogger(RenameTest.class);
    public static final String ARTIST = "artist";
    public static final String TITLE = "title";
    @Test
    public void rename_artist_from_title() throws Exception {
        Path folder = Paths.get("/", "media", "music");
        final List<Path> mp3Files = collectMp3Files(folder);
        for (Path path : mp3Files) {
            Map<String, String> data = parseData(path);
            String fileName = writeNewFile(path, data);
            File file = new File(fileName);
            assertTrue("file was written", file.exists());
            assertEquals("artist is corrected", data.get(ARTIST), readArtist(Paths.get(file.toURI())));
        }
    }
    private String readArtist(Path path) throws InvalidDataException, IOException, UnsupportedTagException {
        Mp3File mp3File = new Mp3File(path.toFile());
        ID3v2 id3v2Tag = mp3File.getId3v2Tag();
        return id3v2Tag.getArtist();
    }
    private String writeNewFile(Path path, Map<String, String> data) throws IOException, NotSupportedException, InvalidDataException, UnsupportedTagException {
        Mp3File mp3File = new Mp3File(path.toFile());
        ID3v2 id3v2Tag = mp3File.getId3v2Tag();
        id3v2Tag.setTitle(data.get(TITLE));
        id3v2Tag.setArtist(data.get(ARTIST));
        StringBuilder newFile = new StringBuilder().append(path.getParent().toAbsolutePath().toString());
        // put in output folder
        newFile.append("/out/");
        //create dir
        File outputDirectory = new File(newFile.toString());
        if (!outputDirectory.exists()) {
            outputDirectory.mkdir();
        }
        String track = id3v2Tag.getTrack(); //returns e.g. "1/22"
        String trackNumber = track.substring(0, track.indexOf('/'));
        newFile.append(String.format("%02d", Integer.valueOf(trackNumber)));
        newFile.append(". ");
        newFile.append(id3v2Tag.getArtist());
        newFile.append(" - ");
        newFile.append(id3v2Tag.getTitle());
        newFile.append(".mp3");
        mp3File.save(newFile.toString());
        return newFile.toString();
    }
    private Map<String, String> parseData(Path path) throws InvalidDataException, IOException, UnsupportedTagException {
        Map<String, String> resultMap = Collections.emptyMap();
        Mp3File mp3file = new Mp3File(path.toFile());
        ID3v2 id3v2Tag = mp3file.getId3v2Tag();
        String info = id3v2Tag.getTitle();
        LOGGER.debug("{} read from id3v2.", info);
        String[] parsedElements = info.split("-");
        if (parsedElements.length > 0) {
            resultMap = new HashMap<>();
            resultMap.put(TITLE, parsedElements[0].trim());
            resultMap.put(ARTIST, parsedElements[1].trim());
        }
        return resultMap;
    }
    private List<Path> collectMp3Files(Path folder) throws IOException {
        List<Path> mp3Files = new ArrayList<>();
        Files.walkFileTree(folder, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                if (file.getFileName().toString().endsWith(".mp3")) {
                    mp3Files.add(file);
                    LOGGER.debug("file {} added.", file);
                }
                return FileVisitResult.CONTINUE;
            }
        });
        return mp3Files;
    }
}
Please remember the terms for blog comments.