Exemplo n.º 1
0
        public static ResultOfParsingMKV GetSubFromFile(string mkvFilePath)
        {

            ResultOfParsingMKV resPars = new ResultOfParsingMKV();

            using (var fs = new FileStream(mkvFilePath, FileMode.Open, FileAccess.Read))
            {
                using (EbmlReader ebmlReader = new EbmlReader(fs))
                {
                    var segmentFound = ebmlReader.LocateElement(MatroskaElementDescriptorProvider.Segment);
                    if (segmentFound)
                    {
                        StringBuilder sb = new StringBuilder();
                        MatroskaElementDescriptorProvider medp = new MatroskaElementDescriptorProvider();
                        ReadContainer(ebmlReader, medp, resPars, 0, sb);
                    }
                }
            }

            // reenumerate
            foreach(var elm in resPars.dicSub)
            {
                int i = 1;
                var coll = elm.Value.Items.OrderBy(x => x.TimeStart);
                foreach(var elm2 in coll)
                {
                    elm2.Number = i++;
                }
            }

            return resPars;
        }
Exemplo n.º 2
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);
            }

        }
Exemplo n.º 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();
        }