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






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

          /**
           * 一個(gè)歌曲信息的類的結(jié)構(gòu)表示
           * 這個(gè)歌曲是使用ID3V1的信息存儲(chǔ)結(jié)構(gòu)的
           * 
          @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;//三個(gè)保留位126,127,128
              private boolean valid;//是否合法
              public transient String fileName;//此歌曲對(duì)應(yīng)的文件名,沒有封裝
              public SongInfo(byte[] data) {
                  
          if (data.length != 128) {
                      
          throw new RuntimeException("數(shù)據(jù)長(zhǎng)度不合法:" + data.length);
                  }
                  String tag 
          = new String(data, 03);
                  
          //只有前三個(gè)字節(jié)是TAG才處理后面的字節(jié)
                  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;
              }

              
          /**
               * 得到此對(duì)象的128個(gè)字節(jié)的表示形式
               * 
          @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;
              }

          }

          編輯對(duì)話框的代碼:
          /*
           * 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;//歌曲信息對(duì)象
              private File file;//文件對(duì)象
              private boolean valid;//表示原來這個(gè)文件是不是合法的,如果不是,就要重新寫入128個(gè)字節(jié)
              /** 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(
          "標(biāo)簽"));

                  jLabel1.setText(
          "標(biāo)  題:");

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

                  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格式標(biāo)簽的存取");

                  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");
                      
          //如果這個(gè)文件原來就是合法的,那么就不用新起128個(gè)字節(jié)了
                      if (valid) {
                          raf.seek(raf.length() 
          - 128);
                      } 
          else {//否則就在末層加上128個(gè)字節(jié)
                          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                   
          }


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






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

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

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

          ReadFile 進(jìn)最后 sizeof(Mp3_Tag) 的字節(jié)進(jìn) Mp3_Tag 結(jié)構(gòu)中的話,所有的屬性數(shù)據(jù)就自動(dòng)分配好了,不需要再次手工從哪個(gè)字節(jié)到哪的arrayCopy。

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

          該項(xiàng)目主頁:http://javamusictag.sourceforge.net/

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

          v2的格式變化太多,把玩不來。。  回復(fù)  更多評(píng)論
            
          # re: JAVA寫的MP3標(biāo)簽讀寫器
          2007-12-20 09:46 | live41
          忘了支持樓主一下。。呵呵。。  回復(fù)  更多評(píng)論
            
          # re: JAVA寫的MP3標(biāo)簽讀寫器
          2007-12-28 22:35 |
          真的很不錯(cuò)哦,厲害啊。  回復(fù)  更多評(píng)論
            
          # re: JAVA寫的MP3標(biāo)簽讀寫器
          2008-01-05 13:41 | 思想阻擊手
          你真的不錯(cuò),真想和你合作一起創(chuàng)業(yè)。
          我的博客是http://hexun.com/mlang/default.html  回復(fù)  更多評(píng)論
            
          # re: JAVA寫的MP3標(biāo)簽讀寫器
          2008-01-05 13:42 | 思想阻擊手
          真的不錯(cuò),真想和你一起創(chuàng)業(yè),
          我的博客是http://hexun.com/mlang/default.html
          如果有意請(qǐng)聯(lián)系。  回復(fù)  更多評(píng)論
            
          # re: JAVA寫的MP3標(biāo)簽讀寫器[未登錄]
          2008-03-25 15:21 | h
          請(qǐng)問你用的是jdk的那個(gè)版本,為什么我在javax.swing下找不到GroupLayout,LayoutStyle類呢?   回復(fù)  更多評(píng)論
            
          # re: JAVA寫的MP3標(biāo)簽讀寫器
          2008-03-26 00:26 | 千里冰封
          @h
          你好,我用的是JDK1.6,JDK1.6才加了這個(gè)類,這個(gè)類的布局功能非常強(qiáng)大,netbeans的GUI編輯器就是用它做為缺省的布局管理器  回復(fù)  更多評(píng)論
            
          # re: JAVA寫的MP3標(biāo)簽讀寫器
          2008-10-08 14:50 | luoguo
          強(qiáng)人,很好好學(xué)習(xí)。。  回復(fù)  更多評(píng)論
            
          # re: JAVA寫的MP3標(biāo)簽讀寫器
          2008-10-19 22:33 | yangkezhi110
          強(qiáng)人,,,,我頂死你啦
          佩服  回復(fù)  更多評(píng)論
            
          # re: JAVA寫的MP3標(biāo)簽讀寫器
          2008-12-14 17:35 | jacklee
          好厲害啊,呵呵,佩服  回復(fù)  更多評(píng)論
            
          # re: JAVA寫的MP3標(biāo)簽讀寫器
          2008-12-21 13:06 | liuwei
          能不能把你的那個(gè)music包發(fā)給我啊,謝謝你了
          angelliuwei2004@163.com  回復(fù)  更多評(píng)論
            
          # re: JAVA寫的MP3標(biāo)簽讀寫器
          2008-12-22 01:36 | 張洪偉
          為什么我找不到創(chuàng)建的包啊?
          呵呵!!!
          可不可以把那個(gè)Music包給我拷貝一個(gè)阿!!‘  回復(fù)  更多評(píng)論
            
          # re: JAVA寫的MP3標(biāo)簽讀寫器
          2008-12-22 01:37 | 張洪偉
          郵箱:goonfendou@163.com  回復(fù)  更多評(píng)論
            
          # re: JAVA寫的MP3標(biāo)簽讀寫器
          2008-12-22 20:42 | 千里冰封
          @張洪偉
          上面的代碼就是全部的代碼啊  回復(fù)  更多評(píng)論
            
          # re: JAVA寫的MP3標(biāo)簽讀寫器
          2009-01-05 21:09 | 謝霽軍
          佩服,我什么時(shí)候才能牛起來啊!  回復(fù)  更多評(píng)論
            
          # re: JAVA寫的MP3標(biāo)簽讀寫器
          2009-04-25 01:14 |
          現(xiàn)在正在找這個(gè), 謝啦  回復(fù)  更多評(píng)論
            
          主站蜘蛛池模板: 海兴县| 盖州市| 扎兰屯市| 临泽县| 靖西县| 米易县| 侯马市| 黎城县| 南溪县| 海南省| 景泰县| 新巴尔虎左旗| 桂平市| 潼南县| 道孚县| 蓝山县| 常德市| 铜陵市| 西乡县| 扎囊县| 册亨县| 烟台市| 繁昌县| 石屏县| 南京市| 伊宁县| 金川县| 枞阳县| 吐鲁番市| 丹棱县| 镇沅| 宜都市| 高雄市| 莱西市| 和田市| 维西| 宜丰县| 梧州市| 安宁市| 甘谷县| 若尔盖县|