Beispiel #1
0
        /// <summary>
        /// Get the available audio streams from a video file
        /// </summary>
        /// <param name="file">The video file</param>
        public static List <InfoStream> getAvailableAudioStreams(string file)
        {
            string            videoInfo   = "";
            List <InfoStream> streamInfos = new List <InfoStream>();

            videoInfo = getVideoInfoStr(file);

            MatchCollection lineMatches = Regex.Matches(videoInfo,
                                                        @".*Stream #(?<AudioStreamNum>\d\:\d)\(?(?<AudioStreamLang>\w*)\)?: Audio: (?<AudioStreamType>.*)",
                                                        RegexOptions.Compiled);

            if (lineMatches.Count != 0)
            {
                int count = 0;
                foreach (Match match in lineMatches)
                {
                    string streamNum = match.Groups["AudioStreamNum"].ToString().Trim();
                    streamNum = streamNum.Replace(".", ":");

                    string streamLang =
                        UtilsLang.LangThreeLetter2Full(match.Groups["AudioStreamLang"].ToString().Trim());
                    string streamType = match.Groups["AudioStreamType"].ToString().Trim();

                    streamInfos.Add(new InfoStream(streamNum, count.ToString(), streamLang, streamType));

                    count++;
                }
            }

            return(streamInfos);
        }
