void WriteHeader(MetadataDictionary metadata, Stream stream) { Contract.Requires(metadata != null); Contract.Requires(stream != null); Contract.Requires(stream.CanWrite); var vorbisComment = new VorbisComment(); try { SafeNativeMethods.VorbisCommentInitialize(out vorbisComment); foreach (var item in new MetadataToVorbisCommentAdapter(metadata)) { // The key and value need to be marshaled as null-terminated UTF-8 strings: var keyBytes = new byte[Encoding.UTF8.GetByteCount(item.Key) + 1]; Encoding.UTF8.GetBytes(item.Key, 0, item.Key.Length, keyBytes, 0); var valueBytes = new byte[Encoding.UTF8.GetByteCount(item.Value) + 1]; Encoding.UTF8.GetBytes(item.Value, 0, item.Value.Length, valueBytes, 0); SafeNativeMethods.VorbisCommentAddTag(ref vorbisComment, keyBytes, valueBytes); } OggPacket first; OggPacket second; OggPacket third; _encoder.HeaderOut(ref vorbisComment, out first, out second, out third); _oggStream.PacketIn(ref first); _oggStream.PacketIn(ref second); _oggStream.PacketIn(ref third); } finally { SafeNativeMethods.VorbisCommentClear(ref vorbisComment); } OggPage page; while (_oggStream.Flush(out page)) { WritePage(page, stream); } }