Exemple #1
0
        /// <summary>
        /// Generate snapshots for all episodes.
        /// </summary>
        public bool genSnapshots(WorkerVars workerVars, DialogProgress dialogProgress)
        {
            int      progessCount  = 0;
            int      episodeCount  = 0;
            int      totalEpisodes = workerVars.CombinedAll.Count;
            int      totalLines    = UtilsSubs.getTotalLineCount(workerVars.CombinedAll);
            DateTime lastTime      = UtilsSubs.getLastTime(workerVars.CombinedAll);

            UtilsName name = new UtilsName(Settings.Instance.DeckName, totalEpisodes,
                                           totalLines, lastTime, Settings.Instance.VideoClips.Size.Width,
                                           Settings.Instance.VideoClips.Size.Height);

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

                // For each line in episode, generate a snapshot
                foreach (InfoCombined t in combArray)
                {
                    progessCount++;

                    string progressText = $"Generating snapshot: {progessCount.ToString()} of {totalLines.ToString()}";

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

                    // Update the progress dialog
                    DialogProgress.updateProgressInvoke(dialogProgress, progress, progressText);

                    InfoCombined comb      = t;
                    DateTime     startTime = comb.Subs1.StartTime;
                    DateTime     endTime   = comb.Subs1.EndTime;
                    DateTime     midTime   = UtilsSubs.getMidpointTime(startTime, endTime);

                    string videoFileName = Settings.Instance.VideoClips.Files[episodeCount - 1];

                    // Create output filename
                    string nameStr = name.createName(ConstantSettings.SnapshotFilenameFormat,
                                                     (int)episodeCount + Settings.Instance.EpisodeStartNumber - 1,
                                                     progessCount, startTime, endTime, comb.Subs1.Text, comb.Subs2.Text);

                    string outFile = $"{workerVars.MediaDir}{Path.DirectorySeparatorChar}{nameStr}"; // {2}

                    // Generate snapshot
                    UtilsSnapshot.takeSnapshotFromVideo(videoFileName, midTime, Settings.Instance.Snapshots.Size,
                                                        Settings.Instance.Snapshots.Crop, outFile);

                    // Did the user press the cancel button?
                    if (dialogProgress.Cancel)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Exemple #2
0
        /// <summary>
        /// Generate the SRS import file.
        /// </summary>
        public bool genSrs(WorkerVars workerVars, DialogProgress dialogProgress)
        {
            int episodeIdx    = -1;
            int totalEpisodes = workerVars.CombinedAll.Count;
            int lineIdx       = -1;
            int totalLines    = UtilsSubs.getTotalLineCount(workerVars.CombinedAll);

            lastTime = UtilsSubs.getLastTime(workerVars.CombinedAll);

            name = new UtilsName(Settings.Instance.DeckName, totalEpisodes,
                                 totalLines, lastTime, Settings.Instance.VideoClips.Size.Width,
                                 Settings.Instance.VideoClips.Size.Height);

            string nameStr = name.createName(ConstantSettings.SrsFilenameFormat, 0,
                                             0, new DateTime(), new DateTime(), "", "");

            // Create filename
            // Example: <outdir>\Toki_wo_Kakeru_Shoujo.tsv
            string     srsFilename = $"{Settings.Instance.OutputDir}{Path.DirectorySeparatorChar}{nameStr}";
            TextWriter srsWriter   = new StreamWriter(srsFilename, false, Encoding.UTF8);

            // For each episode
            foreach (List <InfoCombined> combArray in workerVars.CombinedAll)
            {
                episodeIdx++;
                lineIdx = -1;

                // For each line in episode, process
                foreach (InfoCombined comb in combArray)
                {
                    progessCount++;
                    lineIdx++;
                    mainComb = comb;

                    // Skip lines that are only needed for context
                    if (mainComb.OnlyNeededForContext)
                    {
                        continue;
                    }

                    string srsLine = "";

                    // Format the current import file line
                    srsLine = formatAll(workerVars.CombinedAll, episodeIdx, lineIdx, FormatType.Normal);

                    // Add leading context lines
                    if (Settings.Instance.ContextLeadingCount > 0)
                    {
                        for (int i = Settings.Instance.ContextLeadingCount; i > 0; i--)
                        {
                            int prevLineIdx = lineIdx - i;

                            if (prevLineIdx >= 0)
                            {
                                if (isLineInContextRange(combArray, lineIdx, prevLineIdx))
                                {
                                    srsLine += formatAll(workerVars.CombinedAll, episodeIdx, prevLineIdx,
                                                         FormatType.Leading);
                                }
                                else
                                {
                                    srsLine += formatContextPlaceholder(FormatType.Leading);
                                }
                            }
                            else
                            {
                                srsLine += formatContextPlaceholder(FormatType.Leading);
                            }
                        }
                    }

                    // Add trailing context lines
                    if (Settings.Instance.ContextTrailingCount > 0)
                    {
                        for (int i = 1; i <= Settings.Instance.ContextTrailingCount; i++)
                        {
                            int nextLineIdx = lineIdx + i;

                            if (nextLineIdx < combArray.Count)
                            {
                                if (isLineInContextRange(combArray, lineIdx, nextLineIdx))
                                {
                                    srsLine += formatAll(workerVars.CombinedAll, episodeIdx, nextLineIdx,
                                                         FormatType.Trailing);
                                }
                                else
                                {
                                    srsLine += formatContextPlaceholder(FormatType.Trailing);
                                }
                            }
                            else
                            {
                                srsLine += formatContextPlaceholder(FormatType.Trailing);
                            }
                        }
                    }

                    // Write line to file
                    srsWriter.WriteLine(srsLine);

                    string progressText =
                        $"Generating SRS (ex. Anki) import file: line {progessCount.ToString()} of {totalLines.ToString()}";

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

                    DialogProgress.updateProgressInvoke(dialogProgress, progress, progressText);

                    // Did the user press the cancel button?
                    if (dialogProgress.Cancel)
                    {
                        srsWriter.Close();
                        return(false);
                    }
                }
            }

            srsWriter.Close();

            return(true);
        }
Exemple #3
0
        /// <summary>
        /// Generate video clips for all episodes.
        /// </summary>
        public bool genVideoClip(WorkerVars workerVars, DialogProgress dialogProgress)
        {
            int      progessCount  = 0;
            int      episodeCount  = 0;
            int      totalEpisodes = workerVars.CombinedAll.Count;
            int      totalLines    = UtilsSubs.getTotalLineCount(workerVars.CombinedAll);
            DateTime lastTime      = UtilsSubs.getLastTime(workerVars.CombinedAll);

            UtilsName name = new UtilsName(Settings.Instance.DeckName, totalEpisodes,
                                           totalLines, lastTime, Settings.Instance.VideoClips.Size.Width, Settings.Instance.VideoClips.Size.Height);

            DialogProgress.updateProgressInvoke(dialogProgress, 0, "Creating video clips.");

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

                // It is possible for all lines in an episode to be set to inactive
                if (combArray.Count == 0)
                {
                    // Skip this episode
                    continue;
                }

                string progressText = String.Format("Converting video file {0} of {1}",
                                                    episodeCount,
                                                    totalEpisodes);

                DialogProgress.updateProgressInvoke(dialogProgress, progressText);

                DateTime entireClipStartTime = combArray[0].Subs1.StartTime;
                DateTime entireClipEndTime   = combArray[combArray.Count - 1].Subs1.EndTime;

                // Apply pad to entire clip timings  (if requested)
                if (Settings.Instance.VideoClips.PadEnabled)
                {
                    entireClipStartTime = UtilsSubs.applyTimePad(entireClipStartTime, -Settings.Instance.VideoClips.PadStart);
                    entireClipEndTime   = UtilsSubs.applyTimePad(entireClipEndTime, Settings.Instance.VideoClips.PadEnd);
                }

                // Enable detail mode in progress dialog
                DialogProgress.enableDetailInvoke(dialogProgress, true);

                // Set the duration of the clip in the progress dialog  (for detail mode)
                DateTime entireClipDuration = UtilsSubs.getDurationTime(entireClipStartTime, entireClipEndTime);
                DialogProgress.setDuration(dialogProgress, entireClipDuration);

                string tempVideoFilename = Path.GetTempPath() + ConstantSettings.TempVideoFilename;
                string videoExtension    = ".avi";

                // Convert entire video (from first line to last line) based on user settings (size, crop, bitrate, etc).
                // It will be cut into smaller video clips later.
                if (Settings.Instance.VideoClips.IPodSupport)
                {
                    videoExtension     = ".mp4";
                    tempVideoFilename += videoExtension;

                    UtilsVideo.convertVideo(Settings.Instance.VideoClips.Files[episodeCount - 1],
                                            Settings.Instance.VideoClips.AudioStream.Num,
                                            entireClipStartTime, entireClipEndTime,
                                            Settings.Instance.VideoClips.Size, Settings.Instance.VideoClips.Crop,
                                            Settings.Instance.VideoClips.BitrateVideo, Settings.Instance.VideoClips.BitrateAudio,
                                            UtilsVideo.VideoCodec.h264, UtilsVideo.AudioCodec.AAC,
                                            UtilsVideo.Profilex264.IPod640, UtilsVideo.Presetx264.SuperFast,
                                            tempVideoFilename, dialogProgress);
                }
                else
                {
                    tempVideoFilename += videoExtension;

                    UtilsVideo.convertVideo(Settings.Instance.VideoClips.Files[episodeCount - 1],
                                            Settings.Instance.VideoClips.AudioStream.Num,
                                            entireClipStartTime, entireClipEndTime,
                                            Settings.Instance.VideoClips.Size, Settings.Instance.VideoClips.Crop,
                                            Settings.Instance.VideoClips.BitrateVideo, Settings.Instance.VideoClips.BitrateAudio,
                                            UtilsVideo.VideoCodec.MPEG4, UtilsVideo.AudioCodec.MP3,
                                            UtilsVideo.Profilex264.None, UtilsVideo.Presetx264.None,
                                            tempVideoFilename, dialogProgress);
                }

                DialogProgress.enableDetailInvoke(dialogProgress, false);

                // Generate a video clip for each line of the episode
                foreach (InfoCombined comb in combArray)
                {
                    progessCount++;

                    progressText = string.Format("Generating video clip: {0} of {1}",
                                                 progessCount.ToString(),
                                                 totalLines.ToString());

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

                    // Update the progress dialog
                    DialogProgress.updateProgressInvoke(dialogProgress, progress, progressText);

                    // Did the user press the cancel button?
                    if (dialogProgress.Cancel)
                    {
                        File.Delete(tempVideoFilename);
                        return(false);
                    }

                    // Adjust timing to sync with the start of the converted video (which starts at the episode's first line of dialog)
                    DateTime startTime = UtilsSubs.shiftTiming(comb.Subs1.StartTime, -((int)entireClipStartTime.TimeOfDay.TotalMilliseconds));
                    DateTime endTime   = UtilsSubs.shiftTiming(comb.Subs1.EndTime, -((int)entireClipStartTime.TimeOfDay.TotalMilliseconds));

                    // Times used in the filename
                    DateTime filenameStartTime = comb.Subs1.StartTime;
                    DateTime filenameEndTime   = comb.Subs1.EndTime;

                    // Apply pad (if requested)
                    if (Settings.Instance.VideoClips.PadEnabled)
                    {
                        startTime         = UtilsSubs.applyTimePad(startTime, -Settings.Instance.VideoClips.PadStart);
                        endTime           = UtilsSubs.applyTimePad(endTime, Settings.Instance.VideoClips.PadEnd);
                        filenameStartTime = UtilsSubs.applyTimePad(comb.Subs1.StartTime, -Settings.Instance.VideoClips.PadStart);
                        filenameEndTime   = UtilsSubs.applyTimePad(comb.Subs1.EndTime, Settings.Instance.VideoClips.PadEnd);
                    }

                    // Create output filename
                    string nameStr = name.createName(ConstantSettings.VideoFilenameFormat, (int)episodeCount + Settings.Instance.EpisodeStartNumber - 1,
                                                     progessCount, filenameStartTime, filenameEndTime, comb.Subs1.Text, comb.Subs2.Text);

                    string outFile = string.Format("{0}{1}{2}{3}",
                                                   workerVars.MediaDir,         // {0}
                                                   Path.DirectorySeparatorChar, // {1}
                                                   nameStr,                     // {2}
                                                   videoExtension);             // {3}

                    // Cut video clip for current line
                    UtilsVideo.cutVideo(tempVideoFilename, startTime, endTime, outFile);
                }

                File.Delete(tempVideoFilename);
            }

            return(true);
        }
Exemple #4
0
        /// <summary>
        /// Generate Audio clips for all episodes.
        /// </summary>
        public bool genAudioClip(WorkerVars workerVars, DialogProgress dialogProgress)
        {
            int      progessCount    = 0;
            int      episodeCount    = 0;
            int      totalEpisodes   = workerVars.CombinedAll.Count;
            int      curEpisodeCount = 0;
            int      totalLines      = UtilsSubs.getTotalLineCount(workerVars.CombinedAll);
            DateTime lastTime        = UtilsSubs.getLastTime(workerVars.CombinedAll);

            UtilsName name = new UtilsName(Settings.Instance.DeckName, totalEpisodes,
                                           totalLines, lastTime, Settings.Instance.VideoClips.Size.Width,
                                           Settings.Instance.VideoClips.Size.Height);

            DialogProgress.updateProgressInvoke(dialogProgress, 0, "Creating audio clips.");

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

                // It is possible for all lines in an episode to be set to inactive
                if (combArray.Count == 0)
                {
                    // Skip this episode
                    continue;
                }

                // Is the audio input an mp3 file?
                bool inputFileIsMp3 = Settings.Instance.AudioClips.Files.Length > 0 &&
                                      Path.GetExtension(Settings.Instance.AudioClips.Files[episodeCount - 1])
                                      .ToLower() == ".mp3";

                DateTime entireClipStartTime = combArray[0].Subs1.StartTime;
                DateTime entireClipEndTime   = combArray[combArray.Count - 1].Subs1.EndTime;
                string   tempMp3Filename     = Path.GetTempPath() + ConstantSettings.TempAudioFilename;

                // Apply pad to entire clip timings  (if requested)
                if (Settings.Instance.AudioClips.PadEnabled)
                {
                    entireClipStartTime =
                        UtilsSubs.applyTimePad(entireClipStartTime, -Settings.Instance.AudioClips.PadStart);
                    entireClipEndTime = UtilsSubs.applyTimePad(entireClipEndTime, Settings.Instance.AudioClips.PadEnd);
                }

                // Do we need to extract the audio from the video file?
                if (Settings.Instance.AudioClips.UseAudioFromVideo)
                {
                    string progressText = $"Extracting audio from video file {episodeCount} of {totalEpisodes}"; // {1}

                    bool success = convertToMp3(
                        Settings.Instance.VideoClips.Files[episodeCount - 1],
                        Settings.Instance.VideoClips.AudioStream.Num,
                        progressText,
                        dialogProgress,
                        entireClipStartTime,
                        entireClipEndTime,
                        tempMp3Filename);

                    if (!success)
                    {
                        UtilsMsg.showErrMsg("Failed to extract the audio from the video.\n" +
                                            "Make sure that the video does not have any DRM restrictions.");
                        return(false);
                    }
                }
                // If the reencode option is set or the input audio is not an mp3, reencode to mp3
                else if (ConstantSettings.ReencodeBeforeSplittingAudio || !inputFileIsMp3)
                {
                    string progressText = $"Reencoding audio file {episodeCount} of {totalEpisodes}";

                    bool success = convertToMp3(
                        Settings.Instance.AudioClips.Files[episodeCount - 1],
                        "0",
                        progressText,
                        dialogProgress,
                        entireClipStartTime,
                        entireClipEndTime,
                        tempMp3Filename);

                    if (!success)
                    {
                        UtilsMsg.showErrMsg("Failed to reencode the audio file.\n" +
                                            "Make sure that the audio file does not have any DRM restrictions.");
                        return(false);
                    }
                }

                curEpisodeCount = 0; // Reset

                // For each line in episode, generate an audio clip
                foreach (InfoCombined comb in combArray)
                {
                    progessCount++;
                    curEpisodeCount++;

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

                    string progressText =
                        $"Generating audio clip: {progessCount.ToString()} of {totalLines.ToString()}";

                    // Update the progress dialog
                    DialogProgress.updateProgressInvoke(dialogProgress, progress, progressText);

                    // Did the user press the cancel button?
                    if (dialogProgress.Cancel)
                    {
                        File.Delete(tempMp3Filename);
                        return(false);
                    }

                    DateTime startTime         = comb.Subs1.StartTime;
                    DateTime endTime           = comb.Subs1.EndTime;
                    DateTime filenameStartTime = comb.Subs1.StartTime;
                    DateTime filenameEndTime   = comb.Subs1.EndTime;
                    string   fileToCut         = "";

                    if (Settings.Instance.AudioClips.UseAudioFromVideo ||
                        ConstantSettings.ReencodeBeforeSplittingAudio || !inputFileIsMp3)
                    {
                        startTime = UtilsSubs.shiftTiming(startTime,
                                                          -(int)entireClipStartTime.TimeOfDay.TotalMilliseconds);
                        endTime = UtilsSubs.shiftTiming(endTime,
                                                        -(int)entireClipStartTime.TimeOfDay.TotalMilliseconds);
                        fileToCut = tempMp3Filename;
                    }
                    else
                    {
                        fileToCut = Settings.Instance.AudioClips.Files[episodeCount - 1];
                    }

                    // Apply pad (if requested)
                    if (Settings.Instance.AudioClips.PadEnabled)
                    {
                        startTime         = UtilsSubs.applyTimePad(startTime, -Settings.Instance.AudioClips.PadStart);
                        endTime           = UtilsSubs.applyTimePad(endTime, Settings.Instance.AudioClips.PadEnd);
                        filenameStartTime = UtilsSubs.applyTimePad(comb.Subs1.StartTime,
                                                                   -Settings.Instance.AudioClips.PadStart);
                        filenameEndTime =
                            UtilsSubs.applyTimePad(comb.Subs1.EndTime, Settings.Instance.AudioClips.PadEnd);
                    }

                    string lyricSubs2 = "";

                    // Set the Subs2 lyric if it exists
                    if (Settings.Instance.Subs[1].Files.Length != 0)
                    {
                        lyricSubs2 = comb.Subs2.Text.Trim();
                    }

                    // Create output filename
                    string nameStr = name.createName(ConstantSettings.AudioFilenameFormat,
                                                     (int)episodeCount + Settings.Instance.EpisodeStartNumber - 1,
                                                     progessCount, filenameStartTime, filenameEndTime, comb.Subs1.Text, lyricSubs2);

                    string outName = $"{workerVars.MediaDir}{Path.DirectorySeparatorChar}{nameStr}"; // {2}

                    // Create audio clip
                    UtilsAudio.cutAudio(fileToCut, startTime, endTime, outName);

                    // Tag the audio clip
                    tagAudio(name, outName, episodeCount, curEpisodeCount, progessCount, combArray.Count,
                             filenameStartTime, filenameEndTime, comb.Subs1.Text, lyricSubs2);
                }

                File.Delete(tempMp3Filename);
            }

            // Normalize all mp3 files in the media directory
            if (Settings.Instance.AudioClips.Normalize)
            {
                DialogProgress.updateProgressInvoke(dialogProgress, -1, "Normalizing audio...");

                UtilsAudio.normalizeAudio(workerVars.MediaDir);
            }

            return(true);
        }