Example #1
0
        /// <summary>
        /// Get a list with the inactive lines removed from each episode.
        /// </summary>
        public List <List <InfoCombined> > removeInactiveLines(WorkerVars workerVars, DialogProgress dialogProgress,
                                                               bool dontRemoveContextLines)
        {
            int totalLines   = 0;
            int progessCount = 0;
            List <List <InfoCombined> > activeLines = new List <List <InfoCombined> >();

            bool subs1ContainsVobsubs = UtilsSubs.filePatternContainsVobsubs(Settings.Instance.Subs[0].FilePattern);
            bool subs2ContainsVobsubs = UtilsSubs.filePatternContainsVobsubs(Settings.Instance.Subs[1].FilePattern);

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

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

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

                    if (comb.Active || dontRemoveContextLines && comb.OnlyNeededForContext)
                    {
                        currentEpisodeActiveLines.Add(comb);
                    }
                    else
                    {
                        if (subs1ContainsVobsubs)
                        {
                            try
                            {
                                // Multiple vobsub images can be shown in a single line, so extract each image and delete it
                                List <string> vobsubImages = UtilsSubs.extractVobsubFilesFromText(comb.Subs1.Text);

                                foreach (string vobsubImage in vobsubImages)
                                {
                                    File.Delete(workerVars.MediaDir + Path.DirectorySeparatorChar + vobsubImage);
                                }
                            }
                            catch
                            {
                                // Don't care
                            }
                        }

                        if (subs2ContainsVobsubs)
                        {
                            try
                            {
                                // Multiple vobsub image can be shown in a single line, so extract each image and delete it
                                List <string> vobsubImages = UtilsSubs.extractVobsubFilesFromText(comb.Subs2.Text);

                                foreach (string vobsubImage in vobsubImages)
                                {
                                    File.Delete(workerVars.MediaDir + Path.DirectorySeparatorChar + vobsubImage);
                                }
                            }
                            catch
                            {
                                // Don't care
                            }
                        }
                    }

                    string progressText =
                        $"Remove inactive lines: {Convert.ToInt32(progessCount * (100.0 / totalLines))}%";

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

                    DialogProgress.updateProgressInvoke(dialogProgress, progress, progressText);

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

                activeLines.Add(currentEpisodeActiveLines);
            }

            return(activeLines);
        }
Example #2
0
        /// <summary>
        /// Pair lines from Subs1 to Subs2.
        ///
        /// Subs2srs takes a two-pass approach when it combines Subs1 and Subs2. The first pass matches a line from
        /// Subs1 to the closest line in Subs2. Closest here meaning the difference in start times. This will work fine
        /// assuming that both Subs1 and Subs2 have the exact same number of lines and that lines are similarly timed.
        /// Naturally, this is almost never the case. The result being that some lines will be skipped and others repeated.
        /// The second pass adds back in any lines that were skipped by combining them with others lines and doesn't allow
        /// the same line to be repeated.
        ///
        /// This is used by the Main Dialog, Preview, Dueling Subtitles tools, and Extract Audio from Media Tool.
        /// </summary>
        public List <List <InfoCombined> > combineAllSubs(WorkerVars workerVars, DialogProgress dialogProgress)
        {
            List <List <InfoCombined> > combinedAll = new List <List <InfoCombined> >();
            int totalEpisodes = Settings.Instance.Subs[0].Files.Length;

            // For each episode
            for (int epIdx = 0; epIdx < totalEpisodes; epIdx++)
            {
                SubsParser      subs1Parser          = null;
                SubsParser      subs2Parser          = null;
                List <InfoLine> subs1LineInfos       = null;
                List <InfoLine> subs2LineInfos       = null;
                string          curSub1File          = Settings.Instance.Subs[0].Files[epIdx];
                string          curSub2File          = "";
                bool            subs1ContainsVobsubs = UtilsSubs.filePatternContainsVobsubs(Settings.Instance.Subs[0].FilePattern);
                bool            subs2ContainsVobsubs = UtilsSubs.filePatternContainsVobsubs(Settings.Instance.Subs[1].FilePattern);

                string progressText = $"Processing subtitles for episode {epIdx + 1} of {totalEpisodes}";

                if (subs1ContainsVobsubs || subs2ContainsVobsubs)
                {
                    progressText += "\nNote: Vobsubs (.idx/.sub) can take a few moments to process.";
                }

                int progress = Convert.ToInt32((epIdx + 1) * (100.0 / totalEpisodes));

                DialogProgress.updateProgressInvoke(dialogProgress, progress, progressText);

                int streamSubs1 = 0;
                int streamSubs2 = 0;

                // In the subtitles are in Vobsub format, get the stream to use
                if (subs1ContainsVobsubs)
                {
                    streamSubs1 = Convert.ToInt32(Settings.Instance.Subs[0].VobsubStream.Num);
                }

                if (subs2ContainsVobsubs)
                {
                    streamSubs2 = Convert.ToInt32(Settings.Instance.Subs[1].VobsubStream.Num);
                }

                // Parse Subs1
                subs1Parser = UtilsSubs.getSubtitleParserType(workerVars, curSub1File, streamSubs1,
                                                              epIdx + Settings.Instance.EpisodeStartNumber, 1,
                                                              Encoding.GetEncoding(Settings.Instance.Subs[0].Encoding));

                Logger.Instance.writeFileToLog(curSub1File, Encoding.GetEncoding(Settings.Instance.Subs[0].Encoding));

                subs1LineInfos = subs1Parser.parse();

                if (subs1LineInfos == null)
                {
                    return(null);
                }

                subs1LineInfos = removeIncorrectlyTimedLines(subs1LineInfos);

                if (Settings.Instance.Subs[0].JoinSentencesEnabled && !subs1ContainsVobsubs)
                {
                    subs1LineInfos = combinePartialLinesIntoSentence(subs1LineInfos,
                                                                     Settings.Instance.Subs[0].JoinSentencesCharList);
                }

                // Apply Subs1 time shift
                if (Settings.Instance.TimeShiftEnabled)
                {
                    foreach (InfoLine line in subs1LineInfos)
                    {
                        line.StartTime = UtilsSubs.shiftTiming(line.StartTime, Settings.Instance.Subs[0].TimeShift);
                        line.EndTime   = UtilsSubs.shiftTiming(line.EndTime, Settings.Instance.Subs[0].TimeShift);
                    }
                }

                // Parse Subs2 (if needed)
                if (Settings.Instance.Subs[1].Files.Length != 0)
                {
                    curSub2File = Settings.Instance.Subs[1].Files[epIdx];
                    subs2Parser = UtilsSubs.getSubtitleParserType(workerVars, curSub2File, streamSubs2,
                                                                  epIdx + Settings.Instance.EpisodeStartNumber, 2,
                                                                  Encoding.GetEncoding(Settings.Instance.Subs[1].Encoding));

                    Logger.Instance.writeFileToLog(curSub2File,
                                                   Encoding.GetEncoding(Settings.Instance.Subs[1].Encoding));

                    subs2LineInfos = subs2Parser.parse();

                    if (subs2LineInfos == null)
                    {
                        return(null);
                    }

                    subs2LineInfos = removeIncorrectlyTimedLines(subs2LineInfos);

                    if (Settings.Instance.Subs[1].JoinSentencesEnabled && !subs2ContainsVobsubs)
                    {
                        subs2LineInfos = combinePartialLinesIntoSentence(subs2LineInfos,
                                                                         Settings.Instance.Subs[1].JoinSentencesCharList);
                    }

                    // Apply Subs2 time shift
                    if (Settings.Instance.TimeShiftEnabled)
                    {
                        foreach (InfoLine line in subs2LineInfos)
                        {
                            line.StartTime = UtilsSubs.shiftTiming(line.StartTime, Settings.Instance.Subs[1].TimeShift);
                            line.EndTime   = UtilsSubs.shiftTiming(line.EndTime, Settings.Instance.Subs[1].TimeShift);
                        }
                    }
                }
                else
                {
                    subs2LineInfos = subs1LineInfos;
                }

                // Pass 1: Match each Subs1 to the closest Subs2
                List <InfoCombined> combinedSubs = pass1CombineSubs(subs1LineInfos, subs2LineInfos);

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


                // Pass 2: Fix mismatches present after Pass 1.
                if (Settings.Instance.Subs[1].Files.Length != 0)
                {
                    combinedSubs = pass2FixMismatches(combinedSubs, subs2LineInfos);

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

                // Adjust the timings based on user preference
                foreach (InfoCombined comb in combinedSubs)
                {
                    // Use Subs2 timings?
                    if (Settings.Instance.Subs[1].TimingsEnabled)
                    {
                        // Important Note:
                        // The rest of the software uses subs1 for timing, so just cram subs2 timings into subs1
                        comb.Subs1.StartTime = comb.Subs2.StartTime;
                        comb.Subs1.EndTime   = comb.Subs2.EndTime;
                    }
                }

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

                // Add this episode's paired lines
                combinedAll.Add(combinedSubs);
            }

            return(combinedAll);
        }
Example #3
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);
        }