Beispiel #2
0
        private void backgroundWorkerMain_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            MkvExtractProgress progress = new MkvExtractProgress();

            progress.MaxEpisode = selectedMkvFiles.Count;

            foreach (string file in selectedMkvFiles)
            {
                progress.CurEpisode++;

                List <MkvTrack> tracks = null;

                if (trackTypeToExtract == "All subtitle tracks")
                {
                    tracks = UtilsMkv.getSubtitleTrackList(file);
                }
                else if (trackTypeToExtract == "All audio tracks")
                {
                    tracks = UtilsMkv.getAudioTrackList(file);
                }
                else
                {
                    tracks = UtilsMkv.getTrackList(file);
                }

                progress.CurTrack = 0;
                progress.MaxTrack = tracks.Count;

                foreach (MkvTrack track in tracks)
                {
                    if (worker.CancellationPending)
                    {
                        e.Cancel = true;
                        return;
                    }

                    progress.CurTrack++;

                    worker.ReportProgress(0, progress);

                    string displayLang = UtilsLang.LangThreeLetter2Full(track.Lang);

                    if (displayLang == "")
                    {
                        displayLang = "Unknown";
                    }

                    string fileName =
                        $"{outDir}{Path.DirectorySeparatorChar}{Path.GetFileNameWithoutExtension(file)} - Track {Convert.ToInt32(track.TrackID):00} - {displayLang}.{track.Extension}";

                    UtilsMkv.extractTrack(file, track.TrackID, fileName);
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Read a float setting.
        /// </summary>
        public static float getFloat(string key, float def)
        {
            string defString = def.ToString();
            string valString = "";
            float  value     = 0;

            valString = getString(key, defString);

            try
            {
                value = (float)UtilsLang.toDouble(valString);
            }
            catch
            {
                value = def;
            }

            return(value);
        }
Beispiel #4
0
        public override string ToString()
        {
            string displayLang        = UtilsLang.LangThreeLetter2Full(Lang);
            string displayedExtension = Extension.ToUpper();

            if (Lang == "und" || Lang == "" || displayLang == "")
            {
                displayLang = "Unknown Language";
            }

            if (TrackType == UtilsMkv.TrackType.SUBTITLES)
            {
                if (displayedExtension == "SUB")
                {
                    displayedExtension = "VOBSUB";
                }
            }

            return($"{TrackID} - {displayedExtension} ({displayLang})");
        }
Beispiel #5
0
        public override string ToString()
        {
            string displayLang        = UtilsLang.LangThreeLetter2Full(this.Lang);
            string displayedExtension = this.Extension.ToUpper();

            if ((this.Lang == "und") || (this.Lang == "") || (displayLang == ""))
            {
                displayLang = "Unknown Language";
            }

            if (this.TrackType == UtilsMkv.TrackType.SUBTITLES)
            {
                if (displayedExtension == "SUB")
                {
                    displayedExtension = "VOBSUB";
                }
            }

            return(String.Format("{0} - {1} ({2})",
                                 this.TrackID, displayedExtension, displayLang));
        }
        /// <summary>
        /// Parse the subtitle file and return a list of lines.
        /// </summary>
        override public List <InfoLine> parse()
        {
            List <InfoLine> lineInfos = new List <InfoLine>();
            StreamReader    subFile   = new StreamReader(this.File, this.SubsEncoding);

            XmlTextReader xmlReader = new XmlTextReader(subFile);

            xmlReader.XmlResolver = null; // Ignore dtd

            DateTime startTime   = new DateTime();
            DateTime endTime     = new DateTime();
            DateTime curTime     = new DateTime();
            DateTime turnEndTime = new DateTime();
            string   dialogText  = "";
            int      syncCount   = 0;

            while (xmlReader.Read())
            {
                if (xmlReader.NodeType == XmlNodeType.Element)
                {
                    if (xmlReader.Name.ToLower() == "sync")
                    {
                        // Example sync: <Sync time="1.027"/>
                        syncCount++;

                        string timeStr = xmlReader.GetAttribute("time");

                        try
                        {
                            curTime = new DateTime();
                            curTime = curTime.AddSeconds(UtilsLang.toDouble(timeStr));
                        }
                        catch (Exception e1)
                        {
                            throw new Exception(String.Format("Incorrect time format detected: {0}\n\n{1}", timeStr, e1));
                        }

                        if (syncCount == 1)
                        {
                            startTime = curTime;
                        }
                        else if (syncCount == 2)
                        {
                            endTime = curTime;
                        }
                        else
                        {
                            startTime = endTime;
                            endTime   = curTime;
                        }

                        // If this is not the first time and the length isn't blank
                        if ((syncCount > 1) && (dialogText.Length != 0))
                        {
                            lineInfos.Add(this.createLineInfo(dialogText, startTime, endTime));
                            dialogText = "";
                        }
                    }
                    else if (xmlReader.Name.ToLower() == "turn")
                    {
                        // Example turn: <Turn speaker="spk1" startTime="2.263" endTime="25.566">

                        string timeStr = xmlReader.GetAttribute("endTime");

                        turnEndTime = new DateTime();
                        turnEndTime = curTime.AddSeconds(UtilsLang.toDouble(timeStr));
                    }
                }
                else if (xmlReader.NodeType == XmlNodeType.Text)
                {
                    dialogText += xmlReader.Value;
                }
                else if (xmlReader.NodeType == XmlNodeType.EndElement)
                {
                    // This section handles the final line before the </turn>.
                    // We need to do this because there isn't a Sync tag after the final line.

                    if (xmlReader.Name.ToLower() == "turn") // </Turn>
                    {
                        const double MAX_FINAL_LINE_DURATION = 10.0;
                        startTime = endTime;
                        endTime   = turnEndTime;

                        // Calculate the difference between the startTime and turnEndTime and make sure that
                        // it is a reasonable length. We do this because the turn end time isn't necessarily
                        // the end of the line. If it is not a reasonable length, set it to MAX_FINAL_LINE_DURATION.
                        double diffTime = endTime.TimeOfDay.TotalSeconds - startTime.TimeOfDay.TotalSeconds;

                        if (diffTime > MAX_FINAL_LINE_DURATION)
                        {
                            endTime = startTime;
                            endTime = endTime.AddSeconds(MAX_FINAL_LINE_DURATION);
                        }

                        if ((syncCount >= 1) && (dialogText.Length != 0))
                        {
                            lineInfos.Add(this.createLineInfo(dialogText, startTime, endTime));
                            dialogText = "";
                        }

                        // If needed, restore endtime to the turnEndTime
                        if (diffTime >= MAX_FINAL_LINE_DURATION)
                        {
                            endTime = turnEndTime;
                        }
                    }
                }
            }

            subFile.Close();

            // Since the dialog lines don't have to be in chronological order, sort by the start time
            lineInfos.Sort();

            return(lineInfos);
        }
Beispiel #7
0
        /// <summary>
        /// Inactivate lines from episodes based on include/exclude lists, duplicate lines, etc.
        /// Does not remove lines, only modifies their active flag.
        /// </summary>
        public List <List <InfoCombined> > inactivateLines(WorkerVars workerVars, DialogProgress dialogProgress)
        {
            int totalLines   = 0;
            int progessCount = 0;

            foreach (List <InfoCombined> combArray in workerVars.CombinedAll)
            {
                totalLines += combArray.Count;
            }

            bool checkIncludesExludes = Settings.Instance.Subs[0].IncludedWords.Length != 0 ||
                                        Settings.Instance.Subs[1].IncludedWords.Length != 0 ||
                                        Settings.Instance.Subs[0].ExcludedWords.Length != 0 ||
                                        Settings.Instance.Subs[1].ExcludedWords.Length != 0;

            Hashtable allLinesSoFarSubs1 = new Hashtable();
            Hashtable allLinesSoFarSubs2 = new Hashtable();
            bool      removeDupsSubs1    = Settings.Instance.Subs[0].ExcludeDuplicateLinesEnabled;
            bool      removeDupsSubs2    = Settings.Instance.Subs[1].ExcludeDuplicateLinesEnabled &&
                                           Settings.Instance.Subs[1].FilePattern != "";
            bool checkDups = removeDupsSubs1 || removeDupsSubs2;

            // For each episode
            foreach (List <InfoCombined> combArray in workerVars.CombinedAll)
            {
                List <InfoCombined> compArrayRemoved = new List <InfoCombined>();

                // For each line in episode
                foreach (InfoCombined comb in combArray)
                {
                    bool isExcluded = false;
                    progessCount++;

                    // Don't process if subtitles are vobsub
                    bool isSubs1Vobsub = UtilsSubs.filePatternContainsVobsubs(Settings.Instance.Subs[0].FilePattern);
                    bool isSubs2Vobsub = UtilsSubs.filePatternContainsVobsubs(Settings.Instance.Subs[1].FilePattern);

                    // Remove lines not in the span
                    if (Settings.Instance.SpanEnabled && !isExcluded)
                    {
                        DateTime spanStart = Settings.Instance.SpanStart;
                        DateTime spanEnd   = Settings.Instance.SpanEnd;

                        if (comb.Subs1.StartTime < spanStart || comb.Subs1.StartTime > spanEnd)
                        {
                            isExcluded = true;
                        }
                    }


                    bool passedIgnoreShorterThanTime = true;

                    // Make sure that line is at least the min amount of milliseconds as specified by user
                    if (Settings.Instance.Subs[0].ExcludeShorterThanTimeEnabled &&
                        Settings.Instance.Subs[0].TimingsEnabled)
                    {
                        passedIgnoreShorterThanTime =
                            Math.Abs((int)comb.Subs1.EndTime.TimeOfDay.TotalMilliseconds -
                                     (int)comb.Subs1.StartTime.TimeOfDay.TotalMilliseconds) >=
                            Settings.Instance.Subs[0].ExcludeShorterThanTime;
                    }
                    else if (Settings.Instance.Subs[1].ExcludeShorterThanTimeEnabled &&
                             Settings.Instance.Subs[1].TimingsEnabled)
                    {
                        // Note: using Subs1 here is not a mistake because Subs2 timings will be placed into Subs1 in combineSubs().
                        passedIgnoreShorterThanTime =
                            Math.Abs((int)comb.Subs1.EndTime.TimeOfDay.TotalMilliseconds -
                                     (int)comb.Subs1.StartTime.TimeOfDay.TotalMilliseconds) >=
                            Settings.Instance.Subs[1].ExcludeShorterThanTime;
                    }

                    if (!passedIgnoreShorterThanTime && !isExcluded)
                    {
                        isExcluded = true;
                    }


                    bool passedIgnoreLongerThanTime = true;

                    // Make sure that line is at least the min amount of milliseconds as specified by user
                    if (Settings.Instance.Subs[0].ExcludeLongerThanTimeEnabled &&
                        Settings.Instance.Subs[0].TimingsEnabled)
                    {
                        passedIgnoreLongerThanTime =
                            Math.Abs((int)comb.Subs1.EndTime.TimeOfDay.TotalMilliseconds -
                                     (int)comb.Subs1.StartTime.TimeOfDay.TotalMilliseconds) <=
                            Settings.Instance.Subs[0].ExcludeLongerThanTime;
                    }
                    else if (Settings.Instance.Subs[1].ExcludeLongerThanTimeEnabled &&
                             Settings.Instance.Subs[1].TimingsEnabled)
                    {
                        // Note: using Subs1 here is not a mistake because Subs2 timings will be placed into Subs1 in combineSubs().
                        passedIgnoreLongerThanTime =
                            Math.Abs((int)comb.Subs1.EndTime.TimeOfDay.TotalMilliseconds -
                                     (int)comb.Subs1.StartTime.TimeOfDay.TotalMilliseconds) <=
                            Settings.Instance.Subs[1].ExcludeLongerThanTime;
                    }

                    if (!passedIgnoreLongerThanTime && !isExcluded)
                    {
                        isExcluded = true;
                    }


                    // Make sure that line is at least the min character length as specified by user
                    bool passedIgnoreFewerTestSubs1 =
                        isSubs1Vobsub ||
                        !Settings.Instance.Subs[0].ExcludeFewerEnabled ||
                        Settings.Instance.Subs[0].ExcludeFewerEnabled &&
                        comb.Subs1.Text.Length >= Settings.Instance.Subs[0].ExcludeFewerCount;

                    bool passedIgnoreFewerTestSubs2 = isSubs2Vobsub ||
                                                      !Settings.Instance.Subs[1].ExcludeFewerEnabled ||
                                                      Settings.Instance.Subs[1].ExcludeFewerEnabled &&
                                                      comb.Subs2.Text.Length >=
                                                      Settings.Instance.Subs[1].ExcludeFewerCount;

                    if ((!passedIgnoreFewerTestSubs1 || !passedIgnoreFewerTestSubs2) && !isExcluded)
                    {
                        isExcluded = true;
                    }


                    // Remove based on actors
                    if (Settings.Instance.ActorList.Count > 0 && !isExcluded)
                    {
                        bool actorFound = false;
                        foreach (string actor in Settings.Instance.ActorList)
                        {
                            if (Settings.Instance.Subs[0].ActorsEnabled)
                            {
                                if (comb.Subs1.Actor.Trim().ToLower() == actor.Trim().ToLower())
                                {
                                    actorFound = true;
                                    break;
                                }
                            }
                            else
                            {
                                if (comb.Subs2.Actor.Trim().ToLower() == actor.Trim().ToLower())
                                {
                                    actorFound = true;
                                    break;
                                }
                            }
                        }

                        isExcluded = !actorFound;
                    }


                    // Remove based on include/exclude lists
                    if (checkIncludesExludes && !isExcluded)
                    {
                        if (!isSubs1Vobsub && Settings.Instance.Subs[0].ExcludedWords.Length != 0)
                        {
                            foreach (string word in Settings.Instance.Subs[0].ExcludedWords)
                            {
                                if (comb.Subs1.Text.ToLower().Contains(word.ToLower()))
                                {
                                    isExcluded = true;
                                }
                            }
                        }

                        if (!isSubs2Vobsub && Settings.Instance.Subs[1].ExcludedWords.Length != 0 && !isExcluded)
                        {
                            foreach (string word in Settings.Instance.Subs[1].ExcludedWords)
                            {
                                if (comb.Subs2.Text.ToLower().Contains(word.ToLower()))
                                {
                                    isExcluded = true;
                                }
                            }
                        }

                        if (!isSubs1Vobsub && Settings.Instance.Subs[0].IncludedWords.Length != 0 && !isExcluded)
                        {
                            bool wordFound = false;
                            foreach (string word in Settings.Instance.Subs[0].IncludedWords)
                            {
                                if (comb.Subs1.Text.ToLower().Contains(word.ToLower()))
                                {
                                    wordFound = true;
                                    break;
                                }
                            }

                            isExcluded = !wordFound;
                        }

                        if (!isSubs2Vobsub && Settings.Instance.Subs[1].IncludedWords.Length != 0 && !isExcluded)
                        {
                            bool wordFound = false;
                            foreach (string word in Settings.Instance.Subs[1].IncludedWords)
                            {
                                if (comb.Subs2.Text.ToLower().Contains(word.ToLower()))
                                {
                                    wordFound = true;
                                    break;
                                }
                            }

                            isExcluded = !wordFound;
                        }
                    }


                    // Remove Duplicates
                    if (checkDups && !isExcluded)
                    {
                        if (!isSubs1Vobsub && removeDupsSubs1)
                        {
                            if (allLinesSoFarSubs1.Contains(comb.Subs1.Text.ToLower()))
                            {
                                isExcluded = true;
                            }
                            else
                            {
                                allLinesSoFarSubs1.Add(comb.Subs1.Text.ToLower(), comb);
                            }
                        }

                        if (!isSubs2Vobsub && removeDupsSubs2)
                        {
                            if (allLinesSoFarSubs2.Contains(comb.Subs2.Text.ToLower()))
                            {
                                isExcluded = true;
                            }
                            else
                            {
                                allLinesSoFarSubs2.Add(comb.Subs2.Text.ToLower(), comb);
                            }
                        }
                    }


                    // Remove lines without a kanji
                    if (Settings.Instance.LangaugeSpecific.KanjiLinesOnly && !isExcluded)
                    {
                        if (!isSubs1Vobsub && !UtilsLang.containsIdeograph(comb.Subs1.Text) && !isSubs2Vobsub && !UtilsLang.containsIdeograph(comb.Subs2.Text))
                        {
                            isExcluded = true;
                        }
                    }

                    // Unset the active flag
                    if (isExcluded)
                    {
                        comb.Active = false;
                    }

                    string progressText =
                        $"Setting active lines based on user specified rules: {Convert.ToInt32(progessCount * (100.0 / totalLines))}%";

                    int progress = Convert.ToInt32(progessCount * (100.0 / totalLines));

                    DialogProgress.updateProgressInvoke(dialogProgress, progress, progressText);

                    if (dialogProgress.Cancel)
                    {
                        return(null);
                    }
                }
            }

            return(workerVars.CombinedAll);
        }