Ejemplo n.º 1
0
        /// <summary>
        /// 通过Url下载音频数据到内存流
        /// </summary>
        /// <param name="url"></param>
        public Mp3NetworkStream(string url)
        {
            //需要将网络流全部读入内存中,因为网络流是不能直接查找的
            HttpWebRequest request  = (HttpWebRequest)WebRequest.Create(url);
            WebResponse    response = request.GetResponse();

            using (Stream stream = response.GetResponseStream())
            {
                mp3Stream = new MemoryStream();
                byte[] byteBuffer = new byte[1024];
                if (stream != null)
                {
                    int iReadSize = stream.Read(byteBuffer, 0, byteBuffer.Length);
                    while (iReadSize > 0)
                    {
                        mp3Stream.Write(byteBuffer, 0, iReadSize);
                        iReadSize = stream.Read(byteBuffer, 0, byteBuffer.Length);
                    }
                    stream.Close();
                    stream.Dispose();
                }
                mp3Stream.Flush();
                mp3Stream.Position = 0;

                id3v2Tag = Id3v2Tag.ReadTag(mp3Stream);

                dataStartPosition = mp3Stream.Position;
                var mp3Frame = Mp3Frame.LoadFromStream(mp3Stream);
                sampleRate         = mp3Frame.SampleRate;
                frameLengthInBytes = mp3Frame.FrameLength;
                double bitRate = mp3Frame.BitRate;
                xingHeader = XingHeader.LoadXingHeader(mp3Frame);
                // If the header exists, we can skip over it when decoding the rest of the file
                if (xingHeader != null)
                {
                    dataStartPosition = mp3Stream.Position;
                }

                mp3DataLength = mp3Stream.Length - dataStartPosition;

                // try for an ID3v1 tag as well
                mp3Stream.Position = mp3Stream.Length - 128;
                byte[] tag = new byte[128];
                mp3Stream.Read(tag, 0, 3);
                if (tag[0] == 'T' && tag[1] == 'A' && tag[2] == 'G')
                {
                    id3v1Tag       = tag;
                    mp3DataLength -= 128;
                }

                mp3Stream.Position = dataStartPosition;

                // create a temporary MP3 format before we know the real bitrate
                Mp3WaveFormat = new Mp3WaveFormat(sampleRate, mp3Frame.ChannelMode == ChannelMode.Mono ? 1 : 2, frameLengthInBytes, (int)bitRate);

                CreateTableOfContents();
                tocIndex = 0;

                // [Bit rate in Kilobits/sec] = [Length in kbits] / [time in seconds]
                //                            = [Length in bits ] / [time in milliseconds]

                // Note: in audio, 1 kilobit = 1000 bits.
                bitRate = (mp3DataLength * 8.0 / TotalSeconds());

                mp3Stream.Position = dataStartPosition;

                // now we know the real bitrate we can create an accurate
                Mp3WaveFormat  = new Mp3WaveFormat(sampleRate, mp3Frame.ChannelMode == ChannelMode.Mono ? 1 : 2, frameLengthInBytes, (int)bitRate);
                decompressor   = CreateAcmFrameDecompressor(Mp3WaveFormat);
                waveFormat     = decompressor.OutputFormat;
                bytesPerSample = (decompressor.OutputFormat.BitsPerSample) / 8 * decompressor.OutputFormat.Channels;
                // no MP3 frames have more than 1152 samples in them
                // some MP3s I seem to get double
                decompressBuffer = new byte[1152 * bytesPerSample * 2];
            }
            response.Close();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Load Xing Header
        /// </summary>
        /// <param name="frame">Frame</param>
        /// <returns>Xing Header</returns>
        public static XingHeader LoadXingHeader(Mp3Frame frame)
        {
            XingHeader xingHeader = new XingHeader();

            xingHeader.frame = frame;
            int offset;

            if (frame.MpegVersion == MpegVersion.Version1)
            {
                if (frame.ChannelMode != ChannelMode.Mono)
                {
                    offset = 32 + 4;
                }
                else
                {
                    offset = 17 + 4;
                }
            }
            else if (frame.MpegVersion == MpegVersion.Version2)
            {
                if (frame.ChannelMode != ChannelMode.Mono)
                {
                    offset = 17 + 4;
                }
                else
                {
                    offset = 9 + 4;
                }
            }
            else
            {
                return(null);
                // throw new FormatException("Unsupported MPEG Version");
            }

            if ((frame.RawData[offset + 0] == 'X') &&
                (frame.RawData[offset + 1] == 'i') &&
                (frame.RawData[offset + 2] == 'n') &&
                (frame.RawData[offset + 3] == 'g'))
            {
                offset += 4;
            }
            else
            {
                return(null);
            }

            XingHeaderOptions flags = (XingHeaderOptions)ReadBigEndian(frame.RawData, offset);

            offset += 4;

            if ((flags & XingHeaderOptions.Frames) != 0)
            {
                xingHeader.framesOffset = offset;
                offset += 4;
            }
            if ((flags & XingHeaderOptions.Bytes) != 0)
            {
                xingHeader.bytesOffset = offset;
                offset += 4;
            }
            if ((flags & XingHeaderOptions.Toc) != 0)
            {
                offset += 100;
            }
            if ((flags & XingHeaderOptions.VbrScale) != 0)
            {
                xingHeader.vbrScale = ReadBigEndian(frame.RawData, offset);
            }
            return(xingHeader);
        }