关于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格式,即固定帧长存储,则每一帧的帧头描述都是一样的,基于此,便可计算出所需要的数据
  做一个类,来干这件事情:
  
  
  
  
  
  
  using System;
  
  using System.IO;
  
  using System.Text;
  
  
  
  namespace IndieCommon
  
  
  
  
  
  {
  
  
  public abstract class Mp3Tag
  
  
  
  
  
  
  {
  
  
  // 每秒固定可以播放的帧数
  
  const double playFramesPerSec = 38.461538461538461538461538461538
  
  
  
  
  
  /**
  
  /// 获取MP3帧头包含的信息
  
  
  ///

  
  /// 帧头四字节数据
  
  /// 帧信息结构
  
  
  
  
  static Mp3Frame getFrameInfo(byte[] FrameHeader)#region static Mp3Frame getFrameInfo(byte[] FrameHeader)
  
  {
  
  
  // 比特率检索字典
  
  
  
  int{
  
  { 0,0,0,0,0,0},
  
  
  
  
  ,
  
  
  
  
  
  
  {64,48,{64,48,40,64,48,16},
  
  
  
  ,
  
  
  
  
  
  
  {128,64,
  
  
  
  
  
  
  {160,80,
  
  
  
  
  
  
  {192,96,
  
  
  
  
  
  
  {224,,
  
  
  
  
  
  
  {256,,
  
  
  
  
  
  
  {288,,
  
  
  
  
  
  
  {320,,
  
  
  
  
  
  
  {352,,
  
  
  
  
  
  
  {384,,
  
  
  
  
  
  
  {448,,
  
  
  
  
  
  
  {0,0,0,
  
  // 采样率检索字典
  
  
  
  int{
  
  {44100,22050,11025},
  
  
  
  ,
  
  
  
  
  
  
  {32000,
  
  
  
  
  
  /**
  
  /// 由帧头获取Mp3时长信息
  
  
  ///

  
  /// Mp3结构
  
  /// 帧头
  
  /// ID3 Tag2长度
  
  
  
  
  static void getTimeInfo(ref MP3 paramMP3,byte[] FrameHeader,int ID3V2_frame_size)#region getTimeInfo(ref MP3 paramMP3, {
  
  
  // 文件长度
  
  
  
  Mp3Frame frameInfo frameInfo.CalcFrameSize();
  
  
  //
  
  frameCount =)frameCount / playFramesPerSec;
  
  
  
  paramMP3.seconds
  
  #endregion
  
  
  
  
  
  /**
  
  /// 读取MP3信息
  
  
  ///

  
  /// Mp3描述结构
  
  
  
  
  static void readMP3Tag(ref MP3 paramMP3)#region static void readMP3Tag(ref MP3 paramMP3)
  
  public {
  
  
  // 文件对象
  
  FileStream oFileStream;
  
  
  oFileStream = 是否有ID3 Tag V2
  
  byte[] header = new byte[10];
  
  , SeekOrigin.Begin);
  
  
  oFileStream.Read(header, 0, 10);
  
  
  
  
  
  // ASCIIEncoding();
  
  
  string id3Tag = instEncoding.GetString(header);
  
  
  //"ID3")
  
  
  
  
  
  
  {
  
  
  // ID3Tag V2帧长度
  
  int
  
  | (int)(header[7] & 0x7F) * 0x400
  
  | (int)(header[9] & 0x7F);
  
  
  // 定位到某一帧头
  
  ];
  
  
  oFileStream.Seek(ID3V2_frame_size + 10
  
  );
  
  
  oFileStream.Close();
  
  
  // 获取时长
  
  
  
  // 直读Frame
  
  
  // 读取ID3 Tag V1
  
  
  
  
  
  
  
  /**
  
  /// 更新tag信息
  
  
  ///

  
  ///
  
  
  
  
  static void updateMP3Tag(ref MP3 paramMP3)#region static void updateMP3Tag(ref MP3 paramMP3)
  
  public{
  
  
  // Trim any whitespace
  
  paramMP3.id3Title paramMP3.id3Artist.Trim();
  
  
  paramMP3.id3Album = paramMP3.id3Album.Trim();
  
  
  paramMP3.id3Year paramMP3.id3Comment.Trim();
  
  
  
  
  // Ensure all properties are correct size)
  
  
  paramMP3.id3Title = paramMP3.id3Title.Substring()
  
  
  paramMP3.id3Artist = paramMP3.id3Artist.Substring()
  
  
  paramMP3.id3Album = paramMP3.id3Album.Substring()
  
  
  paramMP3.id3Year = paramMP3.id3Year.Substring(0)
  
  
  paramMP3.id3Comment = paramMP3.id3Comment.Substring(
  
  byte[] tagByteArray = new byte[128];
  
  
  
  
  }
  
  
  
  
  
  
  /**
  
  /// Mp3结构
  
  
  ///

  
  
  
  
  struct MP3#region struct MP3
  
  public struct MP3
  
  
  
  
  
  
  {
  
  
  public string filePath;
  
  
  public string fileFileName;
  
  
  public string fileComplete;
  
  
  public bool
  
  id3Title;
  
  
  public string id3Artist;
  
  
  public string id3Album;
  
  
  public string id3Year;
  
  
  public string
  
  id3TrackNumber;
  
  
  public byte id3Genre;
  
  
  public long FileLength;
  
  
  public int hours;
  
  
  public int minutes;
  
  seconds;
  
  
  
  
  // Required struct constructor
  
  public MP3(string path, string name)
  
  
  
  
  {
  
  
  this.filePath = path;
  
  
  this.fileFileName = name;
  
  
  this.fileComplete = name;
  
  
  this.hasID3Tag = false
  
  this.id3Title = null
  
  this.id3Artist this.id3Album = null
  
  this.id3Year = null
  
  this.id3Comment = null
  
  0
  
  this.FileLength = 0
  
  this.id3Genre = 0
  
  this.hours = 0
  
  
  
  
  
  
  
  /**
  
  /// MP3文件帧结构
  
  
  ///

  
  
  
  
  struct Mp3Frame#region struct Mp3Frame
  
  internal struct Mp3Frame
  
  
  
  
  
  
  {
  
  
  public int version; // MPEG版本(2+,2,1,0表示保留)
  
  layer; // 层级(1,2,3,0表示保留)
  
  public int 是否受CRC校验保护(1为保护,0为未保护)
  
  public int frameSize; // 帧长度 bitrate; // 速率,bps
  
  public int simplingRate; // paddingBits; // 填充位数
  
  public int channel; //
  
  
  
  
  
  /**
  
  /// 计算帧长度
  
  
  ///

  
  
  public int CalcFrameSize()
  
  
  
  
  
  
  {
  
  
  // 计算帧长度的公式
  
  this.frameSize = ((this.version == 1 ? 144 : 72
  
  }
  
  
  很显然,这事儿还没干完,先留着,以后再干~~~

本文转自
http://www.cnblogs.com/moye/archive/2007/08/08/848114.html
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值