private void WriteData() { var reader = new EbmlReader(new MemoryStream(_oldSegmentInfoData), _oldSegmentInfoData.Length); // prepare writing part var infoStream= new MemoryStream(); var infoWriter = new EbmlWriter(infoStream); var writeMap = new[] { new {Id = MatroskaDtd.Segment.Info.Title.Identifier, Value = _title}, new {Id = MatroskaDtd.Segment.Info.WritingApp.Identifier, Value = _writingApp}, }; // enter the Segment block reader.ReadNext(); reader.EnterContainer(); while (reader.ReadNext()) { if (!writeMap.Any(arg => arg.Id == reader.ElementId)) { // copying data as is var buffer = new byte[reader.ElementSize]; reader.ReadBinary(buffer, 0, (int) reader.ElementSize); infoWriter.Write(reader.ElementId, buffer); } } // write title/app in case it was not present! foreach (var e in writeMap.Where(arg => !string.IsNullOrEmpty(arg.Value))) { infoWriter.WriteUtf(e.Id, e.Value); } var outStream = new MemoryStream(_dataLength); var writer = new EbmlWriter(outStream); writer.Write(MatroskaDtd.Segment.Info.Identifier, infoStream.ToArray()); var extraByteCount = _dataLength - outStream.Position; if (extraByteCount != 0) { var extraHLen = StandardDtd.Void.Identifier.Length + 2; var blankDataLen = (int) (extraByteCount - extraHLen); if (blankDataLen < 0) { throw new InvalidOperationException(string.Format("Not enough space to put the new data, {0} bytes to feet", -blankDataLen)); } writer.WriteElementHeader(StandardDtd.Void.Identifier, VInt.EncodeSize((ulong)blankDataLen, 2)); writer.Write(new byte[blankDataLen], 0, blankDataLen); } if (outStream.Length != _dataLength) throw new InvalidOperationException("Failed to prepare modified data - block length mismatch"); _stream.Position = _dataStart; _stream.Write(outStream.ToArray(), 0, _dataLength); }
private static void ReadContainer(EbmlReader ebmlReader, MatroskaElementDescriptorProvider medp, ResultOfParsingMKV resPars, ulong CurrentClusterTimeCode, StringBuilder sb, string GroupName = "", string add = "") { ebmlReader.EnterContainer(); while (ebmlReader.ReadNext()) { var descriptor = medp.GetElementDescriptor(ebmlReader.ElementId); if (descriptor == null) { sb.Append(add + "undefined \r\n"); continue; } string dName = descriptor.Name; sb.Append(add + dName); if (dName == "TrackEntry") { AnalizeTrackEntry(ebmlReader,medp,resPars,sb,GroupName,add); continue; } switch (descriptor.Type) { case ElementType.MasterElement: sb.Append("\r\n"); ReadContainer(ebmlReader, medp, resPars, CurrentClusterTimeCode, sb,descriptor.Name, add + " "); break; case ElementType.AsciiString: sb.Append(" = " + ebmlReader.ReadAscii()); break; case ElementType.Binary: if (GroupName == "BlockGroup" && (dName == "Block" || dName == "SimpleBlock")) { int lSize = ebmlReader.ElementSize > 1000?1000:Convert.ToInt16(ebmlReader.ElementSize); byte[] arr = new byte[lSize]; ebmlReader.ReadBinary(arr, 0, lSize); int TrackNumber = arr[0] & 0x0F; ulong DurationFromCluster = Convert.ToUInt64(arr[1] * 0xFF + arr[2]); if (resPars.dicSub.ContainsKey(TrackNumber)) { Subtitles lsub = resPars.dicSub[TrackNumber]; SubtitleItem subitem = new SubtitleItem(); lsub.Items.Add(subitem); //subitem.Text = System.Text.Encoding.ASCII.GetString(arr, 4, lSize-4); subitem.Text = System.Text.Encoding.UTF8.GetString(arr, 4, lSize - 4); subitem.TimeStart = ((int)(CurrentClusterTimeCode + DurationFromCluster)); // reading the BlockDuration ebmlReader.ReadNext(); ulong BlockDuration = ebmlReader.ReadUInt(); subitem.TimeEnd = subitem.TimeStart + ((int)BlockDuration); } } sb.Append(" (binary size " + ebmlReader.ElementSize + ")"); break; case ElementType.Date: sb.Append(" = " + ebmlReader.ReadDate()); break; case ElementType.Float: double flVal = ebmlReader.ReadFloat(); sb.Append(" = " + flVal); break; case ElementType.None: sb.Append(" (none)"); break; case ElementType.SignedInteger: sb.Append(" = " + ebmlReader.ReadInt()); break; case ElementType.UnsignedInteger: ulong ulVal = ebmlReader.ReadUInt(); if (GroupName == "Cluster" && dName == "Timecode") { CurrentClusterTimeCode = ulVal; } sb.Append(" = " + ulVal); break; case ElementType.Utf8String: sb.Append(" = " + ebmlReader.ReadUtf()); break; } sb.Append("\r\n"); } ebmlReader.LeaveContainer(); }