/// <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); }
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); }
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); }
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; } }