java检测重复音乐文件
随手记
问题背景
闲来无事,把电脑各个角落的音乐文件全部搬到一个文件中,便于管理。
但是问题来了,近千首歌曲,其中有一些是重复的,需要去掉。

解决思路
作为程序员,肯定不会通过人力去查找的啦,于是,不妨写个程序去帮我找?
java如何读取音乐信息?git上一搜,随便下载了demo,然后按照自己的需求魔改下,成品就出来了,嘿嘿
git项目地址:https://gitee.com/clj9509/imusic.git
怎么判断音乐文件是否相同?
需要用到一个工具类jaudiotagger,maven地址:
<dependency>
<groupId>org</groupId>
<artifactId>jaudiotagger</artifactId>
<version>2.0.3</version>
</dependency>
读取音乐文件信息的代码如下:
private static final String SONG_NAME_KEY = "TIT2";
private static final String ARTIST_KEY = "TPE1";
private static final String ALBUM_KEY = "TALB";
static Music getMusicInfo(File file) throws Exception {
Music music = null;
try {
String name = file.getName();
String songName;
// 歌手名称
String artist = "";
// 歌曲专辑
String album = "";
// 播放时长
int duration = 0;
if (name.toUpperCase().contains(".FLAC")) {
AudioFile audioFile = AudioFileIO.read(file);
if (!audioFile.getTag().getFields("ALBUM").isEmpty()) {
album = String.valueOf(audioFile.getTag().getFields("ALBUM").get(0));
}
artist = String.valueOf(audioFile.getTag().getFields("ARTIST").get(0));
songName = String.valueOf(audioFile.getTag().getFields("TITLE").get(0));
} else if (name.toUpperCase().contains(".MP3")) {
MP3File mp3File = (MP3File) AudioFileIO.read(file);
MP3AudioHeader audioHeader = (MP3AudioHeader) mp3File.getAudioHeader();
// 歌曲名称
songName = getInfoFromFrameMap(mp3File, SONG_NAME_KEY);
// 歌手名称
artist = getInfoFromFrameMap(mp3File, ARTIST_KEY);
// 歌曲专辑
album = getInfoFromFrameMap(mp3File, ALBUM_KEY);
// 播放时长
duration = audioHeader.getTrackLength();
} else {
//m4a 等格式不适配
return null;
}
if (songName == null || songName.trim().length() <= 0) {
return null;
}
if (artist != null) {
artist = artist.toUpperCase();
}
songName = songName.toUpperCase();
album = album.toUpperCase();
// 封装到music对象
music = new Music(songName, artist, album, duration, file.length(), file.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
System.out.println("文件读取失败!" + e);
}
return music;
}
private static String getInfoFromFrameMap(MP3File mp3File, String key) {
ID3v23Frame frame = (ID3v23Frame) mp3File.getID3v2Tag().frameMap.get(key);
return frame == null ? null : frame.getContent();
}
判断文件是否一样的代码如下:
private static final String Dir = "E:\\音乐\\";
@Test
public void getMusicInfoByDir() throws Exception {
File file = new File(Dir);
File[] musics = file.listFiles();
//所有音乐
Map<String, Music> allMusicMap = new HashMap<>();
//相同的音乐
Map<String, Music> sameMusicMap = new LinkedHashMap<>();
//读取信息失败的音乐
List<String> emptyMusicList = new LinkedList<>();
int len = musics.length;
for (int i = 0; i < len; i++) {
File m = musics[i];
Music music = MusicUtil.getMusicInfo(m);
if (music == null) {
emptyMusicList.add(m.getAbsolutePath());
continue;
}
if (allMusicMap.get(music.getKey()) != null) {
if (sameMusicMap.get(allMusicMap.get(music.getKey()).toString()) == null) {
sameMusicMap.put(allMusicMap.get(music.getKey()).toString(), allMusicMap.get(music.getKey()));
}
sameMusicMap.put(music.toString(), music);
} else {
allMusicMap.put(music.getKey(), music);
}
System.out.println("处理进度:" + (i + 1) + " / " + len);
}
System.out.println("**********全部音乐**************");
// allMusicMap.forEach((k, v) -> System.out.println(v.toString()));
System.out.println("**********相同音乐**************");
sameMusicMap.forEach((k, v) -> System.out.println(v.toString()));
System.out.println("**********其他音乐**************");
// emptyMusicList.forEach(System.out::println);
}
处理结果

成品地址:
浙公网安备 33010602011771号