using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading; using System.Data; using System.Drawing; using System.Windows.Forms; using System.Xml; using System.IO; using MediaInfoLib; using System.Net; using System.Diagnostics; using MySql.Data.MySqlClient; using System.Runtime.InteropServices; namespace MKV_Chapterizer { public class Chapterizer { //Variables private static int pProgress; private static List pFiles; private static int pChaptersExistAction; private static bool pOverwrite; private static int pChapterInterval; private static bool pFinished = true; private static string pStatus; private static BackgroundWorker worker = new BackgroundWorker(); //------------------------------------------------------ // External used Properties //------------------------------------------------------ // delegate declaration public delegate void ChangingHandler(object sender, ProgressChangedEventArgs pa); public delegate void ChangingHandler2(object sender, RunWorkerCompletedEventArgs ps); // event declaration public event ChangingHandler ProgressChanged; public event ChangingHandler StatusChanged; public event ChangingHandler2 Done; public string Status { get { return pStatus; } set { pStatus = value; ProgressChangedEventArgs ps = new ProgressChangedEventArgs(0, pStatus); StatusChanged(this, ps); } } public int Progress { get { return pProgress; } set { pProgress = value; ProgressChangedEventArgs ps = new ProgressChangedEventArgs(pProgress, null); ProgressChanged(this, ps); } } public int ChapterInterval { get { return pChapterInterval; } set { pChapterInterval = value; } } public List Files { get { return pFiles; } set { pFiles = value; } } public bool Overwrite { get { return pOverwrite; } set { pOverwrite = value; } } public bool Finished { get { return pFinished; } set { pFinished = value; if (value) { RunWorkerCompletedEventArgs ps = new RunWorkerCompletedEventArgs(null, null, false); Done(this, ps); } } } /// /// What to do if the file has chapters. /// 1 = Replace; 2 = Remove; 3 = Skip File /// public int ChaptersExistAction { get { return pChaptersExistAction; } set { pChaptersExistAction = value; } } //------------------------------------------------------ // Accessable Functions //------------------------------------------------------ public void Start() { worker.DoWork += new DoWorkEventHandler(worker_DoWork); worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); worker.WorkerSupportsCancellation = true; Finished = false; worker.RunWorkerAsync(); } private void worker_DoWork(object sender, DoWorkEventArgs e) { List mkvlist = Files; int doneMovies = 0; Status = doneMovies.ToString() + "/" + Files.Count.ToString(); //for each mkv the user has added foreach (string s in mkvlist) { FileInfo fi = new FileInfo(s); //check if it already has chapters if (ChaptersExist(s)) { //the file already has chapters, check what the user want's to do switch (ChaptersExistAction) { case 1: //Replace Them InsertChapters(RemoveChapters(s)); break; case 2: //Remove Them string file = RemoveChapters(s); if (file == "0") { //The task was cancelled e.Cancel = true; worker.Dispose(); } else { //check if the user want to overwrite if (Overwrite) { String newFileName = Properties.Settings.Default.customOutputName.Replace("%O", Path.GetFileNameWithoutExtension(fi.FullName)) + ".mkv"; File.Delete(fi.FullName); File.Move(fi.DirectoryName + "\\" + newFileName, fi.FullName); } } break; case 3: //Skip the file break; } } else { string file = InsertChapters(s); if (file == "0") { e.Cancel = true; worker.Dispose(); } else { if (Overwrite) { //Delete the input file File.Delete(s); //Rename -new file to original name File.Move(file, s); } } } doneMovies += 1; Status = doneMovies.ToString() + "/" + Files.Count.ToString(); } Files = null; } private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Finished = true; //Display a messagebox with success message or error info if (e.Cancelled == false & e.Error == null) { MessageBox.Show("DONE"); } else if (e.Cancelled == true & e.Error == null) { //Clean-up files //String newFile = theFile.DirectoryName + "\\" + Properties.Settings.Default.customOutputName.Replace("%O", Path.GetFileNameWithoutExtension(theFile.FullName)) + ".mkv"; try { //File.Delete(newFile); } catch (IOException ex) { MessageBox.Show("Failed to delete leftovers!:" + Environment.NewLine + ex.Message); } } else if (e.Cancelled == false & e.Error != null) { MessageBox.Show("Error Occured:" + Environment.NewLine + e.Error.Message); } } public void Cancel() { worker.CancelAsync(); } //------------------------------------------------------ // Internal used methods //------------------------------------------------------ private void CreateChapterFile(int runTime) { decimal count = runTime / ChapterInterval; if (count < 0) { MessageBox.Show("Too high interval!"); } else { count = Math.Floor(count); if (Properties.Settings.Default.firstChap00) { count += 1; } } string path = "chapters.xml"; int nmbr = Convert.ToInt32(count); int start; int extraval = 0; int[] time = { 00, 00 }; int interval = ChapterInterval; // trackBar1.Value; XmlTextWriter xwrite = new XmlTextWriter(path, System.Text.Encoding.UTF8); xwrite.WriteStartDocument(); xwrite.Formatting = Formatting.Indented; xwrite.Indentation = 2; xwrite.WriteDocType("Tags", null, "matroskatags.dtd", null); xwrite.WriteStartElement("Chapters"); xwrite.WriteStartElement("EditionEntry"); if (Properties.Settings.Default.firstChap00) { xwrite.WriteStartElement("ChapterAtom"); xwrite.WriteElementString("ChapterTimeStart", string.Format("{0:00}:{1:00}", time[0], time[1]) + ":00.000000000"); xwrite.WriteStartElement("ChapterDisplay"); xwrite.WriteElementString("ChapterString", "Chapter " + Convert.ToString(1)); xwrite.WriteEndElement(); xwrite.WriteEndElement(); extraval = 1; } for (start = 0 + extraval; start < nmbr; start++) { time[1] += interval; if (time[1] >= 60) { time[0] += 1; time[1] -= 60; } xwrite.WriteStartElement("ChapterAtom"); xwrite.WriteElementString("ChapterTimeStart", string.Format("{0:00}:{1:00}", time[0], time[1]) + ":00.000000000"); xwrite.WriteStartElement("ChapterDisplay"); xwrite.WriteElementString("ChapterString", "Chapter " + Convert.ToString(start + 1)); xwrite.WriteEndElement(); xwrite.WriteEndElement(); } if (Properties.Settings.Default.extraChapEnd) { int hours = 0; int minutes = runTime; while (minutes >= 60) { minutes -= 60; hours += 1; } xwrite.WriteStartElement("ChapterAtom"); xwrite.WriteElementString("ChapterTimeStart", string.Format("{0:00}:{1:00}", hours.ToString(), minutes.ToString()) + ":00.000000000"); xwrite.WriteStartElement("ChapterDisplay"); xwrite.WriteElementString("ChapterString", "Chapter " + Convert.ToString(start + 1)); xwrite.WriteEndElement(); xwrite.WriteEndElement(); } xwrite.WriteEndElement(); xwrite.WriteEndElement(); xwrite.Close(); } private string parseProgress(String Text) { String newText = Text.Replace("Progress: ", "").Replace("%", ""); return newText; } private bool ChaptersExist(String file) { MediaInfo info = new MediaInfo(); info.Open(file); int lol = info.Count_Get(StreamKind.Chapters); info.Option("Inform", "XML"); info.Option("Complete"); if (info.Inform().Contains("