//public override bool Open(IStream stream) //{ // this.stream = stream; // #region 初始化mpg123句柄 // int error; // if ((this.mpg123Handle = mpg123.mpg123_new(IntPtr.Zero, out error)) == IntPtr.Zero) // { // this.Close(); // logger.ErrorFormat("mpg123_new失败, {0}", error); // return false; // } // if ((error = mpg123.mpg123_open_feed(this.mpg123Handle)) != mpg123.MPG123_OK) // { // this.Close(); // logger.ErrorFormat("mpg123_open_feed失败, {0}", error); // return false; // } // #endregion // #region 探测流格式 // int readed = 0; // int total = 0; // int rate, channel, encoding; // while ((error = mpg123.mpg123_getformat(this.mpg123Handle, out rate, out channel, out encoding)) != mpg123.MPG123_OK) // { // if (error == mpg123.MPG123_NEED_MORE) // { // if (total > PROBE_FORMATE_MAX_SIZE) // { // /* 检测了PROBE_FORMATE_MAX_SIZE字节的数据也没有检测到文件类型,返回失败 */ // this.Close(); // logger.ErrorFormat("mpg123_getformat失败, {0}", error); // return false; // } // byte[] buffer = new byte[SIZE_PER_READ]; // if ((readed = stream.Read(buffer, buffer.Length)) == 0) // { // /* 流读完了也没有检测到数据类型,返回失败 */ // this.Close(); // logger.ErrorFormat("mpg123_getformat失败, {0}", error); // return false; // } // else // { // IntPtr data = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0); // if ((error = mpg123.mpg123_feed(this.mpg123Handle, data, readed)) != mpg123.MPG123_OK) // { // /* feed数据失败,返回失败 */ // this.Close(); // logger.ErrorFormat("mpg123_getformat失败, {0}", error); // return false; // } // total += SIZE_PER_READ; // } // } // else // { // /* 不认识的流格式 */ // this.Close(); // logger.ErrorFormat("mpg123_getformat失败, {0}", error); // return false; // } // } // logger.InfoFormat("OpenDemuxer成功, rate={0}, channel={1}, encoding={2}", rate, channel, encoding); // #endregion // #region 根据流格式初始化PCM数据格式 // int bps = 0; // if (encoding == (int)mpg123_enc_enum.MPG123_ENC_16) // { // bps = 16; // } // else if (encoding == (int)mpg123_enc_enum.MPG123_ENC_32) // { // bps = 32; // } // else // { // bps = 8; // logger.WarnFormat("bps:{0}", bps); // } // base.AudioFormat.Channel = channel; // base.AudioFormat.SamplesPerSec = rate; // base.AudioFormat.BitsPerSample = bps; // #endregion // return true; //} public override bool Open(AbstractAVStream stream) { byte[] header = new byte[3]; if (stream.Read(header, header.Length) < header.Length) { return(false); } if (header[0] == 'R' && header[1] == 'I' && header[2] == 'F') { } else if (header[0] == 'I' && header[1] == 'D' && header[2] == '3') { // 解析ID3V2格式并初始化DemuxerStream byte[] tag; int major_version, revision, flag, tag_size; if (!this.ParseID3V2Tag(stream, out major_version, out revision, out flag, out tag_size, out tag)) { return(false); } base.ContainerHeader = new byte[header.Length + tag_size]; Buffer.BlockCopy(header, 0, this.ContainerHeader, 0, header.Length); Buffer.BlockCopy(tag, 0, this.ContainerHeader, header.Length, tag_size); } this.stream = stream; return(true); }
public AbstractAVDemuxer Lookup(AbstractAVStream stream) { string demuxer_name; AbstractAVDemuxer demuxer; // 1.根据文件后缀名查找Demuxer //string extension; //string filePath = stream.MusicSource.Uri; //if (Path.HasExtension(filePath) && (extension = Path.GetExtension(filePath)) != null) //{ // if (extensionMap.TryGetValue(extension, out demuxer_name)) // { // logger.InfoFormat("demuxer found by extension, extension:{0}, demuxer:{1}", extension, demuxer_name); // if (!DemuxerRegistry.FindDemuxer(demuxer_name, out demuxer)) // { // return null; // } // return demuxer; // } //} //// 2.挨个循环Demuxer,查找第一个可用的Demuxer //var allDemuxer = this.demuxerMap.Values; //foreach (IGMusicDemuxer demuxer in allDemuxer) //{ // if (demuxer.Check()) // { // logger.InfoFormat("demuxer found by lookup, {0}", demuxer.Name); // return demuxer; // } //} //logger.ErrorFormat("demuxer not found, uri:{0}", filePath); return(null); }
/// <summary> /// 探测是否支持此媒体流 /// /// 1.解析ContainerHeader /// 2.计算第一帧的位置 /// </summary> /// <param name="stream"></param> /// <returns></returns> public abstract bool Open(AbstractAVStream stream);
/// <summary> /// 解析MP3数据帧 /// most of code are copied from mplayer /// </summary> /// <param name="stream"></param> /// <param name="frame_size">不包括帧头的大小</param> /// <param name="position">当前帧在AVStream中的位置</param> /// <returns></returns> private bool ParseMP3Frame(AbstractAVStream stream, out byte[] hdr, out byte[] frame, out long position) { hdr = new byte[4]; frame = null; position = -1; int[] mult = { 12000, 144000, 144000 }; int[] freqs = { 44100, 48000, 32000, // MPEG 1.0 22050, 24000, 16000, // MPEG 2.0 11025, 12000, 8000 }; // MPEG 2.5 int bit_rate_index, mpeg, layer, sampling_frequency, padding, stereo = 0, lsf = 0, frame_size = 0, divisor = 0; int bitrate = 0, sample_per_frame = 0, sample_per_second = 0; #region 查找帧头位置 // 帧头的4字节中高11位全部设置为1(11111111 111xxxxx xxxxxxxx xxxxxxxx),用它作为查找帧的重要依据 if (stream.Read(hdr, 4) != 4) { return(false); } uint newhead = (uint)hdr[0] << 24 | (uint)hdr[1] << 16 | (uint)hdr[2] << 8 | (uint)hdr[3]; while ((newhead & 0xFFE00000) != 0xFFE00000) { int c = stream.ReadByte(); if (c == -1) { return(false); } newhead = newhead << 8 | (uint)c; //hdr[0] = (byte)c; //hdr[1] = hdr[3]; //hdr[2] = hdr[2]; //hdr[3] = hdr[1]; hdr[0] = hdr[1]; hdr[1] = hdr[2]; hdr[2] = hdr[3]; hdr[3] = (byte)c; } #endregion #region 解析帧头字段 /* mpeg版本 */ mpeg = (int)((newhead >> 19) & 3); if (mpeg == 1) { logger.ErrorFormat("mpeg version error, {0}", mpeg); return(false); } /* 采样率索引 */ sampling_frequency = (int)((newhead >> 10) & 3); if (sampling_frequency == 3) { logger.ErrorFormat("sampling_frequency error, {0}", sampling_frequency); return(false); } /* lsf: 低采样率 */ if ((newhead & (1 << 20)) > 0) { lsf = (newhead & (1 << 19)) > 0 ? 0 : 1; sampling_frequency += lsf * 3; } else { lsf = 1; sampling_frequency += 6; } /* Layer版本 */ layer = 4 - (int)(((newhead >> 17) & 3)); if (layer == 0) { logger.ErrorFormat("layer error, {0}", layer); return(false); } /* crc, 0是帧头后没有2个字节的CRC校验值,1是帧头后有2字节的CRC校验值 */ bool crc = ((newhead << 8) & 0x80000000) == 0x80000000; /* 填充 */ padding = (int)(newhead >> 9) & 0x1; /* 比特率,kbps,1kbit per second,每秒传输比特, 1kbit = 1000bit */ bit_rate_index = (int)(newhead >> 12) & 0xF; bitrate = BitRateTable[lsf, layer - 1, bit_rate_index]; frame_size = bitrate * mult[layer - 1]; divisor = layer == 3 ? (freqs[sampling_frequency] << lsf) : freqs[sampling_frequency]; frame_size /= divisor; frame_size += padding; if (layer == 1) { frame_size *= 4; } if (!crc) { frame_size += 2; } /* 声道模式 */ stereo = (((newhead >> 6) & 0x3) == 3) ? 1 : 2; /* 采样率 */ sample_per_second = freqs[sampling_frequency]; /* 每帧采样数 */ if (layer == 1) { sample_per_frame = 384; } else if (layer == 2) { sample_per_frame = 1152; } else if (sampling_frequency > 2) // not 1.0 { sample_per_frame = 576; } else { sample_per_frame = 1152; } ///* 每帧采样数, spf, sample per frame */ //if (layer == 3) //{ // sample_per_frame = 384; //} //else if (layer == 2) //{ // sample_per_frame = 1152; //} //else if (layer == 1) //{ // if (mpeg == 3) // { // sample_per_frame = 1152; // } // else // { // sample_per_frame = 576; // } //} ///* 每秒采样数,采样率, sample per second / sample rate */ //if (mpeg == 3) //{ // /* mpeg1 */ // if (sampling_frequency == 0) // { // sample_per_second = 44100; // } // else if (sampling_frequency == 1) // { // sample_per_second = 48000; // } // else if (sampling_frequency == 2) // { // sample_per_second = 32000; // } //} //else if (mpeg == 2) //{ // /* mpeg2 */ // if (sampling_frequency == 0) // { // sample_per_second = 22050; // } // else if (sampling_frequency == 1) // { // sample_per_second = 24000; // } // else if (sampling_frequency == 2) // { // sample_per_second = 16000; // } //} //else if (mpeg == 0) //{ // /* mpeg2.5 */ // if (sampling_frequency == 0) // { // sample_per_second = 11205; // } // else if (sampling_frequency == 1) // { // sample_per_second = 12000; // } // else if (sampling_frequency == 2) // { // sample_per_second = 8000; // } //} /* 帧大小 */ position = stream.Position - 4; frame = new byte[frame_size - 4]; // frame_size有帧头数据,减4个字节的帧头 stream.Read(frame, frame.Length); #endregion return(true); }
/// <summary> /// 解析ID3V2标签 /// </summary> /// <param name="stream"></param> /// <param name="major_version"></param> /// <param name="revision"></param> /// <param name="flag"></param> /// <param name="size">id3v2标签的大小</param> /// <param name="tag">存储id3v2标签的内容</param> /// <returns></returns> private bool ParseID3V2Tag(AbstractAVStream stream, out int major_version, out int revision, out int flag, out int size, out byte[] tag) { /* * ID3V2标签结构: * +-----------------------------+ * | Header(10 bytes) | * +-----------------------------+ * | Extended Header | * | (variable length, OPTIONAL) | * +-----------------------------+ * | Frames(variable length) | * +-----------------------------+ * | Padding | * | (variable length, OPTIONAL) | * +-----------------------------+ * | Footer(10 bytes, OPTIONAL) | * +-----------------------------+ * * 10个字节的Header结构: * +-----------------------------+ * | ID3 | * +-----------------------------+ * | major_version(1 bytes) | * +-----------------------------+ * | revision(1 bytes) | * +-----------------------------+ * | flags(1 bytes) | * +-----------------------------+ * | size(4 bytes) | * +-----------------------------+ * * The ID3v2 tag size is the sum of the byte length of the extended * header, the padding and the frames after unsynchronisation. If a * footer is present this equals to ('total size' - 20) bytes, otherwise * ('total size' - 10) bytes. */ major_version = revision = flag = size = 0; tag = new byte[65535]; // 用64字节的临时空间用来存放tag数据 /* 读取major version */ major_version = stream.ReadByte(); if (major_version == -1 || major_version == 0xFF) { return(false); } tag[0] = (byte)major_version; /* 读取revision */ revision = stream.ReadByte(); if (revision == -1 || revision == 0xFF) { return(false); } tag[1] = (byte)revision; /* 读取flags */ if ((flag = stream.ReadByte()) == -1) { return(false); } tag[2] = (byte)flag; /* 读取size */ int next = 3; for (int i = 0; i < 4; i++) { int b = stream.ReadByte(); if (b == -1 || (b & 0x80) == 0x80) { return(false); } size = size << 7 | (byte)b; tag[next + i] = (byte)b; } /* 读取id3v2的所有的帧数据 */ if (stream.Read(tag, 7, size) != size) { return(false); } // size不包含footer的大小,如果有footer,读取footer if ((flag & (int)ID3V2Flags.FooterPresent) == (int)ID3V2Flags.FooterPresent) { const int footer_size = 10; size += 10; if (stream.Read(tag, 7 + size, footer_size) != footer_size) { return(false); } } return(true); }