读取MP3详情信息

来源:互联网 发布:洋气的淘宝童装店名字 编辑:程序博客网 时间:2024/05/17 07:16

做之前,都没有想到读取MP3额外信息竟然如此简单,看来有时候技术真的就是一层玻璃纸,捅破了就没有什么秘密感.

类ExtractMusic:

public class ExtractMusic {
    public static void main(String[] args) throws IOException {
        //就用梁静茹的歌做个示例
        String path = new String("d://慢慢来比较快.mp3");
        /**
         * RandomAccessFile(String name, String mode) 
         * 
         * name:指定文件,不用多说了
         * mode:访问模式("r"、"rw"、"rws" 或 "rwd" ),"r"代表只读
         */
        RandomAccessFile read = new RandomAccessFile(path, "r");
        /**
         * public void seek(long pos)  throws IOException
         * pos:文件指针偏移量
         * MP3的最后128个字节用来存储额外信息,详情请看
         * (http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm#MPEGTAG)
         */
        read.seek(read.length()-128);    //将文件指针定位到最后128个字节的位置,准备读取
        byte[] buffer = new byte[128];    //准备存储最后128个字节
        /**
         * public final void readFully(byte[] b)  throws IOException
         * b:从当前文件指针开始,将 b.length 个字节读到 b中
         */
        read.readFully(buffer);
        MusicInfo info = new MusicInfo(buffer);//用MusicInfo类来封装buffer的数据
        if(info.isValid()){    //判断数据的合法性,以及封装数据
            System.out.println("title:" + info.getTitle());
            System.out.println("artist:" + info.getArtist());
            System.out.println("album:" + info.getAlbum());
            System.out.println("year:"  + info.getYear());
            System.out.println("comment:" + info.getComment());
            //在MusicInfo中,虽然有genre的成员,但是并没有给其数据,所以输出为null
            System.out.println(info.getGenre());
        }
        
        /**
              输出:
                 title:慢慢来比较快
                artist:梁静茹
                album:情歌没有告诉你
                year:2010
                comment:WWW.TOP100.CN 巨鲸音乐网
                null
         */
    }
} 

类MusicInfo:

 

public class MusicInfo {
    
    private final String TAG = "TAG";
    private String title;
    private String artist;
    private String album;
    private String year;
    private String comment;
    private String genre;
    
    private byte[] buffer = null;
    public MusicInfo() {}
    
    public MusicInfo(byte[] buffer) { 
        this.buffer = buffer; //接受buffer
    }
    
    public boolean isValid() throws UnsupportedEncodingException{
        /**
          http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm#MPEGTAG
          MP3格式最后128个字节存储方式,
          
            Sign    Length
            (bytes)    Position
            (bytes)    Description
            A    3    (0-2)    Tag identification. Must contain 'TAG' if tag exists and is correct.
            B    30    (3-32)    Title
            C    30    (33-62)    Artist
            D    30    (63-92)    Album
            E    4    (93-96)    Year
            F    30    (97-126)    Comment
            G    1    (127)    Genre
          由于规定前3个字节是TAG,所以如果只想简单的校验数据,只需判断TAG是否存在就行了
         */
        String flag = new String(this.buffer,0,3);
        if(TAG.equals(flag)){        //如果存在,封装数据
            /**
              中文歌曲,而且额外信息中也包含中文,需要手动用gb18030编码,详情请看:
              http://baike.baidu.com/view/889058.htm
             */
            this.title = new String(this.buffer,3,30,"gb18030").trim();
            this.artist = new String(this.buffer,33,30,"gb18030").trim();
            this.album = new String(this.buffer,63,30,"gb18030").trim();
            this.year = new String(this.buffer,93,4,"gb18030").trim();
            this.comment = new String(this.buffer,97,30,"gb18030").trim();
            /**
               没有对genre成员赋值,因为这1个字节里面存的不是流派的直接值,类似于索引值
                0    'Blues'    20    'Alternative'    40    'AlternRock'    60    'Top 40'
                1    'Classic Rock'    21    'Ska'    41    'Bass'    61    'Christian Rap'
                2    'Country'    22    'Death Metal'    42    'Soul'    62    'Pop/Funk'
                3    'Dance'    23    'Pranks'    43    'Punk'    63    'Jungle'
                4    'Disco'    24    'Soundtrack' ...
                ...
                
                这里就不进行处理了
             */
            //this.genre = this.buffer[127];
            return true;
        }
        return false;
    }
    public String getTitle() {
        return title;
    }
    public String getArtist() {
        return artist;
    }
    public String getAlbum() {
        return album;
    }
    public String getYear() {
        return year;
    }
    public String getComment() {
        return comment;
    }
    public String getGenre() {
        return genre;
    }
}