zoukankan      html  css  js  c++  java
  • MP3文件的结构与编程

    有一个朋友喜欢听MP3,为了获取MP3,写了一个程序,专门从一家音乐网站上搜索下载mp3,一下子下载了有上千首。这时朋友又犯愁了,这些MP3的歌曲名字都是使用1,2,3,4,。。等数字命名,挑选起来十分不方便。虽然MP3播放器能够读出MP3文件信息的歌曲名,但歌曲文件本身的名字却不利于自己管理。于是就想写一个小程序实现MP3自动更名。查了一些资料,研究了一下MP3的文件结构。

    研究MP3的结构,就不能不研究ID3标签。ID3标签是MP3音乐档案中的歌曲附加讯息,它能够在MP3中附加曲子的演出者、作者以及其它类别资讯,方便众多乐曲的管理。缺少ID3标签并不会影响 MP3的播放,但若没有的话,管理音乐文件也会相当的麻烦。如果你在网上download MP3,里面多半已经写有预设的ID3讯息。ID3,一般是位于一个mp3文件的开头或末尾的若干字节内,附加了关于该mp3的歌手,标题,专辑名称,年代,风格等信息,该信息就被称为ID3信息,ID3信息分为两个版本,v1和v2版。

    其中:v1版的ID3在mp3文件的末尾128字节,以TAG三个字符开头,后面跟上歌曲信息。

    v2版一般位于mp3的开头,可以存储歌词,该专辑的图片等大容量的信息。

     但ID3并不是MP3标签的ISO国际标准,ID3的各种版本目前只是一个近乎事实上的标准,并没有人强迫播放器或者编码程序必须支持它。

    ID3V1大概有两个版本,由于ID3V1.0没有包括曲目序号的定义,所以Michael Mutschler在1997年进行了改进,引入了版本1.1。通过占用备注字段的最后两个字节,用一个00字节作标记,另一个字节改为序号,可以让ID3支持曲目编号了。一个字节的空间让ID3 V1.1支持最高到255的曲目序号,考虑到一张唱片超过256个曲目的可能性极小,这个改进还是相当合理的。但ID3V1只有128个字节可以使用,如果要在MP3中储存更多的信息,比如歌词,专辑图片等,显然是无法达到的,于是产生了ID3V2。ID3V2到现在一共有4个版本,但流行的播放软件一般只支持第3版,既ID3v2.3。由于ID3V1记录在MP3文件的末尾,ID3V2就只好记录在MP3文件的首部了。也正是由于这个原因,对ID3V2的操作比ID3V1要慢。而且ID3V2结构比ID3V1的结构要复杂得多,但比前者全面且可以伸缩和扩展。

    但我们只需要读出MP3的TITLE,所以只要解析IDV1就够了,这里不对IDV2做过多说明,其实我也没有深入研究IDV2。

    ID3V1的内容和每个标签占用的字节说明如下:

    char Header[3];    /*标签头必须是"TAG"否则认为没有标签*/
    char Title[30];    /*标题*/
    char Artist[30];   /*作者*/
    char Album[30];    /*专集*/
    char Year[4];    /*出品年代*/
    char Comment[30];   /*备注*/
    char Genre;    /*类型*/

    可以定义一个如下的结构来存储MP3信息:

    typedef struct _MP3INFO //MP3信息的结构
    {
     char Identify[3]; //TAG三个字母
     //这里可以用来鉴别是不是文件信息内容
     char Title[31];   //歌曲名,30个字节
     char Artist[31];  //歌手名,30个字节
     char Album[31];   //所属唱片,30个字节
     char Year[5];   //年,4个字节
     char Comment[29]; //注释,28个字节
     unsigned char reserved;  //保留位,1个字节
     unsigned char reserved2; //保留位,1个字节
     unsigned char reserved3; //保留位,1个字节
    } MP3INFO;
    代码可以简单如下:

     #include "stdlib.h"
    #include "stdio.h"
    #include "windows.h"
    #define MAX 128

    typedef struct _MP3INFO //MP3信息的结构
    {
     char Identify[3]; //TAG三个字母
     //这里可以用来鉴别是不是文件信息内容
     char Title[31];   //歌曲名,30个字节
     char Artist[31];  //歌手名,30个字节
     char Album[31];   //所属唱片,30个字节
     char Year[5];   //年,4个字节
     char Comment[29]; //注释,28个字节
     unsigned char reserved;  //保留位,1个字节
     unsigned char reserved2; //保留位,1个字节
     unsigned char reserved3; //保留位,1个字节
    } MP3INFO;

    int main(int argc, char* argv[])
    {
     FILE * fp;
     unsigned char mp3tag[128] = {0};
        MP3INFO mp3info;
     char oldname[MAX],newname[MAX],cmd[MAX];


     fp = fopen("G://mp3//Debug//5.mp3","rb");
     if (NULL==fp)
     {
      printf("open read file error!!");
      return 1;
     }
     fseek(fp,-128,SEEK_END);
     fread(&mp3tag,1,128,fp);
        if(!((mp3tag[0] == 'T'|| mp3tag[0] == 't')
      &&(mp3tag[1] == 'A'|| mp3tag[1] == 'a')
      &&(mp3tag[2] == 'G'|| mp3tag[0] == 'g')))
     {
         printf("mp3 file is error!!");
      fclose(fp) ;
      return 1;
     }

     memcpy((void *)mp3info.Identify,mp3tag,3); //获得tag
     memcpy((void *)mp3info.Title,mp3tag+3,30); //获得歌名
     memcpy((void *)mp3info.Artist,mp3tag+33,30); //获得作者
     memcpy((void *)mp3info.Album,mp3tag+63,30); //获得唱片名
     memcpy((void *)mp3info.Year,mp3tag+93,4); //获得年
     memcpy((void *)mp3info.Comment,mp3tag+97,28); //获得注释
     memcpy((void *)&mp3info.reserved,mp3tag+125,1); //获得保留
     memcpy((void *)&mp3info.reserved2,mp3tag+126,1);
     memcpy((void *)&mp3info.reserved3,mp3tag+127,1);
     fclose(fp);
     if (strlen(mp3info.Title) == 0)
     {
      printf("title is null/n");
      return 1;
     }
        strcpy(oldname,"5.mp3");
     sprintf(newname,"%s.mp3",mp3info.Title);
     sprintf(cmd,"rename G://mp3//Debug//%s %s",oldname,newname);
     printf("%s/n", cmd);
     system(cmd);


     return 0;
    }

    http://blog.csdn.net/yanjiaye520/article/details/6054579

  • 相关阅读:
    Fescar Quick Start
    Fescar Example-Spring Cloud
    IntelliJ IDEA 如何生成时序图?
    git 出现 fatal: refusing to merge unrelated histories 错误
    蘑菇街支付架构 PDF 下载
    优点缺点
    转 CentOS下php安装mcrypt扩展
    转 安装php时报gd相关的错误(gd_ctx.c)
    转 安装PHP出现make: *** [sapi/cli/php] Error 1 解决办法
    转 CentOS开启FTP及配置用户
  • 原文地址:https://www.cnblogs.com/findumars/p/5272750.html
Copyright © 2011-2022 走看看