C#读mp3歌曲信息

来源:互联网 发布:76人状元西蒙斯数据 编辑:程序博客网 时间:2024/04/30 10:37
从MP3中提取歌曲信息

 
              一首MP3歌曲除了音乐信息外,还包含了如歌名、演唱者等信息,当我们用winamp软件听音乐时,播放清单就自动将这些信息读出来。大部分人都喜欢从网上下载音乐,但下载下来的MP3文件名都是文件上传系统自动取名的,和歌曲本身根本不相符,所以,给用户带来了很大的麻烦。但是,懒人有懒人的做法,我们何不自己写一个程序,将歌曲信息自动读出来并为MP3文件自动更名呢?

 

              下面我就以C#为工具,把开发过程写出来。

 

              一首MP3的额外信息存放在文件的最后面,共占128个字节,其中包括以下的内容(我们定义一个结构说明):

              public   struct   Mp3Info
                {
                        public   string   identify;//TAG,三个字节
                        public   string   Title;//歌曲名,30个字节
                        public   string   Artist;//歌手名,30个字节
                        public   string   Album;//所属唱片,30个字节
                        public   string   Year;//年,4个字符
                        public   string   Comment;//注释,28个字节
                        public   char   reserved1;//保留位,一个字节
                        public   char   reserved2;//保留位,一个字节
                        public   char   reserved3;//保留位,一个字节
                }

 

              所以,我们只要把MP3文件的最后128个字节分段读出来并保存到该结构里就可以了。函数定义如下:

                ///   <summary>
                ///   获取MP3文件最后128个字节
                ///   </summary>
                ///   <param   name= "FileName "> 文件名 </param>
                ///   <returns> 返回字节数组 </returns>

                private   byte[]   getLast128(string   FileName)
                {
                        FileStream   fs   =   new   FileStream(FileName,FileMode.Open,FileAccess.Read);
                        Stream   stream   =   fs;
                        stream.Seek(-128,SeekOrigin.End);
                        const   int   seekPos   =   128;
                        int   rl   =   0;
                        byte[]   Info   =   new   byte[seekPos];
                        rl   =   stream.Read(Info,0,seekPos);
                        fs.Close();
                        stream.Close();
                        return   Info;
                }


              再对上面返回的字节数组分段取出,并保存到Mp3Info结构中返回。

                ///   <summary>
                ///   获取MP3歌曲的相关信息
                ///   </summary>
                ///   <param   name   =   "Info "> 从MP3文件中截取的二进制信息 </param>
                ///   <returns> 返回一个Mp3Info结构 </returns>

                private   Mp3Info   getMp3Info(byte[]   Info)
                {
                        Mp3Info   mp3Info   =   new   Mp3Info();
                        string   str   =   null;
                        int   i;
                        int   position   =   0;//循环的起始值
                        int   currentIndex   =   0;//Info的当前索引值

                        //获取TAG标识
                        for(i   =   currentIndex;i <currentIndex+3;i++)
                        {
                                str   =   str+(char)Info[i];
                                position++;
                        }
                        currentIndex   =   position;
                        mp3Info.identify   =   str;

                        //获取歌名
                        str   =   null;
                        byte[]   bytTitle   =   new   byte[30];//将歌名部分读到一个单独的数组中
                        int   j   =   0;
                        for(i   =   currentIndex;i <currentIndex+30;i++)
                        {
                                bytTitle[j]   =   Info[i];        
                                position++;
                                j++;
                        }
                        currentIndex   =   position;
                        mp3Info.Title   =   this.byteToString(bytTitle);

                          //获取歌手名
                        str   =   null;
                        j   =   0;
                        byte[]   bytArtist   =   new   byte[30];//将歌手名部分读到一个单独的数组中
                        for(i   =   currentIndex;i <currentIndex+30;i++)
                        {
                                bytArtist[j]   =   Info[i];        
                                position++;
                                j++;
                        }
                        currentIndex   =   position;
                        mp3Info.Artist   =   this.byteToString(bytArtist);
 

                        //获取唱片名
                        str   =   null;
                        j   =   0;
                        byte[]   bytAlbum   =   new   byte[30];//将唱片名部分读到一个单独的数组中
                        for(i   =   currentIndex;i <currentIndex+30;i++)
                        {
                                bytAlbum[j]   =   Info[i];        
                                position++;
                                j++;
                        }
                        currentIndex   =   position;
                        mp3Info.Album   =   this.byteToString(bytAlbum);
 

                        //获取年
                        str   =   null;
                        j   =   0;
                        byte[]   bytYear   =   new   byte[4];//将年部分读到一个单独的数组中
                        for(i   =   currentIndex;i <currentIndex+4;i++)
                        {
                                bytYear[j]   =   Info[i];    
                                position++;
                                j++;
                        }
                        currentIndex   =   position;
                        mp3Info.Year   =   this.byteToString(bytYear);
                       

                        //获取注释
                        str   =   null;
                        j   =   0;
                        byte[]   bytComment   =   new   byte[28];//将注释部分读到一个单独的数组中
                        for(i   =   currentIndex;i <currentIndex+25;i++)
                        {
                                bytComment[j]   =   Info[i];        
                                position++;
                                j++;
                        }
                        currentIndex   =   position;
                        mp3Info.Comment   =   this.byteToString(bytComment);
 

                        //以下获取保留位
                        mp3Info.reserved1   =   (char)Info[++position];
                        mp3Info.reserved2   =   (char)Info[++position];
                        mp3Info.reserved3   =   (char)Info[++position];
 
                        return   mp3Info;
                }


              上面程序用到下面的方法:

                ///   <summary>
                ///   将字节数组转换成字符串
                ///   </summary>
                ///   <param   name   =   "b "> 字节数组 </param>
                ///   <returns> 返回转换后的字符串 </returns>

                private   string   byteToString(byte[]   b)
                {
                        Encoding   enc   =   Encoding.GetEncoding( "GB2312 ");
                        string   str   =   enc.GetString(b);
                        str   =   str.Substring(0,str.IndexOf( '\0 ')   > =   0   ?   str.IndexOf( '\0 ')   :   str.Length);//去掉无用字符
 
                        return   str;
                }

 
              改名怎么办呢?我们按(演唱者)歌名   的格式对歌曲进行改名,程序如下:

                ///   <summary>
                ///   更改文件名
                ///   </summary>
                ///   <param   name= "filePath "> 文件名 </param>
                ///   <returns> </returns>

                private   bool   ReName(string   filePath)
                {
                        if(File.Exists(filePath))
                        {
                                Mp3Info   mp3Info   =   new   Mp3Info();
                                mp3Info   =   this.getMp3Info(this.getLast128(filePath));//读出文件信息
                                mp3Info.Artist   =   this.DeleteNotValue(mp3Info.Artist);
                                mp3Info.Title   =   this.DeleteNotValue(mp3Info.Title);

                                if(mp3Info.Artist.Trim().Length==0)
                                {
                                        mp3Info.Artist= "未命名 ";
                                }

                                if(mp3Info.Title.Trim().Length==0)
                                {
                                        mp3Info.Title= "未知名歌曲 ";
                                }

                                try
                                {
                                        //更名
                                        File.Move(filePath,filePath.Substring(0,filePath.ToLower().LastIndexOf( "\\ ")).Trim()   +   "\\ "   +   "( "   +   mp3Info.Artist.Trim()   +   ") "   +mp3Info.Title.Trim()   +   ".mp3 ");
                                        return   true;
                                }
                                catch(Exception)
                                {
                                        return   false;
                                }
                        }
                        else
                        {
                                return   false;
                        }

                }

来源于:http://topic.csdn.net/t/20050124/09/3748290.html