/// <summary> /// Overload for LoadFileInfo that takes just one filename instead of many /// </summary> /// <param name="fileName">The file path to load data from</param> private void LoadFileInfo(string fileName) { string exeName = "\"" + MKVToolNix.ExeGetPath(MKVToolNix.mkvmergeExe) + "\""; // Get path for mkvmerge.exe and wrap in quotes for RunProcess // Get dynamic object from JSON string from mkvmerge.exe dynamic json = Utils.GetJsonObject(Utils.RunProcess(exeName, "-i -F json \"" + fileName + "\"")); audioMeta = InitMetaArray(json, MKVToolNix.TRACK_AUDIO, 3); // Initialize Meta Arrays subMeta = InitMetaArray(json, MKVToolNix.TRACK_SUB, 2); InitTrackArrays(json, MKVToolNix.TRACK_AUDIO, out audioLabels, out audioTextBoxes, out audioLangBoxes); // Initialize label and TextBox Arrays InitTrackArrays(json, MKVToolNix.TRACK_SUB, out subLabels, out subTextBoxes, out subLangBoxes); InitPanel(pnlAudio, audioLabels.Length, audioLabels, audioTextBoxes, audioLangBoxes); // Initialize Panels InitPanel(pnlSubtitle, subLabels.Length, subLabels, subTextBoxes, subLangBoxes); GetTracks(json, MKVToolNix.TRACK_AUDIO); // Get info for audio and subtitle tracks from dynamic object GetTracks(json, MKVToolNix.TRACK_SUB); try { lblTitle.Text = json["container"]["properties"]["title"]; // Try to display video Title from JSON Object } catch (KeyNotFoundException) { myDebug.WriteLine("This mkv has no Title set, using blank one... "); lblTitle.Text = ""; // Display blank title if not present } txtFile.Text = fileName; // Put file name in file name textbox }
/// <summary> /// Method to load the data from files to fform /// </summary> private void LoadFileInfo() { string exeName = "\"" + MKVToolNix.ExeGetPath(MKVToolNix.mkvmergeExe) + "\""; // Get path for mkvmeerge and wrap in quotes for RunProcess arg int fileCount = mkvFiles.Length; // Get count of files loaded lblTitleFileNames = new Label[fileCount]; // Make new TitleFileNames Array txtTitles = new TextBox[fileCount]; // make new TitlesTextBox array chkTitleEdit = new CheckBox[fileCount]; // make new "Edit" CheckBox array for titles InitPanel(pnlTitles, fileCount, lblTitleFileNames, txtTitles, chkTitleEdit); // Init Titles Panel with these arrays lblFileFileNames = new Label[fileCount]; // Make new FileFileNames Array txtFileNames = new TextBox[fileCount]; // make new FileNamesTextBox array chkFileEdit = new CheckBox[fileCount]; // make new "Edit" CheckBox array for filenames InitPanel(pnlFileNames, fileCount, lblFileFileNames, txtFileNames, chkFileEdit); // Init filenames Panel with these arrays lblDir.Text = Path.GetDirectoryName(mkvFiles[0]); // Get directory of loaded files for dir Label for (int i = 0; i < fileCount; i++) // For each file... { // Set the dynamic json object to... // ...the output derived from the JSON string... // ...which is taken from the output from mkvmerge.exe dynamic json = Utils.GetJsonObject(Utils.RunProcess(exeName, "-i -F json \"" + mkvFiles[i] + "\"")); lblTitleFileNames[i].Text = Path.GetFileName(mkvFiles[i]); // Get Filename of file and add its element in Label arrays, and to main filenames "Label" (it is really a textbox) lblFileFileNames[i].Text = Path.GetFileName(mkvFiles[i]); txtFileNames[i].Text = Path.GetFileName(mkvFiles[i]); try { //txtTitles[i].Text = json["container"]["properties"]["title"]; // Try to display video Title from JSON Object byte[] eretgfeghbrf = Encoding.Default.GetBytes(json["container"]["properties"]["title"]); // Load title from json this way txtTitles[i].Text = Encoding.UTF8.GetString(eretgfeghbrf); // to handle encoding of displayed text in GUI } catch (KeyNotFoundException) { myDebug.WriteLine("This mkv has no Title set, using blank one... "); txtTitles[i].Text = ""; // Display blank title if not present } } UnlockEditControls(true); // Enable Copy Titles Over button, and the Activated and select all checkboxes txtShowTitle.Focus(); // Put cursor focus on the show title textbox for user to type in the show's title }
/// <summary> /// Method to load info from file to form /// </summary> private void LoadFileInfo(string fileName) { string exeName = "\"" + MKVToolNix.ExeGetPath(MKVToolNix.mkvmergeExe) + "\""; // Get path for mkvmerge.exe and wrap in quotes for RunProcess dynamic mkvData = Utils.GetJsonObject(Utils.RunProcess(exeName, "-i -F json \"" + fileName + "\"")); // Get JSON string from mkvmerge file analysis output and turn it into dynamic object RefreshListBox(lbxAudio, GetTracks(mkvData, MKVToolNix.TRACK_AUDIO)); // Call GetTracks with the created dynamic object to get audio tracks RefreshListBox(lbxSubtitle, GetTracks(mkvData, MKVToolNix.TRACK_SUB)); // Call GetTracks with the created dynamic object to get sub tracks try { lblTitle.Text = mkvData["container"]["properties"]["title"]; // Try to display video Title from JSON Object } catch (KeyNotFoundException) { myDebug.WriteLine("This mkv has no Title set, using blank one... "); lblTitle.Text = ""; // Display blank title if not present } txtFile.Text = fileName; // Put file name in file name textbox }
/// <summary> /// Method to save the currently selected default track configuration to file(s) /// </summary> private void SaveNewSettings() { if (txtFile.Text != "") // If the filename label actually has text in it... (meaning something is actually loaded) { rtxLog.Text = ""; // Clear the log string retStr; // Initialize retStr (used to hold string returned by Utils.RunProcess) //string fileName = "\"" + lblFile.Text + "\""; // Initialize file name, wrapping it in quotes for use in final arg for mkvpropedit string[] mkvFiles = txtFile.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); // Build array of filenames from file name TextBox string exeName = "\"" + MKVToolNix.ExeGetPath(MKVToolNix.mkvpropeditExe) + "\""; // Initialize name for exe for Utils.RunProcess, grabbing path for currently installed mkvpropedit.exe and wrapping in quotes StringBuilder args = new StringBuilder(); // Instantiate new StringBuilder to construct final arguments string args.Append(BuildArgs(lbxAudio, false)); // Call BuildArgs for all audio track args and append to StringBuilder args.Append(BuildArgs(lbxSubtitle, false)); // Call BuildArgs for all subtitle track args and append to StringBuilder if (mkvFiles.Length > 1) // If the "User Is Insane" batch mode option is on... { int filesModified = 0; // Initialize counter to count how maky files were successfully modified for (int i = 0; i < mkvFiles.Length; i++) // For each file... { string fileName = "\"" + mkvFiles[i] + "\""; // Wrap file name in quotes for final arg rtxLog.SendToLog("File No." + (i + 1) + " of " + mkvFiles.Length + ": " + mkvFiles[i]); // Send to log file no. and name rtxLog.SendToLog(exeName + " " + fileName + args.ToString()); // Send to log the complete command sent to mkvpropedit retStr = Utils.RunProcess(exeName, fileName + args.ToString()); // Run mkvpropedit with final generated args rtxLog.SendToLog(retStr); // send returned result from mkvpropedit to log int goodAudioCount = lbxAudio.Items.Count; // Initialize count of "good" audio, count of audio tracks found in file (needed for batch mode, may not have all tracks in selected file) int goodSubCount = lbxSubtitle.Items.Count; // Initialize count of "good" subtitle, count of subtitle tracks found in file StringBuilder argsAlt; // Declare another StringBuilder for an alternate final arg (used for batch mode, in case some tracks are not found) filesModified++; // Increment filesModified while (retStr != MKVToolNix.mkvpropedit_ReturnOK) // While mkvpropedit does not return the "everything completed OK" result { if (retStr.Contains("The file is being analyzed.\r\nError: This file could not be opened or parsed.\r\n")) { rtxLog.SendToLog("ERROR: could not seem to access this file, skipping it..."); filesModified--; break; } if (retStr.Contains("Error: No track corresponding to the edit specification 'a")) // If returned error was an audio track not found... { goodAudioCount--; // Means the last audio track was not found, so decrement good audio count } else if (retStr.Contains("Error: No track corresponding to the edit specification 's")) // If returned error was a subtitle track not found... { goodSubCount--; // Means the last subtitle track was not found, so decrement good subtitle count } if (goodAudioCount < (lbxAudio.SelectedIndex + 1) || goodSubCount < (lbxSubtitle.SelectedIndex + 1)) // If the selected default tracks are not in the "good" tracks avaible in file... { rtxLog.SendToLog("Default track selection does not exist in this file, skipping file..."); // inform user that their selected tracks are not present filesModified--; // decrement filesModified break; // break out of while loop, skipping file } argsAlt = new StringBuilder(); // Instantiate new StringBuilder for alternate args argsAlt.Append(BuildArgs(lbxAudio, false, goodAudioCount)); // Build new audio tracks args based on updated good audio count argsAlt.Append(BuildArgs(lbxSubtitle, false, goodSubCount)); // Build new subtitle track args based on updated good subtitle count rtxLog.SendToLog(exeName + " " + fileName + argsAlt.ToString()); // Send new complete command to log retStr = Utils.RunProcess(exeName, fileName + argsAlt.ToString()); // Try running mkvpropedit with new args rtxLog.SendToLog(retStr); // send result from mkvpropedit to log } } // Finally show message to user when batch operation is done including count of files successfully modified MessageBox.Show(filesModified + " of " + mkvFiles.Length + " files successfully modified!", "Batch save complete!", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { // Else if the batch mode is off, just do the following string fileName = mkvFiles[0]; // If there is only one file, just get filename from array string wrappedFileName = "\"" + fileName + "\""; // Wrap filename in quotes for RunProcess arg rtxLog.SendToLog("File: " + wrappedFileName); // Send file name to log rtxLog.SendToLog(exeName + " " + wrappedFileName + args.ToString()); // Send complete mkvpropedit arg to log retStr = Utils.RunProcess(exeName, wrappedFileName + args.ToString()); // Run mkvpropedit with arg rtxLog.SendToLog(retStr); // send returned result to log } } }
/// <summary> /// Method to load data from selected files /// </summary> /// <param name="mkvFiles">Array of selected files' paths</param> private void LoadFileInfo(string[] mkvFiles) { string exeName = "\"" + MKVToolNix.ExeGetPath(MKVToolNix.mkvmergeExe) + "\""; // Get path for mkvmerge.exe and wrap in quotes for RunProcess dynamic json = null; int maxAudioIndex = 0; // Initialize index of file holding the most audio tracks int maxAudioValue = 0; // Initialize value of how many audio tracks are in the above described file int maxSubIndex = 0; // Initialize index of file holding the most subtitle tracks int maxSubValue = 0; // Initialize value of how many subtitle tracks are in the above described file txtFile.Clear(); // Clear the file name TextBox for (int i = 0; i < mkvFiles.Length; i++) // For each file in the directory... { // Set the dynamic json object to... // ...the output derived from the JSON string... // ...which is taken from the output from mkvmerge.exe json = Utils.GetJsonObject(Utils.RunProcess(exeName, "-i -F json \"" + mkvFiles[i] + "\"")); int audioCount = 0; // Initialize audio track counter int subCount = 0; // Initialize subtitle track counter for (int j = 0; j < json["tracks"].Length; j++) // For each track in the file... { switch ((string)json["tracks"][j]["type"]) // Check the track type { case MKVToolNix.TRACK_AUDIO: // If it is an audio track audioCount++; // Increment audio track counter break; // Break out of switch statement case MKVToolNix.TRACK_SUB: // If it is a subtitle track subCount++; // Increment subtitle track counter break; // Break out of switch statement } } if (maxAudioValue < audioCount) // If the amount of audio tracks in this file is greater than current maximum found... { maxAudioValue = audioCount; // set new maximum to amount found in this file maxAudioIndex = i; // Set the index holding max audio tracks to current file's index } if (maxSubValue < subCount) // If the amount of subtitle tracks in this file is greater than current maximum found... { maxSubValue = subCount; // set new maximum to amount found in this file maxSubIndex = i; // Set the index holding max subtitle tracks to current file's index } myDebug.WriteLine(Path.GetFileName(mkvFiles[i]) + ":\thas " + audioCount + " audio, and " + subCount + " subs."); txtFile.AppendText(mkvFiles[i]); // Add current file's path to file name TextBox if (i < (mkvFiles.Length - 1)) // If the file is not the last one... { txtFile.AppendText(Environment.NewLine); // Also add a new line for nextfile name } } // Get dynamic object from JSON string from mkvmerge.exe for file in folder with max amount of audio tracks json = Utils.GetJsonObject(Utils.RunProcess(exeName, "-i -F json \"" + mkvFiles[maxAudioIndex] + "\"")); RefreshListBox(lbxAudio, GetTracks(json, MKVToolNix.TRACK_AUDIO)); // Call GetTracks with the created dynamic object to get audio tracks if (maxAudioIndex != maxSubIndex) // If the "max audio tracks" file and the "max subtitle tracks" file are not the same... // Get dynamic object from JSON string from mkvmerge.exe for file in folder with max amount of subtitle tracks { json = Utils.GetJsonObject(Utils.RunProcess(exeName, "-i -F json \"" + mkvFiles[maxSubIndex] + "\"")); } RefreshListBox(lbxSubtitle, GetTracks(json, MKVToolNix.TRACK_SUB)); // Call GetTracks with the created dynamic object to get sub tracks lblTitle.Text = "(Multiple files are loaded)"; // Change title label to inform that there are multiple files loadad }
/// <summary> /// Method to save the track names from form to the MKV file(s) /// </summary> private void SaveTrackNames() { if (txtFile.Text != "") // If the file name TextBox actually has something in it... { rtxLog.Text = ""; // Clear the log int filesModified = 0; // Initialize a counter to count the amount of files successfully modified string retStr; // Declare string for RunProcess output string[] mkvFiles = txtFile.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); // Build array of filenames from file name TextBox string exeName = "\"" + MKVToolNix.ExeGetPath(MKVToolNix.mkvpropeditExe) + "\""; // Get path for mkvpropedit.exe and wrap in quotes for use as RunProcess arg StringBuilder args = new StringBuilder(); // Make new StringBuilder for arguments args.Append(BuildArgs(audioTextBoxes, audioLangBoxes, false)); // Add arguments for audio tracks args.Append(BuildArgs(subTextBoxes, subLangBoxes, false)); // Add arguments for subtitle tracks if (mkvFiles.Length > 1) // If there is more than one file to modify... { for (int i = 0; i < mkvFiles.Length; i++) // For each file... { myDebug.WriteLine(mkvFiles[i]); string fileName = "\"" + mkvFiles[i] + "\""; // Wrap file name in quotes for use in args rtxLog.SendToLog("File No." + (i + 1) + " of " + mkvFiles.Length + ": " + mkvFiles[i]); // Send to log file no. and name rtxLog.SendToLog(exeName + " " + fileName + args.ToString()); // Send to log the complete command sent to mkvpropedit retStr = Utils.RunProcess(exeName, fileName + args.ToString()); // Run mkvpropedit with final generated args rtxLog.SendToLog(retStr); // send returned result from mkvpropedit to log int goodAudioCount = audioTextBoxes.Length; // Initialize count of "good" audio, count of audio tracks found in file (needed for batch mode, may not have all tracks in selected file) int goodSubCount = subTextBoxes.Length; // Initialize count of "good" subtitle, count of subtitle tracks found in file StringBuilder argsAlt; // Declare another StringBuilder for an alternate final arg (used for batch mode, in case some tracks are not found) filesModified++; // Increment filesModified while (retStr != MKVToolNix.mkvpropedit_ReturnOK) // While mkvpropedit does not return the "everything completed OK" result { if (retStr.Contains("The file is being analyzed.\r\nError: This file could not be opened or parsed.\r\n")) //If file couldnot be accessed... { rtxLog.SendToLog("ERROR: could not seem to access this file, skipping it..."); // Inform user if the issue filesModified--; // decrement filesModified break; // Break out of while loop, skipping file. } if (retStr.Contains("Error: No track corresponding to the edit specification 'a")) // If returned error was an audio track not found... { goodAudioCount--; // Means the last audio track was not found, so decrement good audio count } else if (retStr.Contains("Error: No track corresponding to the edit specification 's")) // If returned error was a subtitle track not found... { goodSubCount--; // Means the last subtitle track was not found, so decrement good subtitle count } argsAlt = new StringBuilder(); // Instantiate new StringBuilder for alternate args argsAlt.Append(BuildArgs(audioTextBoxes, audioLangBoxes, false, goodAudioCount)); // Build new audio tracks args based on updated good audio count argsAlt.Append(BuildArgs(subTextBoxes, subLangBoxes, false, goodSubCount)); // Build new subtitle track args based on updated good subtitle count rtxLog.SendToLog(exeName + " " + fileName + argsAlt.ToString()); // Send new complete command to log retStr = Utils.RunProcess(exeName, fileName + argsAlt.ToString()); // Try running mkvpropedit with new args rtxLog.SendToLog(retStr); // send result from mkvpropedit to log } } // Finally show message to user when batch operation is done including count of files successfully modified MessageBox.Show(filesModified + " of " + mkvFiles.Length + " files successfully modified!" + Environment.NewLine + Environment.NewLine + "Check the log for more details.", "Batch save complete!", MessageBoxButtons.OK, MessageBoxIcon.Information); LoadFileInfo(mkvFiles); // Reload the files after modification } else { string fileName = mkvFiles[0]; // If there is only one file, just get filename from array string wrappedFileName = "\"" + fileName + "\""; // Wrap filename in quotes for RunProcess arg rtxLog.SendToLog("File: " + wrappedFileName); // Send to log file name rtxLog.SendToLog(exeName + " " + wrappedFileName + args.ToString()); // Send to log the complete command sent to mkvpropedit retStr = Utils.RunProcess(exeName, wrappedFileName + args.ToString()); // Run mkvpropedit with final generated args rtxLog.SendToLog(retStr); // send returned result from mkvpropedit to log LoadFileInfo(fileName); // Reload file after modification } } }
/// <summary> /// Method to save modified internal titles inside each file /// </summary> private void SaveTitleNames() { int filesModified = 0; // Initialize count of successfully modified files int fileCount = lblTitleFileNames.Length; // Get count of all files string retStr = null; // init string retStr for RunProcess output string exeName = "\"" + MKVToolNix.ExeGetPath(MKVToolNix.mkvpropeditExe) + "\""; // Get path for mkvpropedit.exe and wrap in quotes for RunProcess arg string sType = "s"; // init setting type string, default is "s" for (int i = 0; i < fileCount; i++) // For each file... { string filePath = "\"" + mkvFiles[i] + "\""; // get file path and wrap in quotes for RunProcess arg rtxLog.SendToLog("TITLE SAVE: File No." + (i + 1) + " of " + fileCount + ": " + filePath); if (chkTitleEdit[i].Checked == true) // If "Edit" checkbox is checked... { int epNum = i + 1; // get episode no. StringBuilder title = new StringBuilder(); // Initialize new StringBUilder for title if (chkTitlePrepShow.Checked) // If "Prepend Show Title" is checked... { title.Append(txtShowTitle.Text + " "); // Add show title to title } if (chkTitlePrepSeasonPre.Checked) // If "Prepend Season Prefix" is checked... { title.Append(txtTitleSeasonPre.Text); // Add season prefix to title } if (chkTitlePrepEpPrefix.Checked) // If "Prepend Episode Prefix" is checked... { if ((string)cboTitleEpisodePre.SelectedItem == "Custom") // If selected prefix is "Custom"... { title.Append(txtTitleEpisodePre.Text); // Add custom prefix to title } else { title.Append(cboTitleEpisodePre.SelectedItem); // Otherwise add selected prefix to title } } if (chkTitlePrepEpOffset.Checked) // "Offset Episode no." is checked... { epNum += (int)nudTitleEpOffset.Value; // Offset episode no. by amount in respective numeric up-down } if (chkTitlePrepEpiZeros.Checked) // If "Prepend leading zeros" is checked... { int baseNum = 10; // Base is 10 int power = (int)nudTitleMinDigits.Value - 1; // power is minumim anount of digits minus one for (int p = power; p > 0; p--) // For each power... { if (epNum < baseNum.PowerOf(power)) // If episode no. is less than 10 to the power of power... { title.Append("0"); // add a "0" to title } } } if (chkTitlePrepEpNo.Checked) // If "Prepend Episode No." is checked... { title.Append(epNum.ToString() + " "); // Add the episode no. to title } title.Append(txtTitles[i].Text); // Add the title textbox contents to title string arg = " -e info -" + sType + " \"title=" + title.ToString().SanitizeMetaName() + "\""; // make track edit args for mkvpropedit retStr = Utils.RunProcess(exeName, filePath + arg); // Run mkvpropedit with specified args rtxLog.SendToLog(exeName + " " + filePath + arg); // Send full command to log rtxLog.SendToLog(retStr); // Send output from mkvpropedit to log while (retStr != MKVToolNix.mkvpropedit_ReturnOK) // While mkvpropedit returns something that is not "OK"... { // If returned message is file could not be accessed... if (retStr.Contains("The file is being analyzed.\r\nError: This file could not be opened or parsed.\r\n")) { // Send error to log, and skip file rtxLog.SendToLog("ERROR: could not seem to access this file, Skipping..." + Environment.NewLine); //filesModified--; continue; } } filesModified++; // increment filesModified } else { // If the "Edit" checkbox is not checked, send notice to log and move to next file rtxLog.SendToLog("This file is not marked for editing. Skipping..." + Environment.NewLine); } } // Once done, if there was more than one file involved, display batch message with amount of successfully modified files if (fileCount > 1) { MessageBox.Show(filesModified + " of " + mkvFiles.Length + " files successfully modified!" + Environment.NewLine + Environment.NewLine + "Check the log for more details.", "Batch title save complete!", MessageBoxButtons.OK, MessageBoxIcon.Information); } }