关于MP3文件播放时间的计算

  小琢磨了一下mp3的格式,因为很想计算出其文件播放时长
  根据RFC文档上的说法,只要知道文件的长度,播放的比特率(bitRate),采样率(Simpling Frequency Rate)以及 填充位数(Padding bits),以及 “恒定每26ms能播放一数据帧” 的约定,就可以计算出播放时长
  okay,要做的就是,了解mp3帧格式,获取比特率,采样率 以及 填充位数

  在mp3文件的末尾,恒存在一个长度为128字节的ID3 Tag Version 1的标签,用以描述文件。如果愿意,还可以添加一个ID3 Tag Version 2到文件头,长度不固定,不过在其头部,会有10字节的描述头,里头标识出这个TAG结构的总长(含10字节),然后,接下来夹着的一直到TAG V1的部分,就是全部的数据帧。

   假定这些帧是采取CBR格式,即固定帧长存储,则每一帧的帧头描述都是一样的,基于此,便可计算出所需要的数据

   做一个类,来干这件事情:

ContractedBlock.gif ExpandedBlockStart.gif
None.gifusing System;
None.gif
using System.IO;
None.gif
using System.Text;
None.gif
None.gif
namespace IndieCommon
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
public abstract class Mp3Tag
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
// 每秒固定可以播放的帧数
InBlock.gif
        const double playFramesPerSec = 38.461538461538461538461538461538;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 获取MP3帧头包含的信息        
InBlock.gif        
/// </summary>
InBlock.gif        
/// <param name="FrameHeader">帧头四字节数据</param>
ExpandedSubBlockEnd.gif        
/// <returns>帧信息结构</returns>

ContractedSubBlock.gifExpandedSubBlockStart.gif        static Mp3Frame getFrameInfo(byte[] FrameHeader)#region static Mp3Frame getFrameInfo(byte[] FrameHeader)
InBlock.gif        
internal static Mp3Frame getFrameInfo(byte[] FrameHeader)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
// 比特率检索字典
ExpandedSubBlockStart.gifContractedSubBlock.gif
            int[,] bitrateArray = new int[,] dot.gifdot.gif0,0,0,0,0,0},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                               
dot.gif{32,32,32,32,32,8},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                               
dot.gif{64,48,40,64,48,16},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                               
dot.gif{64,48,40,64,48,16},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                               
dot.gif{96,56,48,96,56,24},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                               
dot.gif{128,64,56,128,64,32},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                               
dot.gif{160,80,64,160,80,64},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                               
dot.gif{192,96,80,192,96,80},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                               
dot.gif{224,112,96,224,112,52},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                               
dot.gif{256,128,112,256,128,64},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                               
dot.gif{288,160,128,288,160,128},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                               
dot.gif{320,192,160,320,192,160},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                               
dot.gif{352,320,192,352,320,112},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                               
dot.gif{384,256,224,384,256,128},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                               
dot.gif{448,384,320,448,384,320},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                               
dot.gif{0,0,0,0,0,0} }
;
InBlock.gif            
// 采样率检索字典
ExpandedSubBlockStart.gifContractedSubBlock.gif
            int[,] simpArray = new int[,] dot.gifdot.gif{44100,22050,11025},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                            
dot.gif{48000,24000,12000},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                            
dot.gif{32000,16000,8000},
ExpandedSubBlockStart.gifContractedSubBlock.gif                                            
dot.gif{0,0,0} }
;
InBlock.gif
InBlock.gif            
// 取帧信息
InBlock.gif
            Mp3Frame frame = new Mp3Frame();
