Пример #1
0
        public MetadataDictionary ReadMetadata(Stream stream)
        {
            Contract.Ensures(Contract.Result <MetadataDictionary>() != null);

            var buffer = new byte[4096];

            using (var decoder = new NativeVorbisDecoder())
            {
                NativeOggStream oggStream     = null;
                var             vorbisComment = new VorbisComment();

                try
                {
                    SafeNativeMethods.VorbisCommentInitialize(out vorbisComment);

                    using (var sync = new NativeOggSync())
                    {
                        OggPage page;

                        do
                        {
                            // Read from the buffer into a page:
                            while (sync.PageOut(out page) != 1)
                            {
                                int bytesRead = stream.Read(buffer, 0, buffer.Length);
                                if (bytesRead == 0)
                                {
                                    throw new IOException(Resources.ReadError);
                                }

                                IntPtr nativeBuffer = sync.Buffer(bytesRead);
                                Marshal.Copy(buffer, 0, nativeBuffer, bytesRead);

                                sync.Wrote(bytesRead);
                            }

                            if (oggStream == null)
                            {
                                oggStream = new NativeOggStream(SafeNativeMethods.OggPageGetSerialNumber(ref page));
                            }

                            oggStream.PageIn(ref page);

                            OggPacket packet;
                            while (oggStream.PacketOut(out packet) == 1)
                            {
                                decoder.HeaderIn(ref vorbisComment, ref packet);

                                if (packet.PacketNumber == 1)
                                {
                                    return(new VorbisCommentToMetadataAdapter(vorbisComment));
                                }
                            }
                        } while (SafeNativeMethods.OggPageEndOfStream(ref page) == 0);

                        throw new IOException(Resources.EndOfStreamError);
                    }
                }
                finally
                {
                    oggStream?.Dispose();

                    SafeNativeMethods.VorbisCommentClear(ref vorbisComment);
                }
            }
        }