/// <summary>
        /// Writes this object into the data stream at the current position. Note that this method
        /// reverses some spacefor further additions in the stream,
        /// if the stream is seekable. Following subsequent additions to the object, the update()
        /// method can be used to update the originally written object.
        /// </summary>
        /// <param name="writer">FileStream to write to.</param>
        /// <returns>Length of data written</returns>
        public ulong Write(FileStream writer)
        {
            ulong elementLength = seekHeadElem.WriteElement(writer);
            ulong voidLength    = placeHolderElement.WriteElement(writer);

            if (elementLength + voidLength != BLOCK_RESEVER_SIZE)
            {
                throw new Exception("ElementLength + VoidLength != Reserved size. Something went wrong");
            }
            return(BLOCK_RESEVER_SIZE);
        }
예제 #2
0
        public Element Write(FileStream writer, MatroskaFileMetaSeek metaSeek)
        {
            ulong currentbytePositionInFile = (ulong)writer.Position;

            Utility.LogDebug($"Writing matroska cues at file byte position [{currentbytePositionInFile}]");
            ulong numberOfBytesInCueData = cues.WriteElement(writer);

            Utility.LogDebug($"Done writing matroska cues, number of bytes was [{numberOfBytesInCueData}]");

            metaSeek.AddIndexedElement(cues, getPositionRelativeToSegmentEbmlElement(currentbytePositionInFile));

            return(cues);
        }
        public ulong WriteTracks(FileStream writer)
        {
            MasterElement trackElements = MatroskaDocTypes.Tracks.GetInstance();

            foreach (var track in tracks)
            {
                trackElements.AddChildElement(track.ToElement());
            }
            trackElements.WriteElement(writer);
            if (BLOCK_SIZE < trackElements.TotalSize)
            {
                throw new Exception("BLOCK_SIZE was greater than the track element. Something went wrong.");
            }
            new VoidElement(BLOCK_SIZE - trackElements.TotalSize).WriteElement(writer);
            return(BLOCK_SIZE);
        }
예제 #4
0
        private void writeEBMLHeader()
        {
            MasterElement ebmlHeaderElement = MatroskaDocTypes.EBML.GetInstance();

            UnsignedIntegerElement ebmlVersionElement = MatroskaDocTypes.EBMLVersion.GetInstance();

            ebmlVersionElement.Value = 1;

            UnsignedIntegerElement ebmlReadVersionElement = MatroskaDocTypes.EBMLReadVersion.GetInstance();

            ebmlReadVersionElement.Value = 1;

            UnsignedIntegerElement ebmlMaxIdLengthElement = MatroskaDocTypes.EBMLMaxIDLength.GetInstance();

            ebmlMaxIdLengthElement.Value = 4;

            UnsignedIntegerElement ebmlMaxSizeLengthElement = MatroskaDocTypes.EBMLMaxSizeLength.GetInstance();

            ebmlMaxSizeLengthElement.Value = 8;

            StringElement docTypeElement = MatroskaDocTypes.DocType.GetInstance();

            docTypeElement.Value = "matroska";

            UnsignedIntegerElement docTypeVersionElement = MatroskaDocTypes.DocTypeVersion.GetInstance();

            docTypeVersionElement.Value = 3;

            UnsignedIntegerElement docTypeReadVersionElement = MatroskaDocTypes.DocTypeReadVersion.GetInstance();

            docTypeReadVersionElement.Value = 2;

            ebmlHeaderElement.AddChildElement(ebmlVersionElement);
            ebmlHeaderElement.AddChildElement(ebmlReadVersionElement);
            ebmlHeaderElement.AddChildElement(ebmlMaxIdLengthElement);
            ebmlHeaderElement.AddChildElement(ebmlMaxSizeLengthElement);
            ebmlHeaderElement.AddChildElement(docTypeElement);
            ebmlHeaderElement.AddChildElement(docTypeVersionElement);
            ebmlHeaderElement.AddChildElement(docTypeReadVersionElement);
            ebmlHeaderElement.WriteElement(Writer);
        }
예제 #5
0
        public long WriteElement(FileStream writer)
        {
            MasterElement segmentInfoElement = MatroskaDocTypes.Info.GetInstance();

            StringElement writingAppElement = MatroskaDocTypes.WritingApp.GetInstance();

            writingAppElement.Value = "Matroska File Writer v1.0 C#";

            StringElement muxingAppElement = MatroskaDocTypes.MuxingApp.GetInstance();

            muxingAppElement.Value = ".NET EBML v1.0";

            DateElement dateElement = MatroskaDocTypes.DateUTC.GetInstance();

            dateElement.Date = SegmentDate;

            UnsignedIntegerElement timecodeScaleElement = MatroskaDocTypes.TimecodeScale.GetInstance();

            timecodeScaleElement.Value = TimecodeScale;

            segmentInfoElement.AddChildElement(dateElement);
            segmentInfoElement.AddChildElement(timecodeScaleElement);

            if (Duration != null)
            {
                FloatElement durationElement = MatroskaDocTypes.Duration.GetInstance();
                durationElement.Value = (double)Duration;
                segmentInfoElement.AddChildElement(durationElement);
            }

            segmentInfoElement.AddChildElement(writingAppElement);
            segmentInfoElement.AddChildElement(muxingAppElement);

            ulong       len    = segmentInfoElement.WriteElement(writer);
            VoidElement spacer = new VoidElement((ulong)BLOCK_SIZE - len);

            spacer.WriteElement(writer);
            return(1);
        }
        public ulong Flush(FileStream writer)
        {
            if (frames.Count == 0)
            {
                return(0);
            }

            try
            {
                MasterElement          clusterElement  = MatroskaDocTypes.Cluster.GetInstance();
                UnsignedIntegerElement timecodeElement = MatroskaDocTypes.Timecode.GetInstance();
                timecodeElement.Value = ClusterTimecode;
                clusterElement.AddChildElement(timecodeElement);

                if (silencedTracks.Count != 0)
                {
                    MasterElement silentElement = MatroskaDocTypes.SilentTracks.GetInstance();
                    foreach (ulong silent in silencedTracks)
                    {
                        UnsignedIntegerElement silentTrackElement = MatroskaDocTypes.SilentTrackNumber.GetInstance();
                        silentTrackElement.Value = silent;
                        silentElement.AddChildElement(silentTrackElement);
                    }
                    clusterElement.AddChildElement(silentElement);
                }

                MatroskaSimpleBlock block = null;
                bool  forceNew            = true;
                ulong lastTimecode        = 0;
                int   lastTrackNumber     = 0;

                foreach (var frame in frames)
                {
                    frame.Timecode -= ClusterTimecode;
                    if (forceNew || lastTimecode != frame.Timecode || lastTrackNumber != frame.TrackNumber)
                    {
                        if (block != null)
                        {
                            clusterElement.AddChildElement(block.ToElement());
                        }
                        block = new MatroskaSimpleBlock();
                    }
                    lastTimecode    = frame.Timecode;
                    lastTrackNumber = frame.TrackNumber;
                    forceNew        = true;
                    block.AddFrame(frame);
                }
                if (block != null)
                {
                    clusterElement.AddChildElement(block.ToElement());
                }
                return(clusterElement.WriteElement(writer));
            }
            finally
            {
                frames.Clear();
                Tracks.Clear();
                totalSize       = 0;
                ClusterTimecode = ulong.MaxValue;
            }
        }