InBlock.gif            
// MPEG版本
InBlock.gif
            switch ((FrameHeader[1& 0x18>> 3)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
case 3:                        // MPEG version 1
InBlock.gif
                    frame.version = 1;
InBlock.gif                    
break;
InBlock.gif                
case 2:                        // MPEG version 2
InBlock.gif
                    frame.version = 2;
InBlock.gif                    
break;
InBlock.gif                
case 0:                        // MPEG version 2.5              
InBlock.gif
                    frame.version = 3;
InBlock.gif                    
break;
InBlock.gif                
case 1:                        // Reserve
InBlock.gif
                    frame.version = 0;
InBlock.gif                    
break;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
// 层级
InBlock.gif
            switch ((FrameHeader[1& 0x6>> 1)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
case 1:                         // Layer 3
InBlock.gif
                    frame.layer = 3;
InBlock.gif                    
break;
InBlock.gif                
case 2:                         // Layer 2
InBlock.gif
                    frame.layer = 2;
InBlock.gif                    
break;
InBlock.gif                
case 3:                         // Layer 1
InBlock.gif
                    frame.layer = 1;
InBlock.gif                    
break;
InBlock.gif                
case 0:                         // reserve
InBlock.gif
                    frame.layer = 0;
InBlock.gif                    
break;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
// 是否有CRC保护
InBlock.gif
            frame.protect = FrameHeader[1& 0x1;
InBlock.gif
InBlock.gif            
// 比特率索引
InBlock.gif
            int j = ((FrameHeader[2& 0xf0>> 4)+1;
InBlock.gif            
int i = 0;            
InBlock.gif            
switch (frame.version)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{             
InBlock.gif                
// 通过版本 + 层级 获取 BIT率
InBlock.gif
                case 1:
InBlock.gif                    
switch (frame.layer)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        
case 1:
InBlock.gif                            i 
= 0;
InBlock.gif                            
break;
InBlock.gif                        
case 2:
InBlock.gif                            i 
= 1;
InBlock.gif                            
break;
InBlock.gif                        
case 3:
InBlock.gif                            i 
= 2;
InBlock.gif                            
break;
ExpandedSubBlockEnd.gif                    }
                    
InBlock.gif                    
break;
InBlock.gif                
case 2:
InBlock.gif                
case 3:
InBlock.gif                    
switch (frame.layer)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        
case 1:
InBlock.gif                            i 
= 3;
InBlock.gif                            
break;
InBlock.gif                        
case 2:
InBlock.gif                            i 
= 4;
InBlock.gif                            
break;
InBlock.gif                        
case 3:
InBlock.gif                            i 
= 5;
InBlock.gif                            
break;
ExpandedSubBlockEnd.gif                    }
                    
InBlock.gif                    
break;                                
ExpandedSubBlockEnd.gif            }

InBlock.gif            frame.bitrate 
= bitrateArray[j,i];
InBlock.gif
InBlock.gif            
// 获取采样率
InBlock.gif
            j = ((FrameHeader[2& 0xc>> 2);
InBlock.gif            
switch (frame.version)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
case 1:
InBlock.gif                    i 
= 0;
InBlock.gif                    
break;
InBlock.gif                
case 2:
InBlock.gif                    i 
= 1;
InBlock.gif                    
break;
InBlock.gif                
case 3:
InBlock.gif                    i 
= 2;
InBlock.gif                    
break;
ExpandedSubBlockEnd.gif            }

InBlock.gif            frame.simplingRate 
= simpArray[j, i];
InBlock.gif
InBlock.gif            
// 填充位
InBlock.gif
            frame.paddingBits = ((FrameHeader[2& 0x2>> 1);
InBlock.gif
InBlock.gif            
// 声道,1为立体声,0为单声道
InBlock.gif
            frame.channel = (((FrameHeader[3& 0xc0>> 6< 3 ? 10 );
InBlock.gif
InBlock.gif            
return frame;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif        
#endregion

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 由帧头获取Mp3时长信息
InBlock.gif        
/// </summary>
InBlock.gif        
/// <param name="paramMp3">Mp3结构</param>
InBlock.gif        
/// <param name="FrameHeader">帧头</param>
ExpandedSubBlockEnd.gif        
/// <param name="ID3V2_frame_size">ID3 Tag2长度</param>

ContractedSubBlock.gifExpandedSubBlockStart.gif        static void getTimeInfo(ref MP3 paramMP3,byte[] FrameHeader,int ID3V2_frame_size)#region static void getTimeInfo(ref MP3 paramMP3,byte[] FrameHeader,int ID3V2_frame_size)
InBlock.gif        
internal static void getTimeInfo(ref MP3 paramMP3, byte[] FrameHeader, int ID3V2_frame_size)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
// 文件长度
InBlock.gif
            FileInfo fi = new FileInfo(paramMP3.fileComplete);
InBlock.gif            paramMP3.FileLength 
= fi.Length;
InBlock.gif            
// 获取帧信息
InBlock.gif
            Mp3Frame frameInfo = getFrameInfo(FrameHeader);
InBlock.gif            
// 获取帧长(仅对CBR起作用)
InBlock.gif
            int frameSize = frameInfo.CalcFrameSize();
InBlock.gif            
// 帧数
InBlock.gif            
// 帧总长度 = 文件长度 - ID3 TagV2 - ID3 TagV1(固长128)
InBlock.gif
            long frameCount = (paramMP3.FileLength - ID3V2_frame_size - 128/ frameSize;
InBlock.gif
InBlock.gif            
// 时长
InBlock.gif
            double secs = (double)frameCount / playFramesPerSec;
InBlock.gif            paramMP3.hours 
= (int)secs / 3600;
InBlock.gif            paramMP3.minutes 
= ((int)secs % 3600/ 60;
InBlock.gif            paramMP3.seconds 
= ((int)secs % 3600% 60;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif        
#endregion

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 读取MP3信息
InBlock.gif        
/// </summary>
ExpandedSubBlockEnd.gif        
/// <param name="paramMP3">Mp3描述结构</param>

ContractedSubBlock.gifExpandedSubBlockStart.gif        static void readMP3Tag(ref MP3 paramMP3)#region static void readMP3Tag(ref MP3 paramMP3)
InBlock.gif        
public static void readMP3Tag(ref MP3 paramMP3)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
// 文件对象
InBlock.gif
            FileStream oFileStream;
InBlock.gif            oFileStream 
= new FileStream(paramMP3.fileComplete, FileMode.Open);
InBlock.gif            
InBlock.gif            
// 是否有ID3 Tag V2
InBlock.gif
            byte[] header = new byte[10];
InBlock.gif            oFileStream.Seek(
0, SeekOrigin.Begin);
InBlock.gif            oFileStream.Read(header, 
010);
InBlock.gif            
InBlock.gif            
// 标识头长度的字串
InBlock.gif
            Encoding instEncoding = new ASCIIEncoding(); 
InBlock.gif            
string id3Tag = instEncoding.GetString(header);
InBlock.gif            
// 是否有ID3 Tag V2
InBlock.gif
            if (id3Tag.Substring(03== "ID3")
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
// ID3Tag V2帧长度
InBlock.gif
                int ID3V2_frame_size = (int)(header[6& 0x7F* 0x200000
InBlock.gif                 
| (int)(header[7& 0x7F* 0x400
InBlock.gif                  
| (int)(header[8& 0x7F* 0x80
InBlock.gif                  
| (int)(header[9& 0x7F);                
InBlock.gif                
// 定位到某一帧头
InBlock.gif
                byte[] FrameHeader = new byte[4];
InBlock.gif                oFileStream.Seek(ID3V2_frame_size 
+ 10, SeekOrigin.Begin);
InBlock.gif                oFileStream.Read(FrameHeader, 
04);
InBlock.gif                oFileStream.Close();
InBlock.gif                
// 获取时长
InBlock.gif
                getTimeInfo(ref paramMP3, FrameHeader, ID3V2_frame_size);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
// 直读Frame
InBlock.gif            
// 读取ID3 Tag V1
InBlock.gif
            else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
// 直接获取帧头
InBlock.gif
                byte[] FrameHeader = new byte[4];
InBlock.gif                oFileStream.Seek(
0, SeekOrigin.Begin);
InBlock.gif                oFileStream.Read(FrameHeader, 
04);
InBlock.gif                oFileStream.Close();
InBlock.gif                
// 获取时长
InBlock.gif
                getTimeInfo(ref paramMP3, FrameHeader, 0);
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
// Read the 128 byte ID3 tag into a byte array
InBlock.gif            
InBlock.gif            
//byte[] bBuffer = new byte[128];
InBlock.gif            
//oFileStream.Seek(-128, SeekOrigin.End);
InBlock.gif            
//oFileStream.Read(bBuffer, 0, 128);
InBlock.gif            
//oFileStream.Close();
InBlock.gif

ExpandedSubBlockStart.gifContractedSubBlock.gif            
/**///// Convert the Byte Array to a String           
InBlock.gif            //id3Tag = instEncoding.GetString(bBuffer);
InBlock.gif

ExpandedSubBlockStart.gifContractedSubBlock.gif            
/**///// If there is an attched ID3 v1.x TAG then read it 
InBlock.gif            //if (id3Tag.Substring(0, 3) == "TAG")
InBlock.gif            
//{
InBlock.gif            
//    paramMP3.id3Title = id3Tag.Substring(3, 30).Trim();
InBlock.gif            
//    paramMP3.id3Artist = id3Tag.Substring(33, 30).Trim();
InBlock.gif            
//    paramMP3.id3Album = id3Tag.Substring(63, 30).Trim();
InBlock.gif            
//    paramMP3.id3Year = id3Tag.Substring(93, 4).Trim();
InBlock.gif            
//    paramMP3.id3Comment = id3Tag.Substring(97, 28).Trim();
InBlock.gif
InBlock.gif            
//    // Get the track number if TAG conforms to ID3 v1.1
InBlock.gif            
//    if (id3Tag[125] == 0)
InBlock.gif            
//        paramMP3.id3TrackNumber = bBuffer[126];
InBlock.gif            
//    else
InBlock.gif            
//        paramMP3.id3TrackNumber = 0;
InBlock.gif            
//    paramMP3.id3Genre = bBuffer[127];
InBlock.gif            
//    paramMP3.hasID3Tag = true;
InBlock.gif            
//    // ********* IF USED IN ANGER: ENSURE to test for non-numeric year
InBlock.gif            
//}
InBlock.gif            
//else
InBlock.gif            
//{
InBlock.gif            
//    // ID3 Tag not found so create an empty TAG in case the user saces later
InBlock.gif            
//    paramMP3.id3Title = "";
InBlock.gif            
//    paramMP3.id3Artist = "";
InBlock.gif            
//    paramMP3.id3Album = "";
InBlock.gif            
//    paramMP3.id3Year = "";
InBlock.gif            
//    paramMP3.id3Comment = "";
InBlock.gif            
//    paramMP3.id3TrackNumber = 0;
InBlock.gif            
//    paramMP3.id3Genre = 0;
InBlock.gif            
//    paramMP3.hasID3Tag = false;
InBlock.gif            
//}
ExpandedSubBlockEnd.gif
        }

ExpandedSubBlockEnd.gif        
#endregion

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 更新tag信息
InBlock.gif        
/// </summary>
ExpandedSubBlockEnd.gif        
/// <param name="paramMP3"></param>

ContractedSubBlock.gifExpandedSubBlockStart.gif        static void updateMP3Tag(ref MP3 paramMP3)#region static void updateMP3Tag(ref MP3 paramMP3)
InBlock.gif        
public static void updateMP3Tag(ref MP3 paramMP3)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
// Trim any whitespace
InBlock.gif
            paramMP3.id3Title = paramMP3.id3Title.Trim();
InBlock.gif            paramMP3.id3Artist 
= paramMP3.id3Artist.Trim();
InBlock.gif            paramMP3.id3Album 
= paramMP3.id3Album.Trim();
InBlock.gif            paramMP3.id3Year 
= paramMP3.id3Year.Trim();
InBlock.gif            paramMP3.id3Comment 
= paramMP3.id3Comment.Trim();
InBlock.gif
InBlock.gif            
// Ensure all properties are correct size
InBlock.gif
            if (paramMP3.id3Title.Length > 30)
InBlock.gif                paramMP3.id3Title 
= paramMP3.id3Title.Substring(030);
InBlock.gif            
if (paramMP3.id3Artist.Length > 30)
InBlock.gif                paramMP3.id3Artist 
= paramMP3.id3Artist.Substring(030);
InBlock.gif            
if (paramMP3.id3Album.Length > 30)
InBlock.gif                paramMP3.id3Album 
= paramMP3.id3Album.Substring(030);
InBlock.gif            
if (paramMP3.id3Year.Length > 4)
InBlock.gif                paramMP3.id3Year 
= paramMP3.id3Year.Substring(04);
InBlock.gif            
if (paramMP3.id3Comment.Length > 28)
InBlock.gif                paramMP3.id3Comment 
= paramMP3.id3Comment.Substring(028);
InBlock.gif
InBlock.gif            
// Build a new ID3 Tag (128 Bytes)
InBlock.gif
            byte[] tagByteArray = new byte[128];
InBlock.gif            
for (int i = 0; i < tagByteArray.Length; i++)
InBlock.gif                tagByteArray[i] 
= 0// Initialise array to nulls
InBlock.gif
InBlock.gif            
// Convert the Byte Array to a String
InBlock.gif
            Encoding instEncoding = new ASCIIEncoding(); // NB: Encoding is an Abstract class // ************ To DO: Make a shared instance of ASCIIEncoding so we don't keep creating/destroying it
InBlock.gif            
// Copy "TAG" to Array
InBlock.gif
            byte[] workingByteArray = instEncoding.GetBytes("TAG");
InBlock.gif            Array.Copy(workingByteArray, 
0, tagByteArray, 0, workingByteArray.Length);
InBlock.gif            
// Copy Title to Array
InBlock.gif
            workingByteArray = instEncoding.GetBytes(paramMP3.id3Title);
InBlock.gif            Array.Copy(workingByteArray, 
0, tagByteArray, 3, workingByteArray.Length);
InBlock.gif            
// Copy Artist to Array
InBlock.gif
            workingByteArray = instEncoding.GetBytes(paramMP3.id3Artist);
InBlock.gif            Array.Copy(workingByteArray, 
0, tagByteArray, 33, workingByteArray.Length);
InBlock.gif            
// Copy Album to Array
InBlock.gif
            workingByteArray = instEncoding.GetBytes(paramMP3.id3Album);
InBlock.gif            Array.Copy(workingByteArray, 
0, tagByteArray, 63, workingByteArray.Length);
InBlock.gif            
// Copy Year to Array
InBlock.gif
            workingByteArray = instEncoding.GetBytes(paramMP3.id3Year);
InBlock.gif            Array.Copy(workingByteArray, 
0, tagByteArray, 93, workingByteArray.Length);
InBlock.gif            
// Copy Comment to Array
InBlock.gif
            workingByteArray = instEncoding.GetBytes(paramMP3.id3Comment);
InBlock.gif            Array.Copy(workingByteArray, 
0, tagByteArray, 97, workingByteArray.Length);
InBlock.gif            
// Copy Track and Genre to Array
InBlock.gif
            tagByteArray[126= paramMP3.id3TrackNumber;
InBlock.gif            tagByteArray[
127= paramMP3.id3Genre;
InBlock.gif
InBlock.gif            
// SAVE TO DISK: Replace the final 128 Bytes with our new ID3 tag
InBlock.gif
            FileStream oFileStream = new FileStream(paramMP3.fileComplete, FileMode.Open);
InBlock.gif            
if (paramMP3.hasID3Tag)
InBlock.gif                oFileStream.Seek(
-128, SeekOrigin.End);
InBlock.gif            
else
InBlock.gif                oFileStream.Seek(
0, SeekOrigin.End);
InBlock.gif            oFileStream.Write(tagByteArray, 
0128);
InBlock.gif            oFileStream.Close();
InBlock.gif            paramMP3.hasID3Tag 
= true;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif        
#endregion

ExpandedSubBlockEnd.gif    }
        
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// Mp3结构
ExpandedSubBlockEnd.gif    
/// </summary>

ContractedSubBlock.gifExpandedSubBlockStart.gif    struct MP3#region struct MP3
InBlock.gif    
public struct MP3
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public string filePath;
InBlock.gif        
public string fileFileName;
InBlock.gif        
public string fileComplete;
InBlock.gif        
public bool hasID3Tag;
InBlock.gif        
public string id3Title;
InBlock.gif        
public string id3Artist;
InBlock.gif        
public string id3Album;
InBlock.gif        
public string id3Year;
InBlock.gif        
public string id3Comment;
InBlock.gif        
public byte id3TrackNumber;
InBlock.gif        
public byte id3Genre;
InBlock.gif        
public long FileLength;
InBlock.gif        
public int hours;
InBlock.gif        
public int minutes;
InBlock.gif        
public int seconds;        
InBlock.gif
InBlock.gif        
// Required struct constructor
InBlock.gif
        public MP3(string path, string name)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.filePath = path;
InBlock.gif            
this.fileFileName = name;
InBlock.gif            
this.fileComplete = path + "\\" + name;
InBlock.gif            
this.hasID3Tag = false;
InBlock.gif            
this.id3Title = null;
InBlock.gif            
this.id3Artist = null;
InBlock.gif            
this.id3Album = null;
InBlock.gif            
this.id3Year = null;
InBlock.gif            
this.id3Comment = null;
InBlock.gif            
this.id3TrackNumber = 0;
InBlock.gif            
this.FileLength = 0;
InBlock.gif            
this.id3Genre = 0;
InBlock.gif            
this.hours = 0;
InBlock.gif            
this.minutes = 0;
InBlock.gif            
this.seconds = 0;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedSubBlockEnd.gif    
#endregion

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// MP3文件帧结构
ExpandedSubBlockEnd.gif    
/// </summary>

ContractedSubBlock.gifExpandedSubBlockStart.gif    struct Mp3Frame#region  struct Mp3Frame
InBlock.gif    
internal struct Mp3Frame
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public int version;                     // MPEG版本(2+,2,1,0表示保留)
InBlock.gif
        public int layer;                       // 层级(1,2,3,0表示保留)
InBlock.gif
        public int protect;                     // 是否受CRC校验保护(1为保护,0为未保护)
InBlock.gif
        public int frameSize;                   // 帧长度
InBlock.gif
        public int bitrate;                     // 速率,bps
InBlock.gif
        public int simplingRate;                // 采样率
InBlock.gif
        public int paddingBits;                 // 填充位数
InBlock.gif
        public int channel;                     // 声道模式(1为立体声,0为单声道)
InBlock.gif

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 计算帧长度
ExpandedSubBlockEnd.gif        
/// </summary>        

InBlock.gif        public int CalcFrameSize()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
// 计算帧长度的公式
InBlock.gif
            this.frameSize = ((this.version == 1 ? 144 : 72* 1000 * this.bitrate
InBlock.gif                
/ this.simplingRate) + this.paddingBits;
InBlock.gif
InBlock.gif            
return this.frameSize;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedSubBlockEnd.gif    
#endregion

ExpandedBlockEnd.gif}

None.gif


  很显然,这事儿还没干完,先留着,以后再干~~~

转载于:https://www.cnblogs.com/moye/archive/2007/08/08/848114.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值