Example #4
0
        /// <summary>
        /// Copy the Vobsub image files from the temporary preview directory to the media directory.
        /// </summary>
        public bool copyVobsubsFromPreviewDirToMediaDir(WorkerVars workerVars, DialogProgress dialogProgress)
        {
            int totalLines   = 0;
            int progessCount = 0;

            bool   subs1ContainsVobsubs = UtilsSubs.filePatternContainsVobsubs(Settings.Instance.Subs[0].FilePattern);
            bool   subs2ContainsVobsubs = UtilsSubs.filePatternContainsVobsubs(Settings.Instance.Subs[1].FilePattern);
            string tempPreviewDir       = Path.GetTempPath() + ConstantSettings.TempPreviewDirName;

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

            // For each episode
            foreach (List <InfoCombined> combArray in workerVars.CombinedAll)
            {
                // For each line in episode
                foreach (InfoCombined comb in combArray)
                {
                    progessCount++;

                    if (subs1ContainsVobsubs)
                    {
                        try
                        {
                            // Multiple vobsub image can be shown in a single line, so copy each of them
                            List <string> vobsubImages = UtilsSubs.extractVobsubFilesFromText(comb.Subs1.Text);

                            foreach (string vobsubImage in vobsubImages)
                            {
                                File.Copy(tempPreviewDir + Path.DirectorySeparatorChar + vobsubImage,
                                          workerVars.MediaDir + Path.DirectorySeparatorChar + vobsubImage);
                            }
                        }
                        catch
                        {
                            // Don't care
                        }
                    }

                    if (subs2ContainsVobsubs)
                    {
                        try
                        {
                            // Multiple vobsub image can be shown in a single line, so copy each of them
                            List <string> vobsubImages = UtilsSubs.extractVobsubFilesFromText(comb.Subs2.Text);

                            foreach (string vobsubImage in vobsubImages)
                            {
                                File.Copy(tempPreviewDir + Path.DirectorySeparatorChar + vobsubImage,
                                          workerVars.MediaDir + Path.DirectorySeparatorChar + vobsubImage);
                            }
                        }
                        catch
                        {
                            // Don't care
                        }
                    }

                    string progressText =
                        $"Copying vobsubs to .media directory: {Convert.ToInt32(progessCount * (100.0 / totalLines))}%";

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

                    DialogProgress.updateProgressInvoke(dialogProgress, progress, progressText);

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

            return(true);
        }