コード例 #1
0
        private static async Task <Tuple <List <Frame>, BitrateType, TimeSpan, UInt32> > CollectSamplesAsync(IBinaryStream stream, UInt32 streamLength, UInt32?amount)
        {
            var samples          = new List <Frame>();
            var bitrateType      = BitrateType.Constant;
            var duration         = new TimeSpan();
            var bitrateSum       = 0U;
            var originalPosition = stream.Position;

            while (stream.Position + 20 < streamLength)
            {
                if (amount.HasValue && (samples.Count == amount.Value))
                {
                    break;
                }

                var possibleFrameHeader = await stream.PeekUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false);

                if ((possibleFrameHeader & 0xFFFE0000) == 0xFFFA0000)
                {
                    var bitrate   = Frame.GetBitrate(possibleFrameHeader);
                    var frequency = Frame.GetFrequency(possibleFrameHeader);
                    var padding   = Frame.GetPadding(possibleFrameHeader);
                    var version   = Frame.GetVersion(possibleFrameHeader);
                    var layer     = Frame.GetLayer(possibleFrameHeader);
                    if ((bitrate != 0) && (frequency != 0))
                    {
                        var frame = new Frame(stream.Position, version, layer, bitrate, frequency, padding);
                        if (samples.Count == 0)
                        {
                            var firstFrameContent = await stream.ReadAsync(frame.Length).ConfigureAwait(false);

                            bitrateType = firstFrameContent.IndexOf("Xing").HasValue ? BitrateType.Variable : BitrateType.Constant;
                        }
                        else
                        {
                            stream.Position += frame.Length;
                            duration        += frame.Duration;
                            bitrateSum      += frame.Bitrate;
                        }
                        samples.Add(frame);
                        continue;
                    }
                }

                // this situation means that we've read some samples and haven't found valid sample right after the last valid sample
                // and it means that the file in wrong format, corrupted or we've found all samples.
                if (samples.Count > 0)
                {
                    break;
                }

                stream.Position += 1;
                if (stream.Position - originalPosition > 1024)
                {
                    break;
                }
            }
            return(new Tuple <List <Frame>, BitrateType, TimeSpan, UInt32>(samples, bitrateType, duration, (samples.Count > 0) ? (UInt32)(bitrateSum / samples.Count) : 0));
        }