private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { try { //забиваем необходимые параметры MediaInfoWrapper media = new MediaInfoWrapper(); media.Open(m.infilepath); m.invcodec = media.VCodecString; m.invcodecshort = media.VCodecShort; //Добавляем инфу, по которой потом можно будет определить, применять ли ForceFilm m.inframerate = media.FrameRate; bool pulldown = media.ScanOrder.Contains("Pulldown"); media.Close(); //Выходим при отмене if (worker.CancellationPending) return; //проверка на невалидную индексацию if (m.invcodecshort != "MPEG2" && m.invcodecshort != "MPEG1") { //Выходим отсюда, декодер будет выбран позже m.indexfile = null; m.vdecoder = 0; return; } //получаем индекс файл m.indexfile = Calculate.GetBestIndexFile(m.infilepath); //определяем видео декодер m.vdecoder = AviSynthScripting.Decoders.MPEG2Source; if (File.Exists(m.indexfile) && !worker.CancellationPending) { //проверяем папки script = AviSynthScripting.GetInfoScript(m, AviSynthScripting.ScriptMode.Info); reader = new AviSynthReader(); reader.ParseScript(script); m.induration = TimeSpan.FromSeconds((double)reader.FrameCount / reader.Framerate); //Определяем, использовался ли Force Film if ((pulldown && m.inframerate == "23.976" || m.inframerate == "29.970") && Math.Abs(reader.Framerate - 23.976) < 0.001) { m.IsForcedFilm = true; m.interlace = SourceType.UNKNOWN; } //Закрываем ридер CloseReader(true); //проверка на устаревшую индекс папку string ifopath = Calculate.GetIFO(m.infilepath); if (File.Exists(ifopath) && !worker.CancellationPending) { VStripWrapper vs = new VStripWrapper(); vs.Open(ifopath); TimeSpan duration = vs.Duration(); vs.Close(); //папка устарела (если разница между продолжительностью в скрипте и в IFO больше 10-ти секунд) if (Math.Abs(m.induration.Duration().TotalSeconds - duration.TotalSeconds) > 10) { //Будем папку удалять.. throw new Exception("MPEG2Source"); } } } } catch (Exception ex) { if (worker != null && !worker.CancellationPending && m != null && num_closes == 0) { //Ошибка ex.HelpLink = script; e.Result = ex; } } finally { CloseReader(true); } }
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { try { //забиваем необходимые параметры MediaInfoWrapper media = new MediaInfoWrapper(); media.Open(m.infilepath); m.invcodec = media.VCodecString; m.invcodecshort = media.VCodecShort; //Добавляем инфу, по которой потом можно будет определить, применять ли ForceFilm m.inframerate = media.FrameRate; bool pulldown = media.ScanOrder.Contains("Pulldown"); media.Close(); //Выходим при отмене if (worker.CancellationPending) { return; } //проверка на невалидную индексацию if (!NV && m.invcodecshort != "MPEG2" && m.invcodecshort != "MPEG1") { //Выходим отсюда, декодер будет выбран позже m.indexfile = null; m.vdecoder = 0; return; } //получаем индекс файл m.indexfile = Calculate.GetBestIndexFile(m.infilepath, NV); //определяем видео декодер if (NV) { m.vdecoder = AviSynthScripting.Decoders.DGSource; m.dgdecnv_path = Calculate.StartupPath + "\\apps\\DGDecNV\\"; } else { m.vdecoder = AviSynthScripting.Decoders.MPEG2Source; } if (File.Exists(m.indexfile) && !worker.CancellationPending) { //Определяем, использовался ли Force Film (#1) //Для DGSource ForceFilm задается через скрипт, а не через правку индекс-файла, //его в любой момент можно вкл\выкл, поэтому тут нужно определиться, использовать ли ForceFilm. if (m.vdecoder == AviSynthScripting.Decoders.DGSource) { if (Indexing_DGIndexNV.CheckIndexAndForceFilm(m.indexfile, m.inframerate)) { m.IsForcedFilm = true; m.interlace = SourceType.UNKNOWN; } } //проверяем папки script = AviSynthScripting.GetInfoScript(m, AviSynthScripting.ScriptMode.Info); reader = new AviSynthReader(); reader.ParseScript(script); m.induration = TimeSpan.FromSeconds((double)reader.FrameCount / reader.Framerate); //Определяем, использовался ли Force Film (#2) //Для MPEG2Source ForceFilm задается через правку индекс-файла, //поэтому изменив его однажды (при индексации) ForceFilm всегда будет вкл. if (m.vdecoder == AviSynthScripting.Decoders.MPEG2Source) { if ((pulldown && m.inframerate == "23.976" || m.inframerate == "29.970") && Math.Abs(reader.Framerate - 23.976) < 0.001) { m.IsForcedFilm = true; m.interlace = SourceType.UNKNOWN; } } //Закрываем ридер CloseReader(true); //проверка на устаревшую индекс папку string ifopath = Calculate.GetIFO(m.infilepath); if (File.Exists(ifopath) && !worker.CancellationPending) { VStripWrapper vs = new VStripWrapper(); vs.Open(ifopath); TimeSpan duration = vs.Duration(); vs.Close(); //папка устарела (если разница между продолжительностью в скрипте и в IFO больше 10-ти секунд) if (Math.Abs(m.induration.Duration().TotalSeconds - duration.TotalSeconds) > 10) { //Будем папку удалять.. throw new Exception("MPEG2Source"); } } } } catch (Exception ex) { if (worker != null && !worker.CancellationPending && m != null && num_closes == 0) { //Ошибка ex.HelpLink = script; e.Result = ex; } } finally { CloseReader(true); } }
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { try { string ext = Path.GetExtension((m.infilepath_source != null) ? m.infilepath_source : m.infilepath).ToLower(); if (ext != ".avs" && ext != ".grf" && ext != ".d2v" && ext != ".dga" && ext != ".dgi") { //забиваем максимум параметров файла MediaInfoWrapper media = new MediaInfoWrapper(); media.Open(m.infilepath); //Выходим при отмене if (m == null || worker.CancellationPending) return; m.invcodec = media.VCodecString; m.invcodecshort = media.VCodecShort; m.invbitrate = media.VideoBitrate; m.inresw = media.Width; m.inresh = media.Height; m.inaspect = media.Aspect; //m.pixelaspect = (m.inresw != 0 && m.inresh != 0) ? (m.inaspect / ((double)m.inresw / (double)m.inresh)) : 1.0; m.pixelaspect = media.PixelAspect; m.invideostream_mi_id = media.VTrackID(); m.invideostream_mi_order = media.VTrackOrder(); m.inframerate = media.FrameRate; m.induration = TimeSpan.FromMilliseconds(media.Milliseconds); m.outduration = m.induration; m.interlace = media.Interlace; m.interlace_raw = media.ScanType; m.fieldOrder_raw = media.ScanOrder; m.inframes = media.Frames; //Возвращаем 29фпс для видео с пуллдауном, т.к. MediaInfo выдает для него 23фпс, а MPEG2Source\DGSource //без ForceFilm из-за пуллдауна будет декодировать с 29-ю. Продолжительность пересчитывается в Caching. if (m.vdecoder == AviSynthScripting.Decoders.MPEG2Source || m.vdecoder == AviSynthScripting.Decoders.DGSource) { if (media.ScanOrder.Contains("Pulldown") && m.inframerate == "23.976" && !m.IsForcedFilm) { m.inframerate = "29.970"; m.interlace = SourceType.FILM; } else if (m.IsForcedFilm) { m.inframerate = "23.976"; m.interlace = SourceType.UNKNOWN; } } //забиваем аудио потоки if (ext == ".pmp" && Settings.EnableAudio) { AudioStream stream = new AudioStream(); stream.codec = "AAC"; stream.codecshort = "AAC"; stream.samplerate = "44100"; stream.bits = 16; stream.channels = 2; stream.language = "English"; m.inaudiostreams.Add(stream.Clone()); m.inaudiostream = 0; } else if (ext == ".dpg") { dpgmuxer dpg = new dpgmuxer(); dpgmuxer.DPGHeader header = dpg.ReadHeader(m.infilepath_source); m.inframes = header.frames; m.inframerate = Calculate.ConvertDoubleToPointString((double)header.fps); m.induration = TimeSpan.FromSeconds((double)header.frames / (double)header.fps); m.outduration = m.induration; if (m.inaudiostreams.Count > 0 && Settings.EnableAudio) { AudioStream stream = (AudioStream)m.inaudiostreams[m.inaudiostream]; //забиваем в список все найденные треки MediaInfoWrapper mi = new MediaInfoWrapper(); stream = mi.GetAudioInfoFromAFile(stream.audiopath, true); stream.samplerate = header.samplerate.ToString(); m.inaudiostreams[m.inaudiostream] = stream; } } else if (ext == ".cda") { AudioStream stream = new AudioStream(); stream.codec = "CDDA"; stream.codecshort = "CDDA"; //stream.bitrate = media.AudioBitrate(snum); //stream.mkvid = media.AudioID(snum); //stream.samplerate = media.Samplerate(snum); //stream.bits = media.Bits(snum); //stream.channels = media.Channels(snum); stream.language = "English"; m.isvideo = false; stream.audiopath = m.infilepath; stream.audiofiles = new string[] { stream.audiopath }; stream = Format.GetValidADecoder(stream); m.inaudiostreams.Add(stream.Clone()); } else if (m.indexfile != null && File.Exists(m.indexfile) && Settings.EnableAudio) { int n = 0; ArrayList atracks = Indexing.GetTracks(m.indexfile); foreach (string apath in atracks) { //определяем аудио потоки AudioStream stream = new AudioStream(); //забиваем в список все найденные треки MediaInfoWrapper mi = new MediaInfoWrapper(); stream = mi.GetAudioInfoFromAFile(apath, true); stream.audiopath = apath; stream.delay = Calculate.GetDelay(apath); stream = Format.GetValidADecoder(stream); stream.mi_id = media.ATrackID(n); stream.mi_order = media.ATrackOrder(n); m.inaudiostreams.Add(stream.Clone()); n++; } m.inaudiostream = 0; } else { if (Settings.EnableAudio || media.CountVideoStreams == 0) { for (int snum = 0; snum < media.CountAudioStreams; snum++) { AudioStream stream = new AudioStream(); stream.codec = media.ACodecString(snum); stream.codecshort = media.ACodecShort(snum); stream.bitrate = media.AudioBitrate(snum); stream.mi_id = media.ATrackID(snum); stream.mi_order = media.ATrackOrder(snum); stream.samplerate = media.Samplerate(snum); stream.bits = media.Bits(snum); stream.channels = media.Channels(snum); if (m.indexfile == null) stream.delay = media.Delay(snum); stream.language = media.AudioLanguage(snum); //вероятно звуковой файл if (media.CountVideoStreams == 0) { m.isvideo = false; stream.audiopath = m.infilepath; stream.audiofiles = new string[] { stream.audiopath }; stream = Format.GetValidADecoder(stream); } m.inaudiostreams.Add(stream.Clone()); } //делаем первый трек активным m.inaudiostream = 0; } //довбиваем duration и frames для join заданий if (m.infileslist.Length > 1) { TimeSpan ts = TimeSpan.Zero; foreach (string file in m.infileslist) { MediaInfoWrapper med = new MediaInfoWrapper(); med.Open(file); ts += med.Duration; med.Close(); } m.induration = ts; m.outduration = m.induration; m.inframes = (int)(m.induration.TotalSeconds * Calculate.ConvertStringToDouble(m.inframerate)); } } //довбиваем параметры из IFO string ifo = Calculate.GetIFO(m.infilepath); if (File.Exists(ifo)) { //через MediaInfo media.Close(); media.Open(ifo); int n = 0; foreach (AudioStream stream in m.inaudiostreams) { stream.language = media.AudioLanguage(n); n++; } //через VStrip VStripWrapper vs = new VStripWrapper(); vs.Open(ifo); m.induration = vs.Duration(); m.outduration = m.induration; m.inframes = (int)(m.induration.TotalSeconds * Calculate.ConvertStringToDouble(m.inframerate)); vs.Close(); #region Язык через VStrip: //iifo_lang_tbl[] parse_ifo.c (The ISO 639 language codes) //??? (AC3 2ch, 0xBD 0x80) [0,1] //MI - "Unknown" //Italiano (AC3 2ch, 0xBD 0x82) [0,1]" //MI - "Italian", есть и др. несоответствия.. //Russian (AC3 2ch, 0xBD 0x80) [0,1]" #endregion } //закрываем MediaInfo media.Close(); } if (ext == ".grf" || ext == ".d2v" || ext == ".dga" || ext == ".dgi") { #region grf, d2v, dga, dgi if (ext == ".grf") { string infile = Path.GetFileNameWithoutExtension(m.infilepath).ToLower(); if (infile.StartsWith("audio")) { //Это аудио-граф m.isvideo = false; AudioStream stream = new AudioStream(); stream.audiopath = m.infilepath; stream.audiofiles = new string[] { stream.audiopath }; stream.codec = stream.codecshort = "PCM"; stream.language = "Unknown"; stream = Format.GetValidADecoder(stream); m.inaudiostreams.Add(stream.Clone()); } else { //Это видео-граф m.invcodec = "RAWVIDEO"; m.invcodecshort = "RAWVIDEO"; //Если DirectShowSource не сможет определить fps, то требуемое значение можно будет указать в имени файла.. Regex r = new Regex(@"(fps\s?=\s?([\d\.\,]*))", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); Match mat = r.Match(infile); if (mat.Success) { double fps = Calculate.ConvertStringToDouble(mat.Groups[2].Value); if (fps > 0) m.inframerate = Calculate.ConvertDoubleToPointString(fps); //"Очищаем" имя файла infile = infile.Replace(mat.Groups[1].Value, "").Trim(new char[] { ' ', '_', '-', '(', ')', '.', ',' }); } //Ищем звук к нему if (Settings.EnableAudio) { //Почему на шаблон "audio*.grf" находятся и файлы типа "Копия audio file.grf"?! string[] afiles = Directory.GetFiles(Path.GetDirectoryName(m.infilepath), "audio*.grf"); foreach (string afile in afiles) { string aname = Path.GetFileNameWithoutExtension(afile).ToLower(); if (aname.StartsWith("audio") && aname.Contains(infile)) { AudioStream stream = new AudioStream(); stream.audiopath = afile; stream.audiofiles = new string[] { stream.audiopath }; stream.codec = stream.codecshort = "PCM"; stream.language = "Unknown"; stream = Format.GetValidADecoder(stream); m.inaudiostreams.Add(stream.Clone()); break; //Только один трек } } } } } else if (ext == ".d2v") { //Читаем d2v-файл int n = 0; string line = ""; Match mat1; Match mat2; Regex r1 = new Regex(@"Picture_Size=(\d+)x(\d+)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); Regex r2 = new Regex(@"Aspect_Ratio=(\d+\.*\d*):(\d+\.*\d*)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); int result1 = 720; int result2 = 576; double result3 = 4; double result4 = 3; //Значения по-умолчанию using (StreamReader sr = new StreamReader(m.indexfile, System.Text.Encoding.Default)) while (!sr.EndOfStream && n < 15) //Ограничиваемся первыми 15-ю строчками { line = sr.ReadLine(); mat1 = r1.Match(line); mat2 = r2.Match(line); if (mat1.Success) { result1 = Convert.ToInt32(mat1.Groups[1].Value); result2 = Convert.ToInt32(mat1.Groups[2].Value); } if (mat2.Success) { result3 = Calculate.ConvertStringToDouble(mat2.Groups[1].Value); result4 = Calculate.ConvertStringToDouble(mat2.Groups[2].Value); } n += 1; } m.inresw = result1; m.inresh = result2; m.inaspect = result3 / result4; m.pixelaspect = m.inaspect / ((double)m.inresw / (double)m.inresh); m.invcodecshort = "MPEG2"; } else if (ext == ".dga") { //Смотрим, на месте ли log-файл string log_file = Calculate.RemoveExtention(m.infilepath) + "log"; if (File.Exists(log_file)) { //Читаем log-файл string text_log = ""; Match mat; Regex r1 = new Regex(@"Frame.Size:.(\d+)x(\d+)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); Regex r2 = new Regex(@"SAR:.(\d+):(\d+)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); int result1 = 1280; int result2 = 720; double result3 = 1; double result4 = 1; //Значения по-умолчанию using (StreamReader sr = new StreamReader(log_file, System.Text.Encoding.Default)) text_log = sr.ReadToEnd(); mat = r1.Match(text_log); if (mat.Success) { result1 = Convert.ToInt32(mat.Groups[1].Value); result2 = Convert.ToInt32(mat.Groups[2].Value); } mat = r2.Match(text_log); if (mat.Success) { result3 = Convert.ToDouble(mat.Groups[1].Value); result4 = Convert.ToDouble(mat.Groups[2].Value); } m.inresw = result1; m.inresh = result2; m.inaspect = (result3 / result4) * ((double)m.inresw / (double)m.inresh); m.pixelaspect = m.inaspect / ((double)m.inresw / (double)m.inresh); //можно еще определить тут фпс, но всё-равно это будет сделано позже через ависинт-скрипт (class Caching). m.invcodecshort = "h264"; } else { //Если нет log-файла, ищем исходный файл и берем инфу из него Match mat; string source_file = ""; Regex r = new Regex(@"(\D:\\.*\..*)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); using (StreamReader sr = new StreamReader(m.indexfile, System.Text.Encoding.Default)) for (int i = 0; i < 3 && !sr.EndOfStream; i += 1) { source_file = sr.ReadLine(); } mat = r.Match(source_file); if (mat.Success && File.Exists(source_file = mat.Groups[1].Value)) { MediaInfoWrapper media = new MediaInfoWrapper(); media.Open(source_file); m.invcodecshort = media.VCodecShort; m.inresw = media.Width; m.inresh = media.Height; m.inaspect = media.Aspect; m.pixelaspect = media.PixelAspect; media.Close(); } else { throw new Exception(Languages.Translate("Can`t find DGAVCIndex log-file:") + " " + log_file + "\r\n" + Languages.Translate("And can`t determine the source-file.")); } } } else if (ext == ".dgi") { //Путь к декодеру using (StreamReader sr = new StreamReader(m.indexfile, System.Text.Encoding.Default)) for (int i = 0; i < 2 && !sr.EndOfStream; i += 1) { m.dgdecnv_path = sr.ReadLine(); } if (!File.Exists(m.dgdecnv_path + "DGDecodeNV.dll")) { throw new Exception(Languages.Translate("Can`t find file") + ": " + m.dgdecnv_path + "DGDecodeNV.dll"); } //Смотрим, на месте ли log-файл string log_file = Calculate.RemoveExtention(m.infilepath) + "log"; if (File.Exists(log_file)) { //Читаем log-файл Match mat; string text_log = ""; Regex r1 = new Regex(@"Coded.Size:.(\d+)x(\d+)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); Regex r2 = new Regex(@"SAR:.(\d+):(\d+)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); Regex r3 = new Regex(@"Aspect.Ratio:.(\d+\.*\d*):(\d+\.*\d*)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); Regex r4 = new Regex(@"Video.Type:.(.*).", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); double result1, result2; text_log = File.ReadAllText(log_file, System.Text.Encoding.Default); //Разрешение (Coded Size:) mat = r1.Match(text_log); if (mat.Success) { m.inresw = Convert.ToInt32(mat.Groups[1].Value); m.inresh = Convert.ToInt32(mat.Groups[2].Value); //Аспект (SAR:) mat = r2.Match(text_log); if (mat.Success) { result1 = Convert.ToDouble(mat.Groups[1].Value); result2 = Convert.ToDouble(mat.Groups[2].Value); m.inaspect = (result1 / result2) * ((double)m.inresw / (double)m.inresh); m.pixelaspect = result1 / result2; } else { //Аспект (Aspect Ratio:) mat = r3.Match(text_log); if (mat.Success) { result1 = Calculate.ConvertStringToDouble(mat.Groups[1].Value); result2 = Calculate.ConvertStringToDouble(mat.Groups[2].Value); m.inaspect = result1 / result2; m.pixelaspect = m.inaspect / ((double)m.inresw / (double)m.inresh); } else { m.inaspect = (double)m.inresw / (double)m.inresh; m.pixelaspect = 1.0; } } } else { m.inaspect = 16.0 / 9.0; m.pixelaspect = 1.0; } //Кодек mat = r4.Match(text_log); if (mat.Success) { string codec = mat.Groups[1].Value; if (codec == "AVC") codec = "h264"; m.invcodecshort = codec; } } else { //Если нет log-файла, ищем исходный файл и берем инфу из него string source_file = ""; Regex r = new Regex(@"(\D:\\.*\..*)\s\d+", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); using (StreamReader sr = new StreamReader(m.indexfile, System.Text.Encoding.Default)) for (int i = 0; i < 4 && !sr.EndOfStream; i += 1) { source_file = sr.ReadLine(); } Match mat = r.Match(source_file); if (mat.Success && File.Exists(source_file = mat.Groups[1].Value)) { MediaInfoWrapper media = new MediaInfoWrapper(); media.Open(source_file); m.invcodecshort = media.VCodecShort; m.inresw = media.Width; m.inresh = media.Height; m.inaspect = media.Aspect; m.pixelaspect = media.PixelAspect; media.Close(); } else { throw new Exception(Languages.Translate("Can`t find DGIndexNV log-file:") + " " + log_file + "\r\n" + Languages.Translate("And can`t determine the source-file.")); } } } #endregion } else { //Довбиваем параметры с помощью FFmpeg ff = new FFInfo(); ff.Open(m.infilepath); //Выходим при отмене if (m == null || worker.CancellationPending) return; //Видео if (ff.VideoStreams().Count > 0) { m.invideostream_ff_order = ff.FirstVideoStreamID(); m.invideostream_ff_order_filtered = ff.FilteredStreamOrder(m.invideostream_ff_order); if (m.invideostream_mi_order < 0) m.invideostream_mi_order = m.invideostream_ff_order; if (ext == ".avs") { m.invcodec = ff.StreamCodec(m.invideostream_ff_order); m.invcodecshort = ff.StreamCodecShort(m.invideostream_ff_order); m.invbitrate = ff.VideoBitrate(m.invideostream_ff_order); m.inresw = ff.StreamW(m.invideostream_ff_order); m.inresh = ff.StreamH(m.invideostream_ff_order); m.inaspect = (double)m.inresw / (double)m.inresh; } else { //Через MI нашелся только звук, но у FFmpeg есть и видео if (!m.isvideo) { if (ext != ".cda") { m.isvideo = true; m.invcodec = ff.StreamCodec(m.invideostream_ff_order); m.invcodecshort = ff.StreamCodecShort(m.invideostream_ff_order); m.invbitrate = ff.VideoBitrate(m.invideostream_ff_order); m.inresw = ff.StreamW(m.invideostream_ff_order); m.inresh = ff.StreamH(m.invideostream_ff_order); double sar = ff.CalculateSAR(m.invideostream_ff_order); m.pixelaspect = (sar != 0) ? sar : 1.0; double dar = ff.CalculateDAR(m.invideostream_ff_order); m.inaspect = (dar != 0) ? dar : ((double)m.inresw / (double)m.inresh); //Обнуляем аудио пути (там сейчас вписан сам исходник и декодер под его расширение) foreach (AudioStream stream in m.inaudiostreams) { stream.audiopath = null; stream.audiofiles = null; stream.decoder = 0; } } } else if (Settings.UseFFmpegAR) { double sar = ff.CalculateSAR(m.invideostream_ff_order); if (sar != 0) m.pixelaspect = sar; double dar = ff.CalculateDAR(m.invideostream_ff_order); if (dar != 0) m.inaspect = dar; } } //null - MediaInfo для этого файла не запускалась (avs, grf,..) //"" - MediaInfo запускалась, но нужной инфы получить не удалось //При null тут все-же можно определить fps для avs, но т.к. FFmpeg //сильно округляет fps, то лучше сами позже определим его в Caching(). if (m.inframerate == "") { m.inframerate = ff.StreamFramerate(m.invideostream_ff_order); if (m.inframerate != "") { m.induration = ff.Duration(); m.outduration = m.induration; m.inframes = (int)(m.induration.TotalSeconds * Calculate.ConvertStringToDouble(m.inframerate)); } } } //Аудио if (ff.AudioStreams().Count > 0) { ArrayList AStreams = ff.AudioStreams(); ArrayList AStreams_done = new ArrayList(); //подправляем кодек, ffID, язык //Это будет работать как надо, только если очерёдность наших треков //совпадает с их очерёдностью в FFmpeg, иначе инфа о треках перепутается! int astream = 0; foreach (AudioStream stream in m.inaudiostreams) { stream.ff_order = (int)AStreams[astream]; //ID трека для FFmpeg stream.ff_order_filtered = ff.FilteredStreamOrder(stream.ff_order); if (stream.mi_order < 0) stream.mi_order = stream.ff_order; if (stream.bitrate == 0) stream.bitrate = ff.AudioBitrate(stream.ff_order); if (stream.channels == 0) stream.channels = ff.StreamChannels(stream.ff_order); if (stream.samplerate == null) stream.samplerate = ff.StreamSamplerate(stream.ff_order); if (stream.language == "Unknown") stream.language = ff.StreamLanguage(stream.ff_order); stream.ff_bits = ff.StreamBits(stream.ff_order); stream.ff_codec = ff.StreamCodec(stream.ff_order); if (stream.codec == "A_MS/ACM" || stream.codec == "") { stream.codec = stream.ff_codec; stream.codecshort = ff.StreamCodecShort(stream.ff_order); } AStreams_done.Add(AStreams[astream]); astream++; if (astream >= AStreams.Count) break; } //Удаляем все FF-треки, инфа от которых уже взята foreach (object obj in AStreams_done) AStreams.Remove(obj); //Еще раз перепроверка для звуковых файлов (файл без видео), если //выше через MI это не отловилось (т.е. через MI звук не обнаружился) bool is_audio_only = (m.isvideo && string.IsNullOrEmpty(m.inframerate) && string.IsNullOrEmpty(m.invcodec) && (m.inresw == 0 || m.inresh == 0) && ff.VideoStreams().Count == 0); if ((m.indexfile == null && Settings.EnableAudio || ext == ".avs" || is_audio_only) && AStreams.Count > 0) { //забиваем аудио, если они ещё не забиты (если FF-треков осталось больше, чем у нас уже есть) //Все оставшиеся треки от FFmpeg добавляются к уже имеющимся. Тут тоже нужно как-то //сопоставлять треки, и объединить это всё с кодом, который выше! foreach (int stream_num in AStreams) { AudioStream stream = new AudioStream(); stream.ff_bits = ff.StreamBits(stream_num); stream.ff_codec = stream.codec = ff.StreamCodec(stream_num); stream.codecshort = ff.StreamCodecShort(stream_num); stream.bitrate = ff.AudioBitrate(stream_num); stream.samplerate = ff.StreamSamplerate(stream_num); stream.bits = ff.StreamBits(stream_num); stream.channels = ff.StreamChannels(stream_num); stream.language = ff.StreamLanguage(stream_num); stream.mi_order = stream.ff_order = stream_num; stream.ff_order_filtered = ff.FilteredStreamOrder(stream_num); if (is_audio_only) { m.isvideo = false; stream.audiopath = m.infilepath; stream.audiofiles = new string[] { stream.audiopath }; stream = Format.GetValidADecoder(stream); } m.inaudiostreams.Add(stream.Clone()); } m.inaudiostream = 0; } } //Закрываем FFInfo CloseFFInfo(); } if (!m.isvideo) { m.invcodec = m.invcodecshort = "NONE"; m.inframerate = m.outframerate = "25.000"; m.vdecoder = AviSynthScripting.Decoders.BlankClip; //Кол-во кадров и продолжительность определятся в Caching() //на основе реальной продолжительности звука от декодера m.induration = m.outduration = TimeSpan.Zero; m.inframes = m.outframes = 0; } //определяем аудио декодер foreach (AudioStream stream in m.inaudiostreams) { if (stream.decoder == 0) stream.decoder = Format.GetValidADecoder(stream).decoder; } //подсчитываем размер long sizeb = 0; foreach (string f in m.infileslist) { FileInfo info = new FileInfo(f); sizeb += info.Length; } m.infilesize = Calculate.ConvertDoubleToPointString((double)sizeb / 1049511, 1) + " mb"; m.infilesizeint = (int)((double)sizeb / 1049511); } catch (Exception ex) { if (worker != null && !worker.CancellationPending && m != null && num_closes == 0) { //Ошибка e.Result = ex; } m = null; } }
private void MainFormLoader() { if (!Application.Current.Dispatcher.CheckAccess()) Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new MainFormLoaderDelegate(MainFormLoader)); else { try { // If we have ANY file open, close it and shut down DirectShow if (this.currentState != PlayState.Init) CloseClip(); //список плохих титлов ArrayList badlist = new ArrayList(); if (isInfoLoading) { double maximum = 0; int index_of_maximum = 0; int num = 0; //забиваем длительность foreach (object obj in dvd) { string[] titles = (string[])obj; string ifopath = Calculate.GetIFO(titles[0]); if (File.Exists(ifopath)) { MediaInfoWrapper media = new MediaInfoWrapper(); media.Open(ifopath); string info = media.Width + "x" + media.Height + " " + media.AspectString + " " + media.Standart; media.Close(); //получаем информацию из ифо VStripWrapper vs = new VStripWrapper(); vs.Open(ifopath); double titleduration = vs.Duration().TotalSeconds; //string info = vs.Width() + "x" + vs.Height() + " " + vs.System(); //При обращении к ifoGetVideoDesc на некоторых системах происходит вылет VStrip.dll.. //Теперь нужная инфа будет браться из МедиаИнфо.. vs.Close(); string titlenum = Calculate.GetTitleNum(titles[0]); combo_titles.Items.Add("T" + titlenum + " " + info + " " + Calculate.GetTimeline(titleduration) + " - " + titles.Length + " file(s)"); //Ищем самый продолжительный титл if (titleduration > maximum) { maximum = titleduration; index_of_maximum = num; } num += 1; } //метод если нет IFO else { try { int n = 0; double titleduration = 0.0; string info = ""; foreach (string tilte in titles) { int hr = 0; this.graphBuilder = (IGraphBuilder)new FilterGraph(); // Have the graph builder construct its the appropriate graph automatically hr = this.graphBuilder.RenderFile(tilte, null); DsError.ThrowExceptionForHR(hr); // QueryInterface for DirectShow interfaces this.mediaControl = (IMediaControl)this.graphBuilder; this.mediaPosition = (IMediaPosition)this.graphBuilder; //определяем длительность double cduration = 0.0; hr = mediaPosition.get_Duration(out cduration); DsError.ThrowExceptionForHR(hr); //определяем различные параметры if (n == 0) { this.basicVideo = this.graphBuilder as IBasicVideo; //this.basicAudio = this.graphBuilder as IBasicAudio; int resw; int resh; double AvgTimePerFrame; hr = basicVideo.get_SourceWidth(out resw); DsError.ThrowExceptionForHR(hr); hr = basicVideo.get_SourceHeight(out resh); DsError.ThrowExceptionForHR(hr); hr = basicVideo.get_AvgTimePerFrame(out AvgTimePerFrame); double framerate = 1 / AvgTimePerFrame; string system = "NTSC"; if (framerate == 25.0) system = "PAL"; info += resw + "x" + resh + " " + system + " "; } //освобождаем ресурсы CloseInterfaces(); titleduration += cduration; n++; } string titlenum = Calculate.GetTitleNum(titles[0]); combo_titles.Items.Add("T" + titlenum + " " + info + Calculate.GetTimeline(titleduration)); } catch { badlist.Add(obj); CloseInterfaces(); } } } combo_titles.Items.RemoveAt(0); combo_titles.SelectedIndex = index_of_maximum; this.isInfoLoading = false; } //удаляем плохие титлы foreach (object obj in badlist) dvd.Remove(obj); //загружаем титл string[] deftitles = (string[])dvd[combo_titles.SelectedIndex]; this.filepath = deftitles[0]; string title_s = Calculate.GetTitleNum(this.filepath); textbox_name.Text = Calculate.GetDVDName(this.filepath) + " T" + title_s; m.infilepath = this.filepath; m.infileslist = deftitles; //Определяем аспект для DirectShow плейера (чтоб не вызывать еще раз MediaInfo) string aspect = Calculate.GetRegexValue(@"\s\d+x\d+\s(\d+:\d+)\s", combo_titles.SelectedItem.ToString()); if (!string.IsNullOrEmpty(aspect)) { if (aspect == "4:3") in_ar = 4.0 / 3.0; else if (aspect == "16:9") in_ar = 16.0 / 9.0; else if (aspect == "2.2:1") in_ar = 2.21; } // Reset status variables this.currentState = PlayState.Stopped; // Start playing the media file if (Settings.PlayerEngine != Settings.PlayerEngines.MediaBridge) PlayMovieInWindow(this.filepath); else PlayWithMediaBridge(this.filepath); } catch (Exception ex) { textbox_name.Text = ""; CloseClip(); this.filepath = String.Empty; ErrorException("MainFormLoader: " + ex.Message, ex.StackTrace); } } }
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { try { string ext = Path.GetExtension((m.infilepath_source != null) ? m.infilepath_source : m.infilepath).ToLower(); if (ext != ".avs" && ext != ".grf" && ext != ".d2v" && ext != ".dga" && ext != ".dgi") { //забиваем максимум параметров файла MediaInfoWrapper media = new MediaInfoWrapper(); media.Open(m.infilepath); //Выходим при отмене if (m == null || worker.CancellationPending) { return; } m.invcodec = media.VCodecString; m.invcodecshort = media.VCodecShort; m.invbitrate = media.VideoBitrate; m.inresw = media.Width; m.inresh = media.Height; m.inaspect = media.Aspect; //m.pixelaspect = (m.inresw != 0 && m.inresh != 0) ? (m.inaspect / ((double)m.inresw / (double)m.inresh)) : 1.0; m.pixelaspect = media.PixelAspect; m.invideostream_mi_id = media.VTrackID(); m.invideostream_mi_order = media.VTrackOrder(); m.inframerate = media.FrameRate; m.induration = TimeSpan.FromMilliseconds(media.Milliseconds); m.outduration = m.induration; m.interlace = media.Interlace; m.interlace_raw = media.ScanType; m.fieldOrder_raw = media.ScanOrder; m.inframes = media.Frames; //Возвращаем 29фпс для видео с пуллдауном, т.к. MediaInfo выдает для него 23фпс, а MPEG2Source\DGSource //без ForceFilm из-за пуллдауна будет декодировать с 29-ю. Продолжительность пересчитывается в Caching. if (m.vdecoder == AviSynthScripting.Decoders.MPEG2Source || m.vdecoder == AviSynthScripting.Decoders.DGSource) { if (media.ScanOrder.Contains("Pulldown") && m.inframerate == "23.976" && !m.IsForcedFilm) { m.inframerate = "29.970"; m.interlace = SourceType.FILM; } else if (m.IsForcedFilm) { m.inframerate = "23.976"; m.interlace = SourceType.UNKNOWN; } } //забиваем аудио потоки if (ext == ".pmp" && Settings.EnableAudio) { AudioStream stream = new AudioStream(); stream.codec = "AAC"; stream.codecshort = "AAC"; stream.samplerate = "44100"; stream.bits = 16; stream.channels = 2; stream.language = "English"; m.inaudiostreams.Add(stream.Clone()); m.inaudiostream = 0; } else if (ext == ".dpg") { dpgmuxer dpg = new dpgmuxer(); dpgmuxer.DPGHeader header = dpg.ReadHeader(m.infilepath_source); m.inframes = header.frames; m.inframerate = Calculate.ConvertDoubleToPointString((double)header.fps); m.induration = TimeSpan.FromSeconds((double)header.frames / (double)header.fps); m.outduration = m.induration; if (m.inaudiostreams.Count > 0 && Settings.EnableAudio) { AudioStream stream = (AudioStream)m.inaudiostreams[m.inaudiostream]; //забиваем в список все найденные треки MediaInfoWrapper mi = new MediaInfoWrapper(); stream = mi.GetAudioInfoFromAFile(stream.audiopath, true); stream.samplerate = header.samplerate.ToString(); m.inaudiostreams[m.inaudiostream] = stream; } } else if (ext == ".cda") { AudioStream stream = new AudioStream(); stream.codec = "CDDA"; stream.codecshort = "CDDA"; //stream.bitrate = media.AudioBitrate(snum); //stream.mkvid = media.AudioID(snum); //stream.samplerate = media.Samplerate(snum); //stream.bits = media.Bits(snum); //stream.channels = media.Channels(snum); stream.language = "English"; m.isvideo = false; stream.audiopath = m.infilepath; stream.audiofiles = new string[] { stream.audiopath }; stream = Format.GetValidADecoder(stream); m.inaudiostreams.Add(stream.Clone()); } else if (m.indexfile != null && File.Exists(m.indexfile) && Settings.EnableAudio) { int n = 0; ArrayList atracks = Indexing.GetTracks(m.indexfile); foreach (string apath in atracks) { //определяем аудио потоки AudioStream stream = new AudioStream(); //забиваем в список все найденные треки MediaInfoWrapper mi = new MediaInfoWrapper(); stream = mi.GetAudioInfoFromAFile(apath, true); stream.audiopath = apath; stream.delay = Calculate.GetDelay(apath); stream = Format.GetValidADecoder(stream); stream.mi_id = media.ATrackID(n); stream.mi_order = media.ATrackOrder(n); m.inaudiostreams.Add(stream.Clone()); n++; } m.inaudiostream = 0; } else { if (Settings.EnableAudio || media.CountVideoStreams == 0) { for (int snum = 0; snum < media.CountAudioStreams; snum++) { AudioStream stream = new AudioStream(); stream.codec = media.ACodecString(snum); stream.codecshort = media.ACodecShort(snum); stream.bitrate = media.AudioBitrate(snum); stream.mi_id = media.ATrackID(snum); stream.mi_order = media.ATrackOrder(snum); stream.samplerate = media.Samplerate(snum); stream.bits = media.Bits(snum); stream.channels = media.Channels(snum); if (m.indexfile == null) { stream.delay = media.Delay(snum); } stream.language = media.AudioLanguage(snum); //вероятно звуковой файл if (media.CountVideoStreams == 0) { m.isvideo = false; stream.audiopath = m.infilepath; stream.audiofiles = new string[] { stream.audiopath }; stream = Format.GetValidADecoder(stream); } m.inaudiostreams.Add(stream.Clone()); } //делаем первый трек активным m.inaudiostream = 0; } //довбиваем duration и frames для join заданий if (m.infileslist.Length > 1) { TimeSpan ts = TimeSpan.Zero; foreach (string file in m.infileslist) { MediaInfoWrapper med = new MediaInfoWrapper(); med.Open(file); ts += med.Duration; med.Close(); } m.induration = ts; m.outduration = m.induration; m.inframes = (int)(m.induration.TotalSeconds * Calculate.ConvertStringToDouble(m.inframerate)); } } //довбиваем параметры из IFO string ifo = Calculate.GetIFO(m.infilepath); if (File.Exists(ifo)) { //через MediaInfo media.Close(); media.Open(ifo); int n = 0; foreach (AudioStream stream in m.inaudiostreams) { stream.language = media.AudioLanguage(n); n++; } //через VStrip VStripWrapper vs = new VStripWrapper(); vs.Open(ifo); m.induration = vs.Duration(); m.outduration = m.induration; m.inframes = (int)(m.induration.TotalSeconds * Calculate.ConvertStringToDouble(m.inframerate)); vs.Close(); #region Язык через VStrip: //iifo_lang_tbl[] parse_ifo.c (The ISO 639 language codes) //??? (AC3 2ch, 0xBD 0x80) [0,1] //MI - "Unknown" //Italiano (AC3 2ch, 0xBD 0x82) [0,1]" //MI - "Italian", есть и др. несоответствия.. //Russian (AC3 2ch, 0xBD 0x80) [0,1]" #endregion } //закрываем MediaInfo media.Close(); } if (ext == ".grf" || ext == ".d2v" || ext == ".dga" || ext == ".dgi") { #region grf, d2v, dga, dgi if (ext == ".grf") { string infile = Path.GetFileNameWithoutExtension(m.infilepath).ToLower(); if (infile.StartsWith("audio")) { //Это аудио-граф m.isvideo = false; AudioStream stream = new AudioStream(); stream.audiopath = m.infilepath; stream.audiofiles = new string[] { stream.audiopath }; stream.codec = stream.codecshort = "PCM"; stream.language = "Unknown"; stream = Format.GetValidADecoder(stream); m.inaudiostreams.Add(stream.Clone()); } else { //Это видео-граф m.invcodec = "RAWVIDEO"; m.invcodecshort = "RAWVIDEO"; //Если DirectShowSource не сможет определить fps, то требуемое значение можно будет указать в имени файла.. Regex r = new Regex(@"(fps\s?=\s?([\d\.\,]*))", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); Match mat = r.Match(infile); if (mat.Success) { double fps = Calculate.ConvertStringToDouble(mat.Groups[2].Value); if (fps > 0) { m.inframerate = Calculate.ConvertDoubleToPointString(fps); } //"Очищаем" имя файла infile = infile.Replace(mat.Groups[1].Value, "").Trim(new char[] { ' ', '_', '-', '(', ')', '.', ',' }); } //Ищем звук к нему if (Settings.EnableAudio) { //Почему на шаблон "audio*.grf" находятся и файлы типа "Копия audio file.grf"?! string[] afiles = Directory.GetFiles(Path.GetDirectoryName(m.infilepath), "audio*.grf"); foreach (string afile in afiles) { string aname = Path.GetFileNameWithoutExtension(afile).ToLower(); if (aname.StartsWith("audio") && aname.Contains(infile)) { AudioStream stream = new AudioStream(); stream.audiopath = afile; stream.audiofiles = new string[] { stream.audiopath }; stream.codec = stream.codecshort = "PCM"; stream.language = "Unknown"; stream = Format.GetValidADecoder(stream); m.inaudiostreams.Add(stream.Clone()); break; //Только один трек } } } } } else if (ext == ".d2v") { //Читаем d2v-файл int n = 0; string line = ""; Match mat1; Match mat2; Regex r1 = new Regex(@"Picture_Size=(\d+)x(\d+)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); Regex r2 = new Regex(@"Aspect_Ratio=(\d+\.*\d*):(\d+\.*\d*)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); int result1 = 720; int result2 = 576; double result3 = 4; double result4 = 3; //Значения по-умолчанию using (StreamReader sr = new StreamReader(m.indexfile, System.Text.Encoding.Default)) while (!sr.EndOfStream && n < 15) //Ограничиваемся первыми 15-ю строчками { line = sr.ReadLine(); mat1 = r1.Match(line); mat2 = r2.Match(line); if (mat1.Success) { result1 = Convert.ToInt32(mat1.Groups[1].Value); result2 = Convert.ToInt32(mat1.Groups[2].Value); } if (mat2.Success) { result3 = Calculate.ConvertStringToDouble(mat2.Groups[1].Value); result4 = Calculate.ConvertStringToDouble(mat2.Groups[2].Value); } n += 1; } m.inresw = result1; m.inresh = result2; m.inaspect = result3 / result4; m.pixelaspect = m.inaspect / ((double)m.inresw / (double)m.inresh); m.invcodecshort = "MPEG2"; } else if (ext == ".dga") { //Смотрим, на месте ли log-файл string log_file = Calculate.RemoveExtention(m.infilepath) + "log"; if (File.Exists(log_file)) { //Читаем log-файл string text_log = ""; Match mat; Regex r1 = new Regex(@"Frame.Size:.(\d+)x(\d+)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); Regex r2 = new Regex(@"SAR:.(\d+):(\d+)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); int result1 = 1280; int result2 = 720; double result3 = 1; double result4 = 1; //Значения по-умолчанию using (StreamReader sr = new StreamReader(log_file, System.Text.Encoding.Default)) text_log = sr.ReadToEnd(); mat = r1.Match(text_log); if (mat.Success) { result1 = Convert.ToInt32(mat.Groups[1].Value); result2 = Convert.ToInt32(mat.Groups[2].Value); } mat = r2.Match(text_log); if (mat.Success) { result3 = Convert.ToDouble(mat.Groups[1].Value); result4 = Convert.ToDouble(mat.Groups[2].Value); } m.inresw = result1; m.inresh = result2; m.inaspect = (result3 / result4) * ((double)m.inresw / (double)m.inresh); m.pixelaspect = m.inaspect / ((double)m.inresw / (double)m.inresh); //можно еще определить тут фпс, но всё-равно это будет сделано позже через ависинт-скрипт (class Caching). m.invcodecshort = "h264"; } else { //Если нет log-файла, ищем исходный файл и берем инфу из него Match mat; string source_file = ""; Regex r = new Regex(@"(\D:\\.*\..*)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); using (StreamReader sr = new StreamReader(m.indexfile, System.Text.Encoding.Default)) for (int i = 0; i < 3 && !sr.EndOfStream; i += 1) { source_file = sr.ReadLine(); } mat = r.Match(source_file); if (mat.Success && File.Exists(source_file = mat.Groups[1].Value)) { MediaInfoWrapper media = new MediaInfoWrapper(); media.Open(source_file); m.invcodecshort = media.VCodecShort; m.inresw = media.Width; m.inresh = media.Height; m.inaspect = media.Aspect; m.pixelaspect = media.PixelAspect; media.Close(); } else { throw new Exception(Languages.Translate("Can`t find DGAVCIndex log-file:") + " " + log_file + "\r\n" + Languages.Translate("And can`t determine the source-file.")); } } } else if (ext == ".dgi") { //Путь к декодеру using (StreamReader sr = new StreamReader(m.indexfile, System.Text.Encoding.Default)) for (int i = 0; i < 2 && !sr.EndOfStream; i += 1) { m.dgdecnv_path = sr.ReadLine(); } if (!File.Exists(m.dgdecnv_path + "DGDecodeNV.dll")) { throw new Exception(Languages.Translate("Can`t find file") + ": " + m.dgdecnv_path + "DGDecodeNV.dll"); } //Смотрим, на месте ли log-файл string log_file = Calculate.RemoveExtention(m.infilepath) + "log"; if (File.Exists(log_file)) { //Читаем log-файл Match mat; string text_log = ""; Regex r1 = new Regex(@"Coded.Size:.(\d+)x(\d+)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); Regex r2 = new Regex(@"SAR:.(\d+):(\d+)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); Regex r3 = new Regex(@"Aspect.Ratio:.(\d+\.*\d*):(\d+\.*\d*)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); Regex r4 = new Regex(@"Video.Type:.(.*).", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); double result1, result2; text_log = File.ReadAllText(log_file, System.Text.Encoding.Default); //Разрешение (Coded Size:) mat = r1.Match(text_log); if (mat.Success) { m.inresw = Convert.ToInt32(mat.Groups[1].Value); m.inresh = Convert.ToInt32(mat.Groups[2].Value); //Аспект (SAR:) mat = r2.Match(text_log); if (mat.Success) { result1 = Convert.ToDouble(mat.Groups[1].Value); result2 = Convert.ToDouble(mat.Groups[2].Value); m.inaspect = (result1 / result2) * ((double)m.inresw / (double)m.inresh); m.pixelaspect = result1 / result2; } else { //Аспект (Aspect Ratio:) mat = r3.Match(text_log); if (mat.Success) { result1 = Calculate.ConvertStringToDouble(mat.Groups[1].Value); result2 = Calculate.ConvertStringToDouble(mat.Groups[2].Value); m.inaspect = result1 / result2; m.pixelaspect = m.inaspect / ((double)m.inresw / (double)m.inresh); } else { m.inaspect = (double)m.inresw / (double)m.inresh; m.pixelaspect = 1.0; } } } else { m.inaspect = 16.0 / 9.0; m.pixelaspect = 1.0; } //Кодек mat = r4.Match(text_log); if (mat.Success) { string codec = mat.Groups[1].Value; if (codec == "AVC") { codec = "h264"; } m.invcodecshort = codec; } } else { //Если нет log-файла, ищем исходный файл и берем инфу из него string source_file = ""; Regex r = new Regex(@"(\D:\\.*\..*)\s\d+", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); using (StreamReader sr = new StreamReader(m.indexfile, System.Text.Encoding.Default)) for (int i = 0; i < 4 && !sr.EndOfStream; i += 1) { source_file = sr.ReadLine(); } Match mat = r.Match(source_file); if (mat.Success && File.Exists(source_file = mat.Groups[1].Value)) { MediaInfoWrapper media = new MediaInfoWrapper(); media.Open(source_file); m.invcodecshort = media.VCodecShort; m.inresw = media.Width; m.inresh = media.Height; m.inaspect = media.Aspect; m.pixelaspect = media.PixelAspect; media.Close(); } else { throw new Exception(Languages.Translate("Can`t find DGIndexNV log-file:") + " " + log_file + "\r\n" + Languages.Translate("And can`t determine the source-file.")); } } } #endregion } else { //Довбиваем параметры с помощью FFmpeg ff = new FFInfo(); ff.Open(m.infilepath); //Выходим при отмене if (m == null || worker.CancellationPending) { return; } //Видео if (ff.VideoStreams().Count > 0) { m.invideostream_ff_order = ff.FirstVideoStreamID(); m.invideostream_ff_order_filtered = ff.FilteredStreamOrder(m.invideostream_ff_order); if (m.invideostream_mi_order < 0) { m.invideostream_mi_order = m.invideostream_ff_order; } if (ext == ".avs") { m.invcodec = ff.StreamCodec(m.invideostream_ff_order); m.invcodecshort = ff.StreamCodecShort(m.invideostream_ff_order); m.invbitrate = ff.VideoBitrate(m.invideostream_ff_order); m.inresw = ff.StreamW(m.invideostream_ff_order); m.inresh = ff.StreamH(m.invideostream_ff_order); m.inaspect = (double)m.inresw / (double)m.inresh; } else { //Через MI нашелся только звук, но у FFmpeg есть и видео if (!m.isvideo) { if (ext != ".cda") { m.isvideo = true; m.invcodec = ff.StreamCodec(m.invideostream_ff_order); m.invcodecshort = ff.StreamCodecShort(m.invideostream_ff_order); m.invbitrate = ff.VideoBitrate(m.invideostream_ff_order); m.inresw = ff.StreamW(m.invideostream_ff_order); m.inresh = ff.StreamH(m.invideostream_ff_order); double sar = ff.CalculateSAR(m.invideostream_ff_order); m.pixelaspect = (sar != 0) ? sar : 1.0; double dar = ff.CalculateDAR(m.invideostream_ff_order); m.inaspect = (dar != 0) ? dar : ((double)m.inresw / (double)m.inresh); //Обнуляем аудио пути (там сейчас вписан сам исходник и декодер под его расширение) foreach (AudioStream stream in m.inaudiostreams) { stream.audiopath = null; stream.audiofiles = null; stream.decoder = 0; } } } else if (Settings.UseFFmpegAR) { double sar = ff.CalculateSAR(m.invideostream_ff_order); if (sar != 0) { m.pixelaspect = sar; } double dar = ff.CalculateDAR(m.invideostream_ff_order); if (dar != 0) { m.inaspect = dar; } } } //null - MediaInfo для этого файла не запускалась (avs, grf,..) //"" - MediaInfo запускалась, но нужной инфы получить не удалось //При null тут все-же можно определить fps для avs, но т.к. FFmpeg //сильно округляет fps, то лучше сами позже определим его в Caching(). if (m.inframerate == "") { m.inframerate = ff.StreamFramerate(m.invideostream_ff_order); if (m.inframerate != "") { m.induration = ff.Duration(); m.outduration = m.induration; m.inframes = (int)(m.induration.TotalSeconds * Calculate.ConvertStringToDouble(m.inframerate)); } } } //Аудио if (ff.AudioStreams().Count > 0) { ArrayList AStreams = ff.AudioStreams(); ArrayList AStreams_done = new ArrayList(); //подправляем кодек, ffID, язык //Это будет работать как надо, только если очерёдность наших треков //совпадает с их очерёдностью в FFmpeg, иначе инфа о треках перепутается! int astream = 0; foreach (AudioStream stream in m.inaudiostreams) { stream.ff_order = (int)AStreams[astream]; //ID трека для FFmpeg stream.ff_order_filtered = ff.FilteredStreamOrder(stream.ff_order); if (stream.mi_order < 0) { stream.mi_order = stream.ff_order; } if (stream.bitrate == 0) { stream.bitrate = ff.AudioBitrate(stream.ff_order); } if (stream.channels == 0) { stream.channels = ff.StreamChannels(stream.ff_order); } if (stream.samplerate == null) { stream.samplerate = ff.StreamSamplerate(stream.ff_order); } if (stream.language == "Unknown") { stream.language = ff.StreamLanguage(stream.ff_order); } stream.ff_bits = ff.StreamBits(stream.ff_order); stream.ff_codec = ff.StreamCodec(stream.ff_order); if (stream.codec == "A_MS/ACM" || stream.codec == "") { stream.codec = stream.ff_codec; stream.codecshort = ff.StreamCodecShort(stream.ff_order); } AStreams_done.Add(AStreams[astream]); astream++; if (astream >= AStreams.Count) { break; } } //Удаляем все FF-треки, инфа от которых уже взята foreach (object obj in AStreams_done) { AStreams.Remove(obj); } //Еще раз перепроверка для звуковых файлов (файл без видео), если //выше через MI это не отловилось (т.е. через MI звук не обнаружился) bool is_audio_only = (m.isvideo && string.IsNullOrEmpty(m.inframerate) && string.IsNullOrEmpty(m.invcodec) && (m.inresw == 0 || m.inresh == 0) && ff.VideoStreams().Count == 0); if ((m.indexfile == null && Settings.EnableAudio || ext == ".avs" || is_audio_only) && AStreams.Count > 0) { //забиваем аудио, если они ещё не забиты (если FF-треков осталось больше, чем у нас уже есть) //Все оставшиеся треки от FFmpeg добавляются к уже имеющимся. Тут тоже нужно как-то //сопоставлять треки, и объединить это всё с кодом, который выше! foreach (int stream_num in AStreams) { AudioStream stream = new AudioStream(); stream.ff_bits = ff.StreamBits(stream_num); stream.ff_codec = stream.codec = ff.StreamCodec(stream_num); stream.codecshort = ff.StreamCodecShort(stream_num); stream.bitrate = ff.AudioBitrate(stream_num); stream.samplerate = ff.StreamSamplerate(stream_num); stream.bits = ff.StreamBits(stream_num); stream.channels = ff.StreamChannels(stream_num); stream.language = ff.StreamLanguage(stream_num); stream.mi_order = stream.ff_order = stream_num; stream.ff_order_filtered = ff.FilteredStreamOrder(stream_num); if (is_audio_only) { m.isvideo = false; stream.audiopath = m.infilepath; stream.audiofiles = new string[] { stream.audiopath }; stream = Format.GetValidADecoder(stream); } m.inaudiostreams.Add(stream.Clone()); } m.inaudiostream = 0; } } //Закрываем FFInfo CloseFFInfo(); } if (!m.isvideo) { m.invcodec = m.invcodecshort = "NONE"; m.inframerate = m.outframerate = "25.000"; m.vdecoder = AviSynthScripting.Decoders.BlankClip; //Кол-во кадров и продолжительность определятся в Caching() //на основе реальной продолжительности звука от декодера m.induration = m.outduration = TimeSpan.Zero; m.inframes = m.outframes = 0; } //определяем аудио декодер foreach (AudioStream stream in m.inaudiostreams) { if (stream.decoder == 0) { stream.decoder = Format.GetValidADecoder(stream).decoder; } } //подсчитываем размер long sizeb = 0; foreach (string f in m.infileslist) { FileInfo info = new FileInfo(f); sizeb += info.Length; } m.infilesize = Calculate.ConvertDoubleToPointString((double)sizeb / 1049511, 1) + " mb"; m.infilesizeint = (int)((double)sizeb / 1049511); } catch (Exception ex) { if (worker != null && !worker.CancellationPending && m != null && num_closes == 0) { //Ошибка e.Result = ex; } m = null; } }
private void MainFormLoader() { if (!Application.Current.Dispatcher.CheckAccess()) Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new MainFormLoaderDelegate(MainFormLoader)); else { try { // If we have ANY file open, close it and shut down DirectShow if (this.currentState != PlayState.Init) CloseClip(); if (isInfoLoading) { string info = ""; double maximum = 0; double titleduration = 0.0; int index_of_maximum = 0; int num = 0; //забиваем длительность foreach (object obj in dvd) { string[] titles = (string[])obj; string ifopath = Calculate.GetIFO(titles[0]); if (File.Exists(ifopath)) { //получаем информацию из ифо VStripWrapper vs = new VStripWrapper(); vs.Open(ifopath); titleduration = vs.Duration().TotalSeconds; info = vs.GetVideoInfo(); vs.Close(); string titlenum = Calculate.GetTitleNum(titles[0]); combo_titles.Items.Add("T" + titlenum + " " + info + " " + Calculate.GetTimeline(titleduration) + " - " + titles.Length + " file(s)"); } else { //метод если нет IFO (через DS) info = ""; bool first = true, error = false; foreach (string tilte in titles) { try { int hr = 0; this.graphBuilder = (IGraphBuilder)new FilterGraph(); // Have the graph builder construct its the appropriate graph automatically hr = this.graphBuilder.RenderFile(tilte, null); DsError.ThrowExceptionForHR(hr); //определяем различные параметры if (first) { int resw, resh; double AvgTimePerFrame; this.basicVideo = this.graphBuilder as IBasicVideo; hr = basicVideo.get_SourceWidth(out resw); DsError.ThrowExceptionForHR(hr); hr = basicVideo.get_SourceHeight(out resh); DsError.ThrowExceptionForHR(hr); hr = basicVideo.get_AvgTimePerFrame(out AvgTimePerFrame); DsError.ThrowExceptionForHR(hr); double framerate = 1 / AvgTimePerFrame; string system = (framerate == 25.0 || framerate == 50.0) ? "PAL" : "NTSC"; info = resw + "x" + resh + " " + system; first = false; } //определяем длительность double cduration = 0.0; this.mediaPosition = (IMediaPosition)this.graphBuilder; hr = mediaPosition.get_Duration(out cduration); DsError.ThrowExceptionForHR(hr); titleduration += cduration; } catch (Exception) { error = true; } finally { //освобождаем ресурсы CloseInterfaces(); } } string titlenum = Calculate.GetTitleNum(titles[0]); combo_titles.Items.Add("T" + titlenum + " " + info + " " + Calculate.GetTimeline(titleduration) + (error ? " ERROR" : "") + " - " + titles.Length + " file(s)"); } //Ищем самый продолжительный титл if (titleduration > maximum) { maximum = titleduration; index_of_maximum = num; } num += 1; } combo_titles.Items.RemoveAt(0); combo_titles.SelectedIndex = index_of_maximum; this.isInfoLoading = false; } string[] deftitles = (string[])dvd[combo_titles.SelectedIndex]; if (combo_vob.Tag == null) { //Загружаем титл, выбираем первый воб combo_vob.Items.Clear(); foreach (string vob in deftitles) combo_vob.Items.Add(Path.GetFileName(vob).ToUpper()); combo_vob.SelectedIndex = 0; this.filepath = deftitles[0]; string title_s = Calculate.GetTitleNum(this.filepath); textbox_name.Text = Calculate.GetDVDName(this.filepath) + " T" + title_s; m.infilepath = this.filepath; m.infileslist = deftitles; } else { //Выбираем конкретный воб (только для показа в этом окне) this.filepath = deftitles[(int)combo_vob.Tag]; combo_vob.Tag = null; //При ошибке могло сброситься string title_s = Calculate.GetTitleNum(this.filepath); textbox_name.Text = Calculate.GetDVDName(this.filepath) + " T" + title_s; } //Определяем аспект для плейера (чтоб не вызывать еще раз MediaInfo) string aspect = Calculate.GetRegexValue(@"\s(\d+:\d+)\s", combo_titles.SelectedItem.ToString()); if (!string.IsNullOrEmpty(aspect)) { if (aspect == "4:3") in_ar = 4.0 / 3.0; else if (aspect == "16:9") in_ar = 16.0 / 9.0; else if (aspect == "2.2:1") in_ar = 2.21; } // Reset status variables this.IsAudioOnly = true; this.currentState = PlayState.Stopped; // Start playing the media file if (Settings.PlayerEngine != Settings.PlayerEngines.MediaBridge) PlayMovieInWindow(this.filepath); else PlayWithMediaBridge(this.filepath); this.Focus(); } catch (Exception ex) { CloseClip(); this.filepath = String.Empty; textbox_name.Text = Languages.Translate("Error") + "..."; ErrorException(((isInfoLoading) ? "SortingTitles: " : "PlaySelectedVOB: ") + ex.Message, ex.StackTrace); } } }