Exemple #1
0
        public void WriteMetadata(Stream stream, MetadataDictionary metadata, SettingsDictionary settings)
        {
            bool usePadding;

            if (string.IsNullOrEmpty(settings["UsePadding"]))
            {
                usePadding = false;
            }
            else if (!bool.TryParse(settings["UsePadding"], out usePadding))
            {
                throw new InvalidSettingException(string.Format(CultureInfo.CurrentCulture,
                                                                Resources.MetadataEncoderBadUsePadding, settings["UsePadding"]));
            }

            NativeVorbisCommentBlock vorbisCommentBlock = null;
            NativePictureBlock       pictureBlock       = null;

            try
            {
                using (var chain = new NativeMetadataChain(stream))
                {
                    if (!chain.Read())
                    {
                        MetadataChainStatus chainStatus = chain.GetStatus();
                        if (chainStatus == MetadataChainStatus.NotAFlacFile)
                        {
                            throw new UnsupportedAudioException(Resources.MetadataEncoderNotFlacError);
                        }
                        else
                        {
                            throw new IOException(string.Format(CultureInfo.CurrentCulture,
                                                                Resources.MetadataEncoderReadError, chainStatus));
                        }
                    }

                    // Create a Vorbis Comment block, even if empty:
                    vorbisCommentBlock = new NativeVorbisCommentBlock();
                    foreach (var item in new MetadataToVorbisCommentAdapter(metadata))
                    {
                        vorbisCommentBlock.Append(item.Key, item.Value);
                    }

                    // Create a Picture block if cover art is available:
                    if (metadata.CoverArt != null)
                    {
                        pictureBlock = new CoverArtToPictureBlockAdapter(metadata.CoverArt);
                    }

                    // Iterate over the existing blocks, replacing and deleting as needed:
                    using (var iterator = new NativeMetadataIterator(chain.Handle))
                        UpdateMetadata(iterator, vorbisCommentBlock, pictureBlock);

                    if (chain.CheckIfTempFileNeeded(usePadding))
                    {
                        // If FLAC requests a temporary file, use a MemoryStream instead. Then overwrite the original:
                        using (var tempStream = new MemoryStream())
                        {
                            if (!chain.WriteWithTempFile(usePadding, tempStream))
                            {
                                throw new IOException(string.Format(CultureInfo.CurrentCulture,
                                                                    Resources.MetadataEncoderTempFileError, chain.GetStatus()));
                            }

                            // Clear the original stream, and copy the temporary one over it:
                            stream.SetLength(tempStream.Length);
                            stream.Position = 0;
                            tempStream.WriteTo(stream);
                        }
                    }
                    else if (!chain.Write(usePadding))
                    {
                        throw new IOException(string.Format(CultureInfo.CurrentCulture,
                                                            Resources.MetadataEncoderWriteError, chain.GetStatus()));
                    }
                }
            }
            finally
            {
                vorbisCommentBlock?.Dispose();
                pictureBlock?.Dispose();
            }
        }