using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; using System.Windows.Forms; using System.Xml; using System.Xml.Linq; namespace MKVTest { /* Call mkvpropedit.exe * Edit "Title" detail property: --edit info --set "title=%TITLE%" %FILE% * Edit video track one: --edit track:v1 --set "name(or language)="%VAR%" %FILE% * Edit audio track one: --edit track:a1 --set "name(or language)="%VAR%" %FILE% * To add simply replace "--set" with "--add". */ public partial class Form1 : Form { public static string Language = "eng"; private static readonly ContextMenuStrip menu = new ContextMenuStrip(); public Form1() { InitializeComponent(); inputFilesListView.ItemSelectionChanged += UpdateFilePropPrediction; inputFilesListView.MouseClick += ShowMenu; Resize += Form1_Resize; var item = new ToolStripMenuItem { Name = "RemoveItem", Text = @"Remove" }; menu.Items.Add(item); var inputColumn = new ColumnHeader { Text = @"Files", Name = @"HeaderColumn", Width = inputFilesListView.Width - 10 }; inputFilesListView.Columns.Add(inputColumn); } private void ShowMenu(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { if (inputFilesListView.FocusedItem.Bounds.Contains(e.Location)) { menu.Show(Cursor.Position); } } } private void UpdateFilePropPrediction(object sender, ListViewItemSelectionChangedEventArgs e) { var info = new MkvFileInfo(); var file = info.GetAttributes(e.Item.Name); flowLayoutPanel1.Controls.Clear(); flowLayoutPanel1.Invalidate(); var titleLabel = new Label { Parent = flowLayoutPanel1, Text = @"Current Title: " + file.SegementInformation?.Title, AutoSize = true }; flowLayoutPanel1.Container?.Add(titleLabel); var videoTrackNumber = 1; var audioTrackNumber = 1; var subtitleTrackNumber = 1; foreach (var fileTrack in file.Tracks) { if (fileTrack.Type == MkvTrack.TrackType.Video) { var nameLabel = new Label { AutoSize = true, Text = @"Track:v" + videoTrackNumber + @" Name: " + fileTrack.Name, Parent = flowLayoutPanel1 }; var languageLabel = new Label { AutoSize = true, Text = @"Track:v" + videoTrackNumber + @" Language: " + fileTrack.Language, Parent = flowLayoutPanel1 }; videoTrackNumber++; if (flowLayoutPanel1.Container != null) { flowLayoutPanel1.Container.Add(nameLabel); flowLayoutPanel1.Container.Add(languageLabel); } } if (fileTrack.Type == MkvTrack.TrackType.Audio) { var nameLabel = new Label { AutoSize = true, Text = @"Track:a" + audioTrackNumber + @" Name: " + fileTrack.Name, Parent = flowLayoutPanel1 }; var languageLabel = new Label { AutoSize = true, Text = @"Track:a" + audioTrackNumber + @" Language: " + fileTrack.Language, Parent = flowLayoutPanel1 }; audioTrackNumber++; if (flowLayoutPanel1.Container != null) { flowLayoutPanel1.Container.Add(nameLabel); flowLayoutPanel1.Container.Add(languageLabel); } } if (fileTrack.Type == MkvTrack.TrackType.Subtitle) { var nameLabel = new Label { AutoSize = true, Text = @"Track:s" + subtitleTrackNumber + @" Name: " + fileTrack.Name, Parent = flowLayoutPanel1 }; var languageLabel = new Label { AutoSize = true, Text = @"Track:s" + subtitleTrackNumber + @" Language: " + fileTrack.Language, Parent = flowLayoutPanel1 }; subtitleTrackNumber++; if (flowLayoutPanel1.Container != null) { flowLayoutPanel1.Container.Add(nameLabel); flowLayoutPanel1.Container.Add(languageLabel); } } } } /// /// /// /// /// private string GetEpisodeName(string text) { var s = new StringBuilder(); var hyphenCount = 0; var index = 0; var fileExtensionStartPoint = text.LastIndexOf(".", StringComparison.InvariantCulture); foreach (var c in text) { if (c == '-' && hyphenCount != 2) { hyphenCount++; index++; continue; } if (hyphenCount == 2) { if (c == '.' && index == fileExtensionStartPoint) { break; } s.Append(c); } index++; } return s.ToString().Trim(); } private void ListFiles(string folderPath) { var dir = new DirectoryInfo(folderPath); var files = dir.GetFiles("*.mkv", SearchOption.TopDirectoryOnly); foreach (var file in files) { var node = new ListViewItem { Tag = true, //Assume the file needs to be updated. Name = file.FullName, Text = file.Name }; inputFilesListView.Items.Add(node); } if (inputFilesListView.Items.Count > 0) { applyChangesButton.Enabled = true; } } private void button1_Click(object sender, EventArgs e) { var d = new FolderBrowserDialog(); if (d.ShowDialog() != DialogResult.OK) return; ClearForm(); ListFiles(d.SelectedPath); } private void Form1_Resize(object sender, EventArgs e) { inputFilesListView.Columns[0].Width = inputFilesListView.Width - 10; } private void applyChangesButton_Click(object sender, EventArgs e) { foreach (ListViewItem node in inputFilesListView.Items) { //Check to see if the item has been modified. if (node.Tag == null || (bool) node.Tag == false) continue; if (!File.Exists(node.Name)) continue; var command = "/C mkvpropedit.exe --edit info --set \"title=" + GetEpisodeName(node.Text) + "\" --edit track:v1 --set \"name=" + GetEpisodeName(node.Text) + "\" --edit track:v1 --set \"language=eng\" --edit track:a1 --set \"name=English\" --edit track:a1 --set \"language=eng\" \"" + node.Name + "\" > temp.txt"; var process = new Process(); var startInfo = new ProcessStartInfo { WindowStyle = ProcessWindowStyle.Normal, FileName = "cmd.exe", Arguments = command }; process.StartInfo = startInfo; process.Start(); while (!process.HasExited) { } if (process.ExitCode == 0) continue; var error = File.ReadAllLines("temp.txt"); MessageBox.Show(@"Error on node: " + node.Text + (error.Length > 0 ? Environment.NewLine + error[0] : string.Empty)); break; } File.Delete("temp.txt"); } private void ClearForm() { inputFilesListView.Items.Clear(); flowLayoutPanel1.Controls.Clear(); flowLayoutPanel1.Invalidate(); } private void openFolderFileMainMenu_Click(object sender, EventArgs e) { var d = new FolderBrowserDialog(); if (d.ShowDialog() != DialogResult.OK) return; ClearForm(); ListFiles(d.SelectedPath); } private void exitToolStripMenuItem_Click(object sender, EventArgs e) => Application.Exit(); public static bool CheckFiles() { return File.Exists("mkvpropedit.exe") && File.Exists("mkvinfo.exe"); } private void ReadXml(string s) { var xReader = new XmlTextReader(new StringReader(s)); var r = new StringBuilder(); ClearForm(); var tags = new List(); while (xReader.Read()) { switch (xReader.NodeType) { case XmlNodeType.Element: //inputFilesListView.Items.Add(xReader.Name + ": " + xReader.Value); var t = new XmlTag { Name = xReader.Name }; tags.Add(t); break; case XmlNodeType.Text: //inputFilesListView.Items.Add(xReader.Value); tags[tags.Count - 1].Value = xReader.Value; break; } } foreach (var tag in tags) { var label = new Label { Text = tag.Name }; var textBox = new TextBox { Text = tag.Value }; if (flowLayoutPanel1.Container != null) { flowLayoutPanel1.Container.Add(label); flowLayoutPanel1.Container.Add(textBox); } //inputFilesListView.Items.Add(tag.Name + ": " + tag.Value); } } private void debugToolStripMenuItem_Click(object sender, EventArgs e) { //var xml = new SerializeMkvInfo(); //var x = xml.SerializeFile("info.txt"); //var text = new StringBuilder(); //foreach (var line in x) //{ // text.Append(line.Trim()); //} //ReadXml(text.ToString()); var p = new FrmProperties(); p.ShowDialog(); } } }