日本好好热aⅴ|国产99视频精品免费观看|日本成人aV在线|久热香蕉国产在线

  • <cite id="ikgdy"><table id="ikgdy"></table></cite>
    1. 西西軟件園多重安全檢測(cè)下載網(wǎng)站、值得信賴的軟件下載站!
      軟件
      軟件
      文章
      搜索

      首頁編程開發(fā)java → 用JAVA編寫MP3解碼器——解析文件信息

      用JAVA編寫MP3解碼器——解析文件信息

      相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來源:本站整理時(shí)間:2010/8/19 12:20:33字體大小:A-A+

      作者:佚名點(diǎn)擊:914次評(píng)論:1次標(biāo)簽: JAVA MP3

      • 類型:行業(yè)軟件大。7.3M語言:中文 評(píng)分:10.0
      • 標(biāo)簽:
      立即下載

      前文提到解析MP3標(biāo)簽,程序源碼中也已經(jīng)出現(xiàn)了調(diào)用解析MP3標(biāo)簽、打印MP3文件信息的功能,這兒先說說MP3文件信息的解析。

      解析MP3的文件信息對(duì)MP3解碼器來說只是一個(gè)附加功能,如果不加入這部分源碼,同時(shí)刪除掉前文源碼中的相關(guān)調(diào)用,不影響解碼播放。如果你想編寫“迷你”型的MP3解碼器,可以忽略這些附加的功能。

      MP3的標(biāo)簽信息位于文件開始處或結(jié)尾處,用于表達(dá)MP3文件的相關(guān)信息,常見的有ID3、APE等。

       

      ID3 V1 位于文件最后的128字節(jié),共表示7個(gè)信息:

      [0-2] 3 bytes: ID3 v1標(biāo)識(shí) -- 'TAG'
      [3—32] 30 bytes: 標(biāo)題
      [33—62] 30 bytes: 藝術(shù)家
      [63—92] 30 bytes: 專輯名
      [93—96] 4 bytes: 發(fā)行年份
      [97—126] 30 bytes: v1.0 -- 注釋/附加/備注信息
      v1.1 -- 前29 bytes注釋/附加/備注信息,最后1 byte音軌信息

      [127] 1 byte : 流派

      從“標(biāo)題”開始,每部分內(nèi)容之間用'\0'(字符串結(jié)束標(biāo)志)或'\20'(空格)隔開。

       

      ID3 V2 表示的信息更豐富,結(jié)構(gòu)更復(fù)雜,位于文件開始處或位于APE標(biāo)簽之后。ID3 V2的詳細(xì)內(nèi)容請(qǐng)參見http://www.id3.org/id3v2.3.0

      APE V1 & V2 位于文件開始處或ID3 V2之后。詳細(xì)內(nèi)容請(qǐng)參見http://cn.bing.com/reference/semhtml/APE_tag(External links下的鏈接就是APE V2)

       

      本文只解析ID3 V1的那幾項(xiàng)簡單的內(nèi)容,JAVA的字符集轉(zhuǎn)換很方便,所以解析ID3 V2的代碼很簡潔。ID3 V2的每一幀都以“Frame ID”開始,例如TT2或TIT2表示“標(biāo)題”,程序中通過計(jì)算ID的哈希值來識(shí)別不同的幀。ID3Tag.java源碼:

      Java代碼
      package tag;

      import java.io.UnsupportedEncodingException;

      public final class ID3Tag {
      // ID3v1 & ID3v2
      private String strTitle;
      private String strArtist;
      private String strAlbum;
      private String strYear;

      // ID3v2
      //private String strLyrics; // (內(nèi)嵌)歌詞
      private int intVersion;
      private int intExHeaderSize;
      private boolean boolID3v2Footer;
      //TEXT_ENCODING[0]應(yīng)由 "ISO-8859-1" 改為 "GBK". ??
      private static String[] TEXT_ENCODING = {"GBK", "UTF-16", "UTF-16BE", "UTF-8"};

      //--------------------------------------------------------------------
      // ID3v1 & ID3v2

      public void printTag() {
      //if (strLyrics != null)
      // System.out.println("\r" + strLyrics + "\n");
      if (strTitle != null)
      System.out.println("\r 標(biāo)題: " + strTitle);
      if (strArtist != null)
      System.out.println("\r 藝術(shù)家: " + strArtist);
      if (strAlbum != null)
      System.out.println("\r 唱片集: " + strAlbum);
      if (strYear != null)
      System.out.println("\r 發(fā)行年: " + strYear);
      }

      public void destroy() {
      strTitle = strArtist = strAlbum = strYear = null;
      //strLyrics = null;
      intVersion = intExHeaderSize = 0;
      boolID3v2Footer = false;
      }

      //--------------------------------------------------------------------
      // ID3v1

      public boolean checkID3V1(byte[] b) {
      return b[0] == 'T' && b[1] == 'A' && b[2] == 'G';
      }

      public void parseID3V1(byte[] b) {
      if (b.length < 128 || checkID3V1(b) == false)
      return;

      byte[] buf = new byte[125];
      System.arraycopy(b, 3, buf, 0, 125);
      for (int i = 0; i < buf.length; i++)
      if (buf[i] == 0)
      buf[i] = 0x20; //空格

      if (strTitle == null)
      strTitle = new String(buf, 0, 30).trim();
      if (strTitle.length() == 0)
      strTitle = null;

      if (strArtist == null)
      strArtist = new String(buf, 30, 30).trim();
      if (strArtist.length() == 0)
      strArtist = null;

      if (strAlbum == null)
      strAlbum = new String(buf, 60, 30).trim();
      if (strAlbum.length() == 0)
      strAlbum = null;

      if (strYear == null)
      strYear = new String(buf, 90, 4).trim();
      if (strYear.length() == 0)
      strYear = null;

      buf = null;
      }

      //--------------------------------------------------------------------
      // ID3v2

      public int checkID3V2(byte[] b, int off) {
      if(b.length - off < 10)
      return 0;
      if(b[off] != 'I' || b[off+1] != 'D' || b[off+2] != '3')
      return 0;

      intVersion = b[off+3] & 0xff;

      if(intVersion > 2 && (b[off+5] & 0x40) != 0)
      intExHeaderSize = 1; //設(shè)置為1表示有擴(kuò)展頭

      boolID3v2Footer = (b[off+5] & 0x10) != 0;
      int size = synchSafeInt(b, off+6);
      size += 10; // ID3 header:10bytes
      return size;
      }

      //b[off..]不含ID3v2 頭(10 bytes)
      public void parseID3V2(byte[] b, int off) {
      int max_size = b.length;
      int pos = off;
      if(intExHeaderSize == 1) {
      intExHeaderSize = synchSafeInt(b, off);
      pos += intExHeaderSize;
      }
      max_size -= 10; //1 frame header: 10 bytes
      if(boolID3v2Footer)
      max_size -= 10;

      //System.out.println("ID3 v2." + intVersion);
      while(pos < max_size)
      pos += getText(b, pos, max_size);
      }

      private int synchSafeInt(byte[] b, int off) {
      int i = (b[off] & 0x7f) << 21;
      i |= (b[off+1] & 0x7f) << 14;
      i |= (b[off+2] & 0x7f) << 7;
      i |= b[off+3] & 0x7f;
      return i;
      }

      private int makeInt(byte[] b, int off, int len) {
      int i, ret = b[off] & 0xff;
      for (i = 1; i < len; i++) {
      ret <<= 8;
      ret |= b[off + i] & 0xff;
      }
      return ret;
      }

      private int getText(byte[] b, int off, int max_size) {
      int id_part = 4, frame_header = 10;
      if(intVersion == 2) {
      id_part = 3;
      frame_header = 6;
      }
      String id = new String(b, off, id_part);
      off += id_part;

      int fsize, len;
      fsize = len = makeInt(b, off, id_part);
      off += id_part; // frame size = frame id bytes
      if (intVersion > 2)
      off += 2; // flag: 2 bytes

      int en = b[off];
      len--; // Text encoding: 1 byte
      off++; // Text encoding: 1 byte
      if (len <= 0 || off + len > max_size || en < 0 || en >= TEXT_ENCODING.length)
      return fsize + frame_header;
      //System.out.println(len+" ------------------------------------ off = " + off);
      //System.out.println("ID: " + id + ", id.hashCode()=" + id.hashCode());
      //System.out.println("text encoding: " + TEXT_ENCODING[en]);
      //System.out.println("frame size: " + fsize);

      try {
      switch(id.hashCode()) {
      case 83378: //TT2 v2.2
      case 2575251: //TIT2 標(biāo)題
      if (strTitle == null)
      strTitle = new String(b, off, len, TEXT_ENCODING[en]).trim();
      break;
      case 83552:
      case 2590194: //TYER 發(fā)行年
      if (strYear == null)
      strYear = new String(b, off, len, TEXT_ENCODING[en]).trim();
      break;
      case 2569358: //TCON 流派
      break;
      case 82815:
      case 2567331: //TALB 唱片集
      if (strAlbum == null)
      strAlbum = new String(b, off, len, TEXT_ENCODING[en]).trim();
      break;
      case 83253:
      case 2581512: //TPE1 藝術(shù)家
      if (strArtist == null)
      strArtist = new String(b, off, len, TEXT_ENCODING[en]).trim();
      break;
      case 2583398: //TRCK 音軌
      break;
      /*case 2614438: //USLT 歌詞
      off += 4; //Languge: 4 bytes
      len -= 4;
      strLyrics = new String(b, off, len, TEXT_ENCODING[en]);
      break;*/
      }
      } catch (UnsupportedEncodingException e) {
      return fsize + frame_header;
      } finally {
      id = null;
      }
      return fsize + frame_header;
      }
      }

        PPT圖表
        (111)PPT圖表
        我們?cè)谥谱鞲黝惖臅r(shí)候,或多或少的都能用到圖表。圖表它可以直觀的展示出各種信息數(shù)據(jù),有了圖表你就可以很好的將數(shù)據(jù)更直觀準(zhǔn)確的表達(dá)出來。小編在這里為大家搜集整理了一些大家可能會(huì)用到的圖表模板,歡迎有需要的各位前來下載。...更多>>

        相關(guān)評(píng)論

        閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

        • 8 喜歡喜歡
        • 3 頂
        • 1 難過難過
        • 5 囧
        • 3 圍觀圍觀
        • 2 無聊無聊

        熱門評(píng)論

        最新評(píng)論

        第 1 樓 四川成都鐵通ADSL 網(wǎng)友 客人 發(fā)表于: 2011/6/15 11:11:52
        有點(diǎn)忘了,但是我想學(xué)的欲望又被燃燒了

        支持( 0 ) 蓋樓(回復(fù))

        發(fā)表評(píng)論 查看所有評(píng)論(1)

        昵稱:
        表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
        字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過審核才能顯示)