예제 #1
0
        public static void CopyTo(MatroskaDocument doc, Stream outputStream, OggOpusAudioStreamDemuxerSettings?settings = null)
        {
            if (doc == null)
            {
                throw new ArgumentNullException(nameof(doc));
            }

            if (doc.Segment.Clusters == null)
            {
                throw new ArgumentNullException(nameof(doc.Segment.Clusters));
            }

            if (outputStream == null)
            {
                throw new ArgumentNullException(nameof(outputStream));
            }

            settings ??= new OggOpusAudioStreamDemuxerSettings();

            var validator = new OggOpusValidator();

            validator.ValidateAndThrow((settings, doc));

            var    opusAudio = doc.Segment.Tracks.TrackEntries.First(t => t.TrackNumber == settings.AudioTrackNumber);
            ushort preSkip   = GetPreSkipFromCodecPrivate(opusAudio);

            var sampleRate = (int)opusAudio.Audio.SamplingFrequency;
            var channels   = (int)opusAudio.Audio.Channels;

            var oggPageWriter       = new OggPageWriter(outputStream, settings.AudioStreamSerial);
            var oggOpusHeaderWriter = new OggOpusHeaderWriter(oggPageWriter);

            // Write OpusHeader (+ OpusTags)
            oggOpusHeaderWriter.WriteHeaders(channels, sampleRate, preSkip);

            // Loop OggSegments
            byte segmentParts        = 0;
            var  oggPageWithSegments = new List <SegmentEntry>();

            void WriteOggPageAndResetParts(OggHeaderType oggHeaderType)
            {
                // Write Ogg Page
                oggPageWriter.WriteOggPage(oggHeaderType, segmentParts, oggPageWithSegments);

                // Reset data
                segmentParts = 0;
                oggPageWithSegments.Clear();
            }

            // Loop SegmentEntries
            foreach (var oggSegmentEntry in ConvertClustersToSegmentTable(doc.Segment.Clusters, sampleRate, settings.AudioTrackNumber))
            {
                oggPageWithSegments.Add(oggSegmentEntry);
                segmentParts = (byte)(segmentParts + oggSegmentEntry.SegmentBytes.Length);

                if (segmentParts >= settings.MaxSegmentPartsPerOggPage)
                {
                    WriteOggPageAndResetParts(oggPageWithSegments.Any(o => o.IsLast) ? OggHeaderType.EndOfStream : OggHeaderType.None);
                }
            }

            if (segmentParts > 0)
            {
                WriteOggPageAndResetParts(OggHeaderType.EndOfStream);
            }

            oggPageWriter.Flush();
        }
예제 #2
0
 public OggOpusHeaderWriter(OggPageWriter oggPageWriter)
 {
     _oggPageWriter = oggPageWriter;
 }