Exemplo n.º 1
0
        private int GetXingHeaderOffset(MpegFrameHeader mpegHeader)
        {
            // TODO: mpegHeader.IsProtected

            switch (mpegHeader.AudioVersion)
            {
                case AudioVersion.Mpeg1:
                    return mpegHeader.ChannelMode != ChannelMode.Mono ? 32 : 17;

                case AudioVersion.Mpeg2:
                case AudioVersion.Mpeg25:
                    return mpegHeader.ChannelMode != ChannelMode.Mono ? 17 : 9;
            }

            throw new NotSupportedException();
        }
Exemplo n.º 2
0
        public MpegFileInfo(Stream stream)
            : this()
        {
            MaxBitrate = int.MinValue;
            MinBitrate = int.MaxValue;

            if (stream.Length < 4)
                return;

            stream.Seek(0, SeekOrigin.Begin);

            long expectedNextFrameOffset = 0;
            long frameCount = 0;
            long bitrateSum = 0;

            while (stream.Position <= stream.Length)
            {
                var buffer = new byte[4];
                var bytesRead = stream.Read(buffer, 0, 4);

                if (bytesRead < 4)
                    break;

                if (!MpegFrameHeader.IsValid(buffer))
                {
                    if (stream.Position == stream.Length)
                        break;

                    stream.Seek(-3, SeekOrigin.Current);

                    if (frameCount == 0)
                        expectedNextFrameOffset = stream.Position;

                    // An invalid frame after the first 2 valid frames indicates false detection
                    if (frameCount <= 2)
                    {
                        _firstMpegFrameHeader = null;
                        _firstMpegFrameData = null;
                        MinBitrate = int.MaxValue;
                        MaxBitrate = int.MinValue;
                        frameCount = 0;
                        bitrateSum = 0;
                    }

                    continue;
                }

                if (frameCount > 0 && expectedNextFrameOffset != stream.Position - 4)
                    Errors.Add(new MisplacedFrameMpegError(expectedNextFrameOffset, stream.Position - 4, TimeSpan.FromSeconds(frameCount * _firstMpegFrameHeader.SamplesPerFrame / _firstMpegFrameHeader.SampleRate)));

                var mpegHeader = new MpegFrameHeader(buffer);
                var frameOffset = stream.Position - 4;

                if (frameCount == 0)
                {
                    _firstMpegFrameHeader = mpegHeader;
                    _firstMpegFrameData = new byte[mpegHeader.FrameSize];
                    stream.Read(_firstMpegFrameData, 0, _firstMpegFrameData.Length);

                    StartOffset = frameOffset;
                }

                if (mpegHeader.Bitrate < MinBitrate)
                    MinBitrate = mpegHeader.Bitrate;

                if (mpegHeader.Bitrate > MaxBitrate)
                    MaxBitrate = mpegHeader.Bitrate;

                bitrateSum += mpegHeader.Bitrate;
                frameCount++;
                expectedNextFrameOffset = frameOffset + mpegHeader.FrameSize;

                if (expectedNextFrameOffset == stream.Length)
                    break;

                if (expectedNextFrameOffset > stream.Length)
                {
                    Errors.Add(new LastFrameTruncatedMpegError());
                    break;
                }

                stream.Seek(expectedNextFrameOffset, SeekOrigin.Begin);
                Size = (int)(stream.Position - StartOffset);
            }

            if (frameCount > 0)
            {
                Bitrate = (int)(bitrateSum / frameCount);
                Duration = TimeSpan.FromSeconds(frameCount * _firstMpegFrameHeader.SamplesPerFrame / _firstMpegFrameHeader.SampleRate);
                HasXingHeader = ArrayHelper.CompareArray(_firstMpegFrameData.SubArray(GetXingHeaderOffset(_firstMpegFrameHeader), 4), XingSignature);
                HasVbriHeader = ArrayHelper.CompareArray(_firstMpegFrameData.SubArray(32, 4), VbriSignature);
            }
        }