<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    千里冰封
    JAVA 濃香四溢
    posts - 151,comments - 2801,trackbacks - 0
    前幾天寫了一個NB的音樂插件,自己用了一下,還是挺方便的,后來想想,如果能把歌詞也顯示出來那就更好了。呵呵,怎么辦呢,只有自己寫了,在顯示歌詞之前,必須要知道目前正在播放的MP3是什么內容啊,一點可以從文件名得到一些信息,還有一點就是從MP3文件里面得到這個MP3的信息,我這里實現的ID3V1的格式標簽,APEV2也想實現,無奈找不到相關的資料,不知道APEV2的數據結構是怎么樣的,所以也無從分析。目前已經寫完了ID3V1格式標簽的讀取和寫入。并且NB的音樂插件也實現了本地歌詞的搜索,先把ID3V1的文件結構的類文件帖一下,大家一起分享。
    MP3的ID3V1的信息結構是很有規律的,它一般是出現在MP3文件的最后128個字節上,并且是以“TAG”開頭。我這里把它封裝成一個類了。
    截圖如下:






    代碼如下:
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     
    */
    package com.hadeslee.music;

    /**
     * 一個歌曲信息的類的結構表示
     * 這個歌曲是使用ID3V1的信息存儲結構的
     * 
    @author hadeslee
     
    */
    public class SongInfo {

        
    private final String TAG = "TAG";//文件頭1-3
        private String songName;//歌曲名4-33
        private String artist;//歌手名34-63
        private String album;//專輯名61-93
        private String year;//年94-97
        private String comment;//備注98-125
        private byte r1,  r2,  r3;//三個保留位126,127,128
        private boolean valid;//是否合法
        public transient String fileName;//此歌曲對應的文件名,沒有封裝
        public SongInfo(byte[] data) {
            
    if (data.length != 128) {
                
    throw new RuntimeException("數據長度不合法:" + data.length);
            }
            String tag 
    = new String(data, 03);
            
    //只有前三個字節是TAG才處理后面的字節
            if (tag.equalsIgnoreCase("TAG")) {
                valid 
    = true;
                songName 
    = new String(data, 330).trim();
                artist 
    = new String(data, 3330).trim();
                album 
    = new String(data, 6330).trim();
                year 
    = new String(data, 934).trim();
                comment 
    = new String(data, 9728).trim();
                r1 
    = data[125];
                r2 
    = data[126];
                r3 
    = data[127];
            } 
    else {
                valid 
    = false;
            }
        }

        
    public SongInfo() {
        }

        
    /**
         * 返回是否合法
         * 
    @return 是否
         
    */
        
    public boolean isValid() {
            
    return valid;
        }

        
    /**
         * 得到此對象的128個字節的表示形式
         * 
    @return
         
    */
        
    public byte[] getBytes() {
            
    byte[] data = new byte[128];
            System.arraycopy(TAG.getBytes(), 
    0, data, 03);
            
    byte[] temp = songName.getBytes();
            System.arraycopy(temp, 
    0, data, 3, temp.length > 30 ? 30 : temp.length);
            temp 
    = artist.getBytes();
            System.arraycopy(temp, 
    0, data, 33, temp.length > 30 ? 30 : temp.length);
            temp 
    = album.getBytes();
            System.arraycopy(temp, 
    0, data, 63, temp.length > 30 ? 30 : temp.length);
            temp 
    = year.getBytes();
            System.arraycopy(temp, 
    0, data, 93, temp.length > 4 ? 4 : temp.length);
            temp 
    = comment.getBytes();
            System.arraycopy(temp, 
    0, data, 97, temp.length > 28 ? 28 : temp.length);
            data[
    125= r1;
            data[
    126= r2;
            data[
    127= r3;
            
    return data;
        }

        
    public String getArtist() {
            
    return artist;
        }

        
    public void setArtist(String authorName) {
            
    this.artist = authorName;
        }

        
    public String getComment() {
            
    return comment;
        }

        
    public void setComment(String comment) {
            
    this.comment = comment;
        }

        
    public byte getR1() {
            
    return r1;
        }

        
    public void setR1(byte r1) {
            
    this.r1 = r1;
        }

        
    public byte getR2() {
            
    return r2;
        }

        
    public void setR2(byte r2) {
            
    this.r2 = r2;
        }

        
    public byte getR3() {
            
    return r3;
        }

        
    public void setR3(byte r3) {
            
    this.r3 = r3;
        }

        
    public String getSongName() {
            
    return songName;
        }

        
    public void setSongName(String songName) {
            
    if(songName==null){
                
    throw new NullPointerException("歌名不能是null!");
            }
            valid
    =true;
            
    this.songName = songName;
        }

        
    public String getAlbum() {
            
    return album;
        }

        
    public void setAlbum(String specialName) {
            
    this.album = specialName;
        }

        
    public String getYear() {
            
    return year;
        }

        
    public void setYear(String year) {
            
    this.year = year;
        }

    }

    編輯對話框的代碼:
    /*
     * SongInfoDialog.java
     *
     * Created on 2007年11月26日, 下午4:12
     
    */
    package com.hadeslee.music;

    import java.awt.Dialog;
    import java.awt.Frame;
    import java.io.File;
    import java.io.RandomAccessFile;
    import java.util.logging.Level;
    import java.util.logging.Logger;

    /**
     *
     * 
    @author  hadeslee
     
    */
    public class SongInfoDialog extends javax.swing.JDialog {

        
    private SongInfo info;//歌曲信息對象
        private File file;//文件對象
        private boolean valid;//表示原來這個文件是不是合法的,如果不是,就要重新寫入128個字節
        /** Creates new form SongInfoDialog */
        
    public SongInfoDialog(java.awt.Frame parent, boolean modal) {
            
    super(parent, modal);
            initComponents();
        }

        
    public SongInfoDialog(Dialog parent, boolean modal) {
            
    super(parent, modal);
            initComponents();
        }

        
    public SongInfoDialog(Frame parent, boolean modal, File file) {
            
    this(parent, modal);
            
    this.file = file;
            init();
        }

        
    public SongInfoDialog(Dialog parent, boolean modal, File file) {
            
    this(parent, modal);
            
    this.file = file;
            init();
        }

        
    /**
         * 初始化
         
    */
        
    private void init() {
            
    try {
                fileName.setText(file.toString());
                RandomAccessFile ra 
    = new RandomAccessFile(file, "r");
                
    byte[] buffer = new byte[128];
                ra.seek(ra.length() 
    - 128);
                ra.read(buffer);
                info 
    = new SongInfo(buffer);
                valid 
    = info.isValid();
                title.setText(info.getSongName());
                artist.setText(info.getArtist());
                album.setText(info.getAlbum());
                year.setText(info.getYear());
                comment.setText(info.getComment());
                r2.setText(
    "" + info.getR2());
                r3.setText(
    "" + info.getR3());
                ra.close();
            } 
    catch (Exception ex) {
                Logger.getLogger(SongInfoDialog.
    class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        
    /** This method is called from within the constructor to
         * initialize the form.
         * WARNING: Do NOT modify this code. The content of this method is
         * always regenerated by the Form Editor.
         
    */
        
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
        private void initComponents() {

            jLabel5 
    = new javax.swing.JLabel();
            fileName 
    = new javax.swing.JTextField();
            jPanel1 
    = new javax.swing.JPanel();
            jLabel1 
    = new javax.swing.JLabel();
            title 
    = new javax.swing.JTextField();
            jLabel2 
    = new javax.swing.JLabel();
            artist 
    = new javax.swing.JTextField();
            jLabel3 
    = new javax.swing.JLabel();
            jLabel4 
    = new javax.swing.JLabel();
            album 
    = new javax.swing.JTextField();
            jLabel6 
    = new javax.swing.JLabel();
            r2 
    = new javax.swing.JTextField();
            year 
    = new javax.swing.JTextField();
            jLabel7 
    = new javax.swing.JLabel();
            r3 
    = new javax.swing.JTextField();
            jLabel8 
    = new javax.swing.JLabel();
            jScrollPane1 
    = new javax.swing.JScrollPane();
            comment 
    = new javax.swing.JTextArea();
            jButton1 
    = new javax.swing.JButton();
            jButton2 
    = new javax.swing.JButton();
            jButton3 
    = new javax.swing.JButton();
            jLabel9 
    = new javax.swing.JLabel();

            setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

            jLabel5.setText(
    "文件名:");

            fileName.setEditable(
    false);

            jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(
    "標簽"));

            jLabel1.setText(
    "標  題:");

            jLabel2.setText(
    "藝術家:");

            jLabel3.setText(
    "專  輯:");

            jLabel4.setText(
    "年份:");

            jLabel6.setText(
    "音軌:");

            r2.setEditable(
    false);

            jLabel7.setText(
    "流  派:");

            r3.setEditable(
    false);

            jLabel8.setText(
    "備  注:");

            comment.setColumns(
    20);
            comment.setRows(
    5);
            jScrollPane1.setViewportView(comment);

            javax.swing.GroupLayout jPanel1Layout 
    = new javax.swing.GroupLayout(jPanel1);
            jPanel1.setLayout(jPanel1Layout);
            jPanel1Layout.setHorizontalGroup(
                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanel1Layout.createSequentialGroup()
                            .addComponent(jLabel1)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(title, javax.swing.GroupLayout.PREFERRED_SIZE, 
    183, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGroup(jPanel1Layout.createSequentialGroup()
                            .addComponent(jLabel2)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(artist, javax.swing.GroupLayout.DEFAULT_SIZE, 
    185, Short.MAX_VALUE)
                            .addContainerGap())
                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(jPanel1Layout.createSequentialGroup()
                                    .addComponent(jLabel3)
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                    .addComponent(album, javax.swing.GroupLayout.DEFAULT_SIZE, 
    110, Short.MAX_VALUE))
                                .addGroup(jPanel1Layout.createSequentialGroup()
                                    .addComponent(jLabel7)
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                    .addComponent(r3, javax.swing.GroupLayout.DEFAULT_SIZE, 
    110, Short.MAX_VALUE)))
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(jPanel1Layout.createSequentialGroup()
                                    .addComponent(jLabel4)
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                    .addComponent(year, javax.swing.GroupLayout.PREFERRED_SIZE, 
    31, javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addGroup(jPanel1Layout.createSequentialGroup()
                                    .addComponent(jLabel6)
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                    .addComponent(r2, javax.swing.GroupLayout.PREFERRED_SIZE, 
    30, javax.swing.GroupLayout.PREFERRED_SIZE)))
                            .addContainerGap())
                        .addGroup(jPanel1Layout.createSequentialGroup()
                            .addComponent(jLabel8)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 
    185, Short.MAX_VALUE)
                            .addContainerGap())))
            );
            jPanel1Layout.setVerticalGroup(
                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel1)
                        .addComponent(title, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel2)
                        .addComponent(artist, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel3)
                        .addComponent(r2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jLabel6)
                        .addComponent(album, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel4)
                        .addComponent(year, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jLabel7)
                        .addComponent(r3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanel1Layout.createSequentialGroup()
                            .addComponent(jLabel8)
                            .addContainerGap(
    42, Short.MAX_VALUE))
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 
    57, Short.MAX_VALUE)))
            );

            jButton1.setText(
    "重新讀取文件");
            jButton1.addActionListener(
    new java.awt.event.ActionListener() {
                
    public void actionPerformed(java.awt.event.ActionEvent evt) {
                    jButton1ActionPerformed(evt);
                }
            });

            jButton2.setText(
    "保存到文件");
            jButton2.addActionListener(
    new java.awt.event.ActionListener() {
                
    public void actionPerformed(java.awt.event.ActionEvent evt) {
                    jButton2ActionPerformed(evt);
                }
            });

            jButton3.setText(
    "取消");
            jButton3.addActionListener(
    new java.awt.event.ActionListener() {
                
    public void actionPerformed(java.awt.event.ActionEvent evt) {
                    jButton3ActionPerformed(evt);
                }
            });

            jLabel9.setForeground(
    new java.awt.Color(2550102));
            jLabel9.setText(
    "注:目前只支持ID3v1格式標簽的存取");

            javax.swing.GroupLayout layout 
    = new javax.swing.GroupLayout(getContentPane());
            getContentPane().setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(jLabel5)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(fileName, javax.swing.GroupLayout.DEFAULT_SIZE, 
    221, Short.MAX_VALUE))
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(jButton1)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(jButton2)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(jButton3))
                        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(jLabel9))
                    .addContainerGap())
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel5)
                        .addComponent(fileName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jButton1)
                        .addComponent(jButton2)
                        .addComponent(jButton3))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addComponent(jLabel9)
                    .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            );

            pack();
        }
    // </editor-fold>                        
        private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {                                         
            
    // TODO add your handling code here:
            this.dispose();
        }                                        

        
    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
            
    // TODO add your handling code here:
            doSave();
        }                                        

        
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
            
    // TODO add your handling code here:
            init();
        }                                        

        
    private void doSave() {
            
    try {
                info.setAlbum(album.getText());
                info.setArtist(artist.getText());
                info.setComment(comment.getText());
                info.setR1((
    byte0);
                
    try {
                    info.setR2(Byte.parseByte(r2.getText()));
                    info.setR3(Byte.parseByte(r3.getText()));
                } 
    catch (Exception exe) {
                    exe.printStackTrace();
                }
                info.setYear(year.getText());
                info.setSongName(title.getText());
                RandomAccessFile raf 
    = new RandomAccessFile(file, "rw");
                
    //如果這個文件原來就是合法的,那么就不用新起128個字節了
                if (valid) {
                    raf.seek(raf.length() 
    - 128);
                } 
    else {//否則就在末層加上128個字節
                    raf.seek(raf.length());
                }
                raf.write(info.getBytes());
                raf.close();
                
    this.dispose();
            } 
    catch (Exception ex) {
                Logger.getLogger(SongInfoDialog.
    class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        
    /**
         * 
    @param args the command line arguments
         
    */
        
    public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(
    new Runnable() {

                
    public void run() {
                    SongInfoDialog dialog 
    = new SongInfoDialog(new javax.swing.JFrame(), true);
                    dialog.addWindowListener(
    new java.awt.event.WindowAdapter() {

                        
    public void windowClosing(java.awt.event.WindowEvent e) {
                            System.exit(
    0);
                        }
                    });
                    dialog.setVisible(
    true);
                }
            });
        }
        
    // Variables declaration - do not modify                     
        private javax.swing.JTextField album;
        
    private javax.swing.JTextField artist;
        
    private javax.swing.JTextArea comment;
        
    private javax.swing.JTextField fileName;
        
    private javax.swing.JButton jButton1;
        
    private javax.swing.JButton jButton2;
        
    private javax.swing.JButton jButton3;
        
    private javax.swing.JLabel jLabel1;
        
    private javax.swing.JLabel jLabel2;
        
    private javax.swing.JLabel jLabel3;
        
    private javax.swing.JLabel jLabel4;
        
    private javax.swing.JLabel jLabel5;
        
    private javax.swing.JLabel jLabel6;
        
    private javax.swing.JLabel jLabel7;
        
    private javax.swing.JLabel jLabel8;
        
    private javax.swing.JLabel jLabel9;
        
    private javax.swing.JPanel jPanel1;
        
    private javax.swing.JScrollPane jScrollPane1;
        
    private javax.swing.JTextField r2;
        
    private javax.swing.JTextField r3;
        
    private javax.swing.JTextField title;
        
    private javax.swing.JTextField year;
        
    // End of variables declaration                   
    }


    有歌詞的插件,由于還不是很完善,所以過一兩天再發布,呵呵。:)






    盡管千里冰封
    依然擁有晴空

    你我共同品味JAVA的濃香.
    posted on 2007-11-27 08:51 千里冰封 閱讀(5322) 評論(30)  編輯  收藏 所屬分類: JAVA擴展

    FeedBack:
    # re: JAVA寫的MP3標簽讀寫器[未登錄]
    2007-11-27 09:12 | 阿蜜果
    呵呵,功能越來越完善了  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2007-11-27 11:03 | shaomin
    很強大了
    學習下
    謝謝分享
      回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2007-11-27 11:05 | 隔葉黃鶯
    不錯,只是我還是在思考Java能否借鑒于C/C++的做法,比如定義一個結構
    struct Mp3_Tag{
    char Header[3]; /*標簽頭必須是"TAG"否則認為沒有標簽*/
    char Title[30]; /*標題*/
    char Artist[30]; /*作者*/
    char Album[30]; /*專集*/
    char Year[4]; /*出品年代*/
    char Comment[30]; /*備注*/
    char Genre; /*類型*/
    }

    ReadFile 進最后 sizeof(Mp3_Tag) 的字節進 Mp3_Tag 結構中的話,所有的屬性數據就自動分配好了,不需要再次手工從哪個字節到哪的arrayCopy。

    Java似乎沒法做到這一點,上面代碼可能還需要考慮字節對齊  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2007-11-27 12:10 | BeanSoft
    真不錯啊....都支持顯示歌詞了!!!  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2007-11-27 16:59 | faen
    暈啊,樓主真是無敵了...  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2007-11-28 13:21 | ahfallen
    太牛了  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2007-11-29 10:24 | lizongbo
    Java ID3 Tab Library
    這個包用來讀取歌曲的信息比如:從MP3文件讀取歌曲的標題,藝術家,唱片套.它支持ID3v1, ID3v1.1, Lyrics3v1, Lyrics3v2, ID3v2.2, ID3v2.3,與ID3v2.4 tags.

    該項目主頁:http://javamusictag.sourceforge.net/

      回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2007-11-29 13:22 | 敗者
    請問你用的是jdk的那個版本,為什么我在javax.swing下找不到GroupLayout,LayoutStyle類呢?
      回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2007-11-30 01:27 | 得意門生
    你QQ多少啊樓主,加QQ聊啊,我的是45975656
      回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2007-11-30 18:48 | oracle
    看下,佩服啊  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2007-11-30 23:05 | zhangwin3
    誠懇的謝謝你這樣的人!好人啊 !  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器[未登錄]
    2007-12-04 01:23 | gg
    暈,NB自帶的代碼你也貼啊  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2007-12-15 16:55 |
    太厲害了
      回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2007-12-18 11:34 | 潔白滴黑子
    搞ID3V2的吧,那個玩出來的話會更爽的。  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2007-12-20 09:45 | live41
    “搞ID3V2的吧,那個玩出來的話會更爽的。”

    v2的格式變化太多,把玩不來。。  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2007-12-20 09:46 | live41
    忘了支持樓主一下。。呵呵。。  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2007-12-28 22:35 |
    真的很不錯哦,厲害啊。  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2008-01-05 13:41 | 思想阻擊手
    你真的不錯,真想和你合作一起創業。
    我的博客是http://hexun.com/mlang/default.html  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2008-01-05 13:42 | 思想阻擊手
    真的不錯,真想和你一起創業,
    我的博客是http://hexun.com/mlang/default.html
    如果有意請聯系。  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器[未登錄]
    2008-03-25 15:21 | h
    請問你用的是jdk的那個版本,為什么我在javax.swing下找不到GroupLayout,LayoutStyle類呢?   回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2008-03-26 00:26 | 千里冰封
    @h
    你好,我用的是JDK1.6,JDK1.6才加了這個類,這個類的布局功能非常強大,netbeans的GUI編輯器就是用它做為缺省的布局管理器  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2008-10-08 14:50 | luoguo
    強人,很好好學習。。  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2008-10-19 22:33 | yangkezhi110
    強人,,,,我頂死你啦
    佩服  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2008-12-14 17:35 | jacklee
    好厲害啊,呵呵,佩服  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2008-12-21 13:06 | liuwei
    能不能把你的那個music包發給我啊,謝謝你了
    angelliuwei2004@163.com  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2008-12-22 01:36 | 張洪偉
    為什么我找不到創建的包啊?
    呵呵!!!
    可不可以把那個Music包給我拷貝一個阿!!‘  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2008-12-22 01:37 | 張洪偉
    郵箱:goonfendou@163.com  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2008-12-22 20:42 | 千里冰封
    @張洪偉
    上面的代碼就是全部的代碼啊  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2009-01-05 21:09 | 謝霽軍
    佩服,我什么時候才能牛起來啊!  回復  更多評論
      
    # re: JAVA寫的MP3標簽讀寫器
    2009-04-25 01:14 |
    現在正在找這個, 謝啦  回復  更多評論
      
    主站蜘蛛池模板: 最近2019中文字幕mv免费看| 午夜不卡久久精品无码免费| 毛片免费观看的视频在线| 日产亚洲一区二区三区| 亚洲一区二区在线免费观看| 久久久久亚洲AV成人无码 | 色偷偷亚洲第一综合| 日韩成全视频观看免费观看高清| 久久精品国产亚洲AV忘忧草18| 国产在线jyzzjyzz免费麻豆| 亚洲欧洲视频在线观看| 成人片黄网站A毛片免费| 中文字幕在线观看亚洲视频| 免费无码成人AV片在线在线播放| 亚洲av日韩综合一区久热| 国产禁女女网站免费看| 乱人伦中文视频在线观看免费| 亚洲成A∨人片天堂网无码| 一级毛片免费一级直接观看| 国产亚洲自拍一区| 99精品视频在线免费观看| 亚洲国产精品综合福利专区| 在线观看成人免费视频| 国产亚洲综合精品一区二区三区| 亚洲狠狠爱综合影院婷婷| 中文在线观看永久免费| 亚洲美女视频免费| 国产成人综合久久精品免费| 丝袜足液精子免费视频| 亚洲日本国产精华液| 国产精品无码免费视频二三区| 二个人看的www免费视频| 亚洲综合精品香蕉久久网97| 成人毛片免费视频| 亚洲精品偷拍视频免费观看| 91亚洲精品第一综合不卡播放| 免费看少妇作爱视频| 两个人看的www高清免费视频| 91亚洲性爱在线视频| 亚洲最大av无码网址| 91手机看片国产永久免费|