Exemple #1
0
        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();
        }