关闭

Java批量修改本地Mp3的名称为Mp3Tag中的歌名

标签: javamp3Java解析Mp3Mp3-Tag
1603人阅读 评论(0) 收藏 举报
分类:

一些我们下载的Mp3歌曲名称是错的,但我们怎么能快速的把这些歌曲的名字修改正确呢。Follow me!

(在实际运行代码时,发现Mp3的Tag中存的信息并不都是准确的,并且有时得到的歌曲名字中有”?”。在网上搜了好久也是没找到解决办法~~)

  1. MP3文件结构的简单介绍
    一个规则的MP3文件大致含有3个部分:

    TAG_V2(ID3V2)
    Frame
    TAG_V1(ID3V1)
    

    其中TAG_V2和TAG_V1这两个部分MP3文件标签信息(歌手,歌曲名,发行时间..)保存的区域

    在这两个部分中,TAG_V2的长度不是固定的,包含了众多关于MP3文件的信息

    而TAG_V1的长度是固定的,128byte.期中包含MP3文件的基本信息.

  2. TAG_V1中包含了什么信息

    字节    长度(字节)  说 明
    1-3       3          存放"TAG"字符,表示ID3V1.0标准
    4-33    30        歌名
    34-63   30        作者
    64-93   30        专辑名
    94-97   4         年份
    98-127  30        附注
    128     1         MP3音乐类别
  3. 实现过程

    1). 根据文件或者文件夹路径,获取所有的文件的文件名;
    2).筛选出其中所有Mp3文件;
    3).循环将Mp3文件的名字修改为在Tag中获取到的Mp3歌曲名。

  4. 代码如下

    Main.java

package com.daidai.main;

import java.io.File;
import java.io.IOException;
import java.util.List;

import com.daidai.util.MP3Info;
import com.daidai.util.Mp3Util;

public class Main {

    public static void main(String[] args) {
        renameMp3Name("E:\\Music");
    }

    public static void renameMp3Name(String sourceStr) {
        // 1、获取所有音乐文件
        String[] fileArgs = Mp3Util.getFiles(sourceStr);

        if (null == fileArgs || fileArgs.length == 0) {
            return;
        }

        // 2.筛选出Mp3文件
        List<String> mp3StrList = Mp3Util.screenMp3Files(fileArgs);

        if (null == mp3StrList || mp3StrList.size() == 0) {
            return;
        }

        // 3.循环修改名字
        MP3Info mp3 = null;
        for (String str : mp3StrList) {
            System.out.println("开始给歌曲文件 " + str + " 改名...");
            try {
                mp3 = new MP3Info(new File(sourceStr + File.separator + str));
            } catch (IOException e) {
                // 有些Mp3文件的Tag格式不符合格式,这些Mp3我们跳过,不进行处理。
                continue;
            }

            Mp3Util.renameMp3(sourceStr + File.separator + str,
                    mp3.getSongName());
        }
    }
}

Mp3Util.java

package com.daidai.util;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class Mp3Util {

    /**
     * 根据路径获取歌曲文件地址,可以是文件或者是文件夹
     * @param sourceDir
     * @return
     */
    public static String[] getFiles(String sourceDir){

        String[] retStrArgs = null;

        File file = new File(sourceDir);

        if(!file.exists()){
            System.out.println("文件或文件夹不存在");
            return retStrArgs;
        }

        if(file.isDirectory()){
            retStrArgs = file.list();
        }else if(file.isFile()){
            retStrArgs = new String[1];
            retStrArgs[0] = sourceDir;
        }

        return retStrArgs;
    }

    /**
     * 筛选Mp3文件,将不是Mp3格式的文件都去除掉
     * @param fileArgs
     */
    public static List<String> screenMp3Files(String[] fileArgs){

        List<String> mp3List = new ArrayList<String>();

        String suffix = "";//后缀

        for(String str : fileArgs){
            suffix = str.substring(str.lastIndexOf(".")+1);

            if("mp3".equalsIgnoreCase(suffix)){
                mp3List.add(str);
            }

        }

        return mp3List;
    }

    /**
     * 给Mp3文件重命名
     * @param oldFileStr    Mp3文件地址
     * @param newName       新名称
     * @return
     */
    public static boolean renameMp3(String oldFileStr, String newName){

        File oldFile = new File(oldFileStr);

        if(!oldFile.exists() || !oldFile.isFile()){
            System.out.println(oldFileStr + "文件不存在!");
            return false;
        }

        String newFileStr = oldFileStr.substring(0, oldFileStr.lastIndexOf(".")) + newName + ".mp3";

        File newFile = new File(newFileStr);

        if(newFile.exists()){

            StringBuilder sb = new StringBuilder();
            sb.append("将文件");
            sb.append(oldFile.getName());
            sb.append("改名为");
            sb.append(newFile.getName());
            sb.append("失败,原因:");
            sb.append(newFile.getName());
            sb.append("已经存在!");

            System.out.println(sb.toString());
            return false;
        }

        StringBuilder sb = new StringBuilder();
        sb.append("将文件");
        sb.append(oldFile.getName());
        sb.append("改名为");
        sb.append(newFile.getName());
        sb.append("成功!");

        System.out.println(sb.toString());

        oldFile.renameTo(newFile); 

        return true;
    }

}

MP3Info.java

package com.daidai.util;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;



/**
 * 获得MP3文件的信息
 * 
 * Mp3 最后128字节存储信息格式:
 *  字节     长度 (字节)  说       明
 *  1-3     3       存放“TAG”字符,表示ID3 V1.0标准,紧接其后的是歌曲信息。
 *  4-33    30      歌名
 *  34-63   30      作者
 *  64-93   30      专辑名
 *  94-97   4       年份
 *  98-127  30      附注
 *  128     1       MP3音乐类别,共147种。
 * 
 */
public class MP3Info {

    private String charset = "UTF-8";//解析MP3信息时用的字符编码

    private byte[] buf;//MP3的标签信息的byte数组

    /**
     * 实例化一个MP3文件的信息的类
     * @param mp3 MP3文件
     * @throws IOException 读取MP3出错则MP3文件不存在
     */
    public MP3Info(File mp3) throws IOException{

        buf = new byte[128];//初始化标签信息的byte数组

        RandomAccessFile raf = new RandomAccessFile(mp3, "r");//随机读写方式打开MP3文件
        raf.seek(raf.length() - 128);//移动到文件MP3末尾
        raf.read(buf);//读取标签信息

        raf.close();//关闭文件

        if(buf.length != 128){//数据是否合法
            System.out.println("MP3标签信息数据长度不合法!");
            throw new IOException("MP3标签信息数据长度不合法!");
        }

        if(!"TAG".equalsIgnoreCase(new String(buf,0,3))){//信息格式是否正确
            System.out.println("MP3标签信息数据格式不正确!");
            throw new IOException("MP3标签信息数据格式不正确!");
        }

    }

    /**
     * 得到歌曲名称
     * @return
     */
    public String getSongName(){
        try {
            return new String(buf,3,30,charset).trim();
        } catch (UnsupportedEncodingException e) {
            return new String(buf,3,30).trim();
        }
    }

    /**
     * 得到专辑名称
     * @return
     */
    public String getArtist(){
        try {
            return new String(buf,33,30,charset).trim();
        } catch (UnsupportedEncodingException e) {
            return new String(buf,33,30).trim();
        }
    }

    public String getAlbum(){
        try {
            return new String(buf,63,30,charset).trim();
        } catch (UnsupportedEncodingException e) {
            return new String(buf,63,30).trim();
        }
    }

    /**
     * 获取年份
     * @return
     */
    public String getYear(){
        try {
            return new String(buf,93,4,charset).trim();
        } catch (UnsupportedEncodingException e) {
            return new String(buf,93,4).trim();
        }
    }

    /**
     * 获取歌曲描述
     * @return
     */
    public String getComment(){
        try {
            return new String(buf,97,30,charset).trim();
        } catch (UnsupportedEncodingException e) {
            return new String(buf,97,30).trim();
        }
    }

    /**
     * 获得目前解析时用的字符编码
     * @return 目前解析时用的字符编码
     */
    public String getCharset() {
        return charset;
    }

    /**
     * 设置解析时用的字符编码
     * @param charset 解析时用的字符编码
     */
    public void setCharset(String charset) {
        this.charset = charset;
    }

}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:144977次
    • 积分:2106
    • 等级:
    • 排名:第18105名
    • 原创:56篇
    • 转载:0篇
    • 译文:0篇
    • 评论:35条
    博客专栏
    文章分类
    最新评论