示例#1
0
        private static void AnalizeTrackEntry(EbmlReader ebmlReader, MatroskaElementDescriptorProvider medp, ResultOfParsingMKV resPars, StringBuilder sb, string GroupName = "", string add = "")
        {
            ulong TrackNumber = 0;
            ulong TrackUID = 0;
            ulong TrackType = 0;
            ulong FlagDefault = 0;
            ulong FlagLacing = 0;
            string CodecID = "";
            string Name = "";
            ulong  DefaultDuration = 0;
            string Language = "";
            
            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);

                switch (descriptor.Type)
                {
                    case ElementType.MasterElement:
                        sb.Append("\r\n");
                        //ReadContainer(ebmlReader, medp, dicSub, CurrentClusterTimeCode, sb, descriptor.Name, add + "    ");
                        break;
                    case ElementType.AsciiString:
                        string strVal = ebmlReader.ReadAscii();
                        if(dName == "CodecID") CodecID = strVal; 
                        if (dName == "Language") Language = strVal; 
                        sb.Append(" = " + strVal);
                        break;
                    case ElementType.Binary:
                        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(dName == "TrackNumber") TrackNumber = ulVal;
                        if(dName == "TrackType") TrackType = ulVal;
                        if(dName == "FlagDefault") FlagDefault = ulVal;
                        if(dName == "FlagLacing ") FlagLacing = ulVal;
                        if(dName == "DefaultDuration") DefaultDuration = ulVal;
                        if (dName == "TrackUID") TrackUID = ulVal;
                        sb.Append(" = " + ulVal);
                        break;
                    case ElementType.Utf8String:
                        string utfStr = ebmlReader.ReadUtf();
                        if (dName == "Name") Name = utfStr;
                        sb.Append(" = " + utfStr);
                        break;
                }
                sb.Append("\r\n");
            }
            ebmlReader.LeaveContainer();
            
            // If it's subtitles track
            if (TrackType == 17) { 
                Subtitles sub = new Subtitles();
                sub.Items = new SynchronizedObservableCollection<SubtitleItem>();
                sub.Language = Language.Length == 0 ? "eng" : Language;
                sub.Type = Name;
                sub.Format = CodecID;
                sub.TrackUID = (long)TrackUID;

                resPars.dicSub.Add(Convert.ToInt16(TrackNumber),sub);
            }

            // If it's subtitles track
            if (TrackType == 2)
            {
                AudioTrack aud = new AudioTrack();
                aud.Language = Language.Length == 0 ? "eng" : Language;
                aud.CodecID = CodecID;
                aud.Number = resPars.AudioTracks.Count + 1;

                resPars.AudioTracks.Add(aud);
            }

        }
示例#2
0
        private void ReadData(Stream src)
        {
            var reader = new EbmlReader(src);

            var readMap = new[]
                {
                    new {Element = MatroskaDtd.Segment.Info.Title, Code = new Action(() => _title = reader.ReadUtf())},
                    new {Element = MatroskaDtd.Segment.Info.WritingApp, Code = new Action(() => _writingApp = reader.ReadUtf())},
                    new {Element = MatroskaDtd.Segment.Info.MuxingApp, Code = new Action(() => MuxingApp = reader.ReadUtf())},
                    new {Element = MatroskaDtd.Segment.Info.Duration, Code = new Action(() => Duration = TimeSpan.FromMilliseconds(reader.ReadFloat()))},
                };

            if (!reader.LocateElement(MatroskaDtd.Segment))
                throw new InvalidDataException("Failed to locate Segment");

            reader.EnterContainer();

            var segmentInfoIdentifier = MatroskaDtd.Segment.Info.Identifier;

            // support for Void block right before SegmentInfo
            var priorElementId = VInt.MakeId(0);
            var priorElementStart = -1l;

            // locate SegmentInfo and track its predesessor
            while (reader.ReadNext())
            {
                if (reader.ElementId == segmentInfoIdentifier) break;
                priorElementId = reader.ElementId;
                priorElementStart = reader.ElementPosition;
            }

            if (reader.ElementId != segmentInfoIdentifier)
                throw new InvalidDataException("Failed to locate Segment");

            _dataStart = priorElementId == StandardDtd.Void.Identifier ? priorElementStart : reader.ElementPosition;
            var oldDataStart = reader.ElementPosition;

            reader.EnterContainer();

            while (reader.ReadNext())
            {
                var entry = readMap.FirstOrDefault(arg => arg.Element.Identifier == reader.ElementId);
                if (entry != null)
                    entry.Code();
            }

            reader.LeaveContainer();

            // getting start of the next element
            reader.ReadNext();
            if (reader.ElementId == StandardDtd.Void.Identifier)
            {
                reader.ReadNext();
            }
            _dataLength = (int)(reader.ElementPosition - _dataStart);

            var oldDataLen = (int)(reader.ElementPosition - oldDataStart);
            _oldSegmentInfoData = new byte[oldDataLen];
            _stream.Seek(oldDataStart, SeekOrigin.Begin);
            _stream.Read(_oldSegmentInfoData, 0, oldDataLen);
        }
示例#3
0
        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();
        }