private void buttonExtract_Click(object sender, EventArgs e) { labelProgress.Visible = true; progressBarMain.Visible = true; buttonExtract.Enabled = false; selectedTrack = (MkvTrack)comboBoxTrack.SelectedItem; backgroundWorkerMain.RunWorkerAsync(); }
/// <summary> /// Get list of audio and subtitle tracks in the provided .mkv file. /// </summary> public static List <MkvTrack> getTrackList(string mkvFile) { List <MkvTrack> trackList = new List <MkvTrack>(); if (Path.GetExtension(mkvFile) != ".mkv") { return(trackList); } string args = $"\"{mkvFile}\""; string mkvIinfo = UtilsCommon.startProcessAndGetStdout(ConstantSettings.PathMkvInfoExeRel, ConstantSettings.PathMkvInfoExeFull, args); if (mkvIinfo == "Error.") { return(trackList); } mkvIinfo = mkvIinfo.Replace("\r\r", ""); string[] lines = mkvIinfo.Split('\n'); TrackListParseState state = TrackListParseState.SEARCH_FOR_START_OF_TRACKS; MkvTrack curTrack = new MkvTrack(); foreach (string line in lines) { switch (state) { case TrackListParseState.SEARCH_FOR_START_OF_TRACKS: { if (line.StartsWith("|+ Segment tracks")) { state = TrackListParseState.GET_NEXT_TRACK; } break; } case TrackListParseState.GET_NEXT_TRACK: { // Reset track info curTrack = new MkvTrack(); if (line.StartsWith("| + A track")) { state = TrackListParseState.GET_TRACK_NUM; } break; } case TrackListParseState.GET_TRACK_NUM: { Match match = Regex.Match(line, @"^\| \+ Track number: \d+ \(track ID for mkvmerge & mkvextract: (?<TrackNum>\d+)\)"); if (match.Success) { curTrack.TrackID = match.Groups["TrackNum"].ToString().Trim(); state = TrackListParseState.GET_TRACK_TYPE; } break; } case TrackListParseState.GET_TRACK_TYPE: { Match match = Regex.Match(line, @"^\| \+ Track type: (?<TrackType>\w+)"); if (match.Success) { string trackType = match.Groups["TrackType"].ToString().Trim(); if (trackType == "subtitles") { curTrack.TrackType = TrackType.SUBTITLES; state = TrackListParseState.GET_CODEC_ID; } else if (trackType == "audio") { curTrack.TrackType = TrackType.AUDIO; state = TrackListParseState.GET_CODEC_ID; } else { state = TrackListParseState.GET_NEXT_TRACK; } } break; } case TrackListParseState.GET_CODEC_ID: { Match match = Regex.Match(line, @"^\| \+ Codec ID: (?<CodecID>.+)"); if (match.Success) { string codecID = match.Groups["CodecID"].ToString().Trim(); curTrack.Extension = codecID; // See http://matroska.org/technical/specs/codecid/index.html // Try subtitle Codec IDs first if (codecID == "S_VOBSUB") { curTrack.Extension = "sub"; state = TrackListParseState.GET_LANG; } else if (codecID == "S_TEXT/UTF8") { curTrack.Extension = "srt"; state = TrackListParseState.GET_LANG; } else if (codecID == "S_TEXT/ASS") { curTrack.Extension = "ass"; state = TrackListParseState.GET_LANG; } else if (codecID == "S_TEXT/SSA") { curTrack.Extension = "ssa"; state = TrackListParseState.GET_LANG; } // // Now try audio Codec IDs // else if (codecID == "A_MPEG/L3") { curTrack.Extension = "mp3"; state = TrackListParseState.GET_LANG; } else if (codecID == "A_MPEG/L2") { curTrack.Extension = "mp2"; state = TrackListParseState.GET_LANG; } else if (codecID == "A_MPEG/L1") { curTrack.Extension = "mp1"; state = TrackListParseState.GET_LANG; } else if (codecID.StartsWith("A_PCM")) { curTrack.Extension = "wav"; state = TrackListParseState.GET_LANG; } else if (codecID == "A_MPC") { curTrack.Extension = "mpc"; state = TrackListParseState.GET_LANG; } else if (codecID.StartsWith("A_AC3")) { curTrack.Extension = "ac3"; state = TrackListParseState.GET_LANG; } else if (codecID.StartsWith("A_ALAC")) { curTrack.Extension = "m4a"; state = TrackListParseState.GET_LANG; } else if (codecID.StartsWith("A_DTS")) { curTrack.Extension = "dts"; state = TrackListParseState.GET_LANG; } else if (codecID == "A_VORBIS") { curTrack.Extension = "ogg"; state = TrackListParseState.GET_LANG; } else if (codecID == "A_FLAC") { curTrack.Extension = "flac"; state = TrackListParseState.GET_LANG; } else if (codecID.StartsWith("A_REAL")) { curTrack.Extension = "rm"; state = TrackListParseState.GET_LANG; } else if (codecID.StartsWith("A_AAC")) { curTrack.Extension = "aac"; state = TrackListParseState.GET_LANG; } else if (codecID.StartsWith("A_QUICKTIME")) { curTrack.Extension = "aiff"; state = TrackListParseState.GET_LANG; } else if (codecID == "A_TTA1") { curTrack.Extension = "tta"; state = TrackListParseState.GET_LANG; } else if (codecID == "A_WAVPACK4") { curTrack.Extension = "wv"; state = TrackListParseState.GET_LANG; } else { state = TrackListParseState.GET_NEXT_TRACK; } } break; } // Note: Lang is optional case TrackListParseState.GET_LANG: { Match match = Regex.Match(line, @"^\| \+ Language: (?<Lang>\w+)"); if (match.Success) { curTrack.Lang = match.Groups["Lang"].ToString().Trim(); // All required info for this track was found, add it to the list trackList.Add(curTrack); state = TrackListParseState.GET_NEXT_TRACK; } else { if (line.StartsWith("| + A track")) { // Lang is missing, add what we have trackList.Add(curTrack); state = TrackListParseState.GET_TRACK_NUM; // Reset track info curTrack = new MkvTrack(); } else if (line.StartsWith("|+")) // Are we past the track section? { // Lang is missing, add what we have trackList.Add(curTrack); goto lbl_end_parse; } } break; } default: throw new ArgumentOutOfRangeException(); } } lbl_end_parse: return(trackList); }