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

原创 2015年11月17日 18:21:28

一些我们下载的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;
    }

}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Java--语言应用--批量修改MP3的文件名、标题

从网上下了些脱口秀mp3,准备回家的时候在路上听听。下载之后发现文件名都是以“某某网整理”开头,导入到手机之后歌名长得连有用的信息都看不到了。不想一个个改了,于是敲了几行java,来了个批量重命名,有...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

开源IndexR:如何对上千亿的数据进行秒级探索式分析

目前,行业中的大数据分析架构一般使用基于 Hadoop 体系的分布式计算引擎 + 分布式存储系统架构(如下图)。 Hadoop 体系的架构特点是上层解决计算问题,下层解决存储...
  • xinzhi8
  • xinzhi8
  • 2017年06月16日 10:14
  • 592

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

使用Saiku+Kylin构建多维分析OLAP平台

http://lxw1234.com/archives/2016/05/647.htm 关于Kylin的介绍和使用请参考之前的文章 《分布式大数据多维分析(OLAP)引擎Apache Kyli...
  • zoubf
  • zoubf
  • 2016年08月03日 16:54
  • 10445

批量修改MP3 Tag

  • 2015年07月02日 09:32
  • 649KB
  • 下载

Android开发本地及网络Mp3音乐播放器(十三)网络音乐搜索功能实现,歌名歌手专辑名搜索

实现功能: 实现网络音乐搜索功能 使用观察者设计模式 使用URLEncoder.encode转码 SearchMusicUtils是重点 截止到目前的源码下载: http://download.c...

Android 播放mp3 tag乱码分析之java 篇

    在Java程序中的字符,不管是中文的还是英文的,都是占用二个字节,这个结论我们大家都烂熟于心了,但是纠结是为什么呢?    其实是因为 char 类型就好比双字节的无符号整数  。    UT...

MP3 Tag 修改器

  • 2006年03月16日 00:00
  • 195KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java批量修改本地Mp3的名称为Mp3Tag中的歌名
举报原因:
原因补充:

(最多只允许输入30个字)