//начало открытия файла private void action_open(Massive x) { try { if (x == null) return; //Если AviSynth не был найден при старте и не был установлен после него if (SysInfo.AVSVersionFloat == 0 && !SysInfo.RetrieveAviSynthInfo()) { throw new Exception(Languages.Translate("AviSynth is not found!") + "\r\n" + Languages.Translate("Please install AviSynth 2.5.7 MT or higher.")); } string ext = Path.GetExtension(x.infilepath).ToLower(); //Уводим фокус с комбобоксов куда-нибудь! if (!slider_pos.Focus()) slider_Volume.Focus(); //Проверка на "нехорошие" символы в путях if (ext != ".tsks" && !Calculate.ValidatePath(x.infilepath, !IsBatchOpening)) return; //Закрываем уже открытый файл; обнуляем трим и его кнопки if (!IsBatchOpening && m != null) CloseFile(false); else ResetTrim(); //Загружаем сохраненные задания if (ext == ".tsks") { RestoreTasks(x.infilepath, ref x); //Выходим при ошибке или если были только одни задания; //если был и массив, то открываем его if (x == null) return; else m = x.Clone(); x = null; LoadVideoPresets(); if (m.outaudiostreams.Count > 0) { AudioStream outstream = (AudioStream)m.outaudiostreams[m.outaudiostream]; LoadAudioPresets(); combo_aencoding.SelectedItem = outstream.encoding; Settings.SetAEncodingPreset(m.format, outstream.encoding); } else { combo_aencoding.SelectedItem = "Disabled"; } combo_format.SelectedItem = Format.EnumToString(Settings.FormatOut = m.format); combo_sbc.SelectedItem = Settings.SBC = m.sbc; combo_filtering.SelectedValue = Settings.Filtering = m.filtering; combo_vencoding.SelectedItem = m.vencoding; Settings.SetVEncodingPreset(m.format, m.vencoding); goto finish; } //Определяем, где создавать индекс-файлы для FFmpegSource2 + занесение их в список на удаление if (!(x.ffms_indexintemp = (Settings.FFMS_IndexInTemp || Calculate.IsReadOnly(x.infilepath)))) { foreach (string file in x.infileslist) { if (!ffcache.Contains(file + ".ffindex")) ffcache.Add(file + ".ffindex"); } } //Возможные индекс-файлы от LSMASH foreach (string file in x.infileslist) { if (!lsmashcache.Contains(file + ".lwi")) lsmashcache.Add(file + ".lwi"); } //присваиваем заданию уникальный ключ if (Settings.Key == "9999") Settings.Key = "0000"; x.key = Settings.Key; //имя if (x.taskname == null) x.taskname = Path.GetFileNameWithoutExtension(x.infilepath); //забиваем основные параметры кодирования x.format = Settings.FormatOut; x.sbc = Settings.SBC; x = ColorCorrection.DecodeProfile(x); x.filtering = Settings.Filtering; x.resizefilter = Settings.ResizeFilter; //Звук для d2v, dga и dgi файлов if (ext == ".d2v" || ext == ".dga" || ext == ".dgi") { x.indexfile = x.infilepath; ArrayList atracks = Indexing.GetTracks(x.indexfile); int n = 0; if (atracks.Count > 0 && Settings.EnableAudio) { foreach (string apath in atracks) { //забиваем в список все найденные треки MediaInfoWrapper mi = new MediaInfoWrapper(); AudioStream stream = mi.GetAudioInfoFromAFile(apath, true); stream.delay = Calculate.GetDelay(apath); x.inaudiostreams.Add(stream.Clone()); n++; } x.inaudiostream = 0; } } //блок для файлов с обязательной разборкой if (ext == ".dpg") { x.invcodecshort = "MPEG1"; string outext = Format.GetValidRAWVideoEXT(x); string vpath = Settings.TempPath + "\\" + x.key + "." + outext; string apath = Settings.TempPath + "\\" + x.key + "_0.mp2"; //удаляем старый файл SafeDelete(vpath); SafeDelete(apath); //извлекаем новый файл Demuxer dem = new Demuxer(x, Demuxer.DemuxerMode.ExtractVideo, vpath); if (!dem.IsErrors && Settings.EnableAudio) dem = new Demuxer(x, Demuxer.DemuxerMode.ExtractAudio, apath); //проверка на удачное завершение if (File.Exists(vpath) && new FileInfo(vpath).Length != 0) { x.infilepath_source = x.infilepath; x.infilepath = vpath; x.infileslist = new string[] { x.infilepath }; deletefiles.Add(vpath); } //проверка на удачное завершение if (File.Exists(apath) && new FileInfo(apath).Length != 0) { AudioStream stream = new AudioStream(); stream.audiopath = apath; stream.audiofiles = new string[] { apath }; stream = Format.GetValidADecoder(stream); x.inaudiostreams.Add(stream.Clone()); x.inaudiostream = 0; deletefiles.Add(apath); } } //Имя для DVD if (Calculate.IsValidVOBName(x.infilepath)) { x.dvdname = Calculate.GetDVDName(x.infilepath); string title = Calculate.GetTitleNum(x.infilepath); if (!string.IsNullOrEmpty(title)) title = "_T" + title; x.taskname = x.dvdname + title; } //Определяем видеодекодер (#1) x.vdecoder = Format.GetValidVDecoder(x); //Проверка необходимости индексации для DGIndex\DGIndexNV if (x.vdecoder == AviSynthScripting.Decoders.MPEG2Source && ext != ".d2v" || x.vdecoder == AviSynthScripting.Decoders.DGSource && ext != ".dgi") { if (x.vdecoder == AviSynthScripting.Decoders.MPEG2Source) { //Проверяем индекс папку (проверка содержимого файла для DGIndex - если там MPEG1\2, то можно индексировать; тут-же идет запуск MediaInfo) IndexChecker ich = new IndexChecker(x, false); if (ich.m == null) return; x = ich.m.Clone(); if (x.indexfile != null) { //Индексация DGIndex if (!File.Exists(x.indexfile)) { Indexing index = new Indexing(x); if (index.m == null) return; x = index.m.Clone(); } //Добавление кэш-файла в список на удаление if (!dgcache.Contains(x.indexfile) && Path.GetDirectoryName(x.indexfile).EndsWith(".index") && x.indexfile != x.infilepath) dgcache.Add(x.indexfile); } else if (x.vdecoder == 0) { //Определяем видеодекодер (#2) //Файл распознался, как MPEG-PS\TS, но внутри оказался не MPEG1\2, поэтому декодер обнулился. //Вторая попытка - на случай, если для "другие файлы" выбран DGSource. x.vdecoder = Format.GetValidVDecoder(x); } } if (x.vdecoder == AviSynthScripting.Decoders.DGSource) { //Проверяем индекс папку IndexChecker ich = new IndexChecker(x, true); if (ich.m == null) return; x = ich.m.Clone(); if (x.indexfile != null) { //Индексация DGIndexNV if (!File.Exists(x.indexfile)) { Indexing_DGIndexNV index = new Indexing_DGIndexNV(x); if (index.m == null) return; x = index.m.Clone(); } //Добавление кэш-файла в список на удаление if (!dgcacheNV.Contains(x.indexfile) && Path.GetDirectoryName(x.indexfile).EndsWith(".idxNV") && x.indexfile != x.infilepath) dgcacheNV.Add(x.indexfile); } } } //получаем информацию через MediaInfo if (ext != ".vdr") { Informer info = new Informer(x); if (info.m == null) return; x = info.m.Clone(); } //Определяем видеодекодер (#3), т.к. выше он мог обнулиться if (x.vdecoder == 0) x.vdecoder = Format.GetValidVDecoder(x); //принудительный фикс цвета для DVD if (Settings.AutoColorMatrix && x.format != Format.ExportFormats.Audio) { if (x.iscolormatrix == false && x.invcodecshort == "MPEG2") { x.iscolormatrix = true; if (combo_sbc.Items.Contains("MPEG2Fix") && Settings.SBC == "Disabled") combo_sbc.SelectedItem = "MPEG2Fix"; } } //похоже что к нам идёт звковой файл if (x.format != Format.ExportFormats.Audio && !x.isvideo) { Settings.FormatOut = x.format = Format.ExportFormats.Audio; combo_format.SelectedItem = Format.EnumToString(Format.ExportFormats.Audio); LoadAudioPresets(); SetAudioPreset(); } //Индексация для FFmpegSource2 if (x.vdecoder == AviSynthScripting.Decoders.FFmpegSource2) { Indexing_FFMS ffindex = new Indexing_FFMS(x); if (ffindex.m == null) return; } if (x.inaudiostreams.Count > 0 && Settings.EnableAudio) { //Автовыбор трека if (x.inaudiostreams.Count > 1) { if (Settings.DefaultATrackMode == Settings.ATrackModes.Language) { //По языку for (int i = 0; i < x.inaudiostreams.Count; i++) { if (((AudioStream)x.inaudiostreams[i]).language.ToLower() == Settings.DefaultATrackLang.ToLower()) { x.inaudiostream = i; break; } } } else if (Settings.DefaultATrackMode == Settings.ATrackModes.Number) { //По номеру x.inaudiostream = Settings.DefaultATrackNum - 1; if (x.inaudiostream >= x.inaudiostreams.Count) x.inaudiostream = 0; } AudioStream instream = (AudioStream)x.inaudiostreams[x.inaudiostream]; //Требуется извлечение звука if (instream.audiopath == null && instream.decoder == 0 && x.inaudiostream > 0) { //FFMS2 и LSMASH умеют переключать треки, для них их можно не извлекать if (!(x.vdecoder == AviSynthScripting.Decoders.FFmpegSource2 && Settings.FFMS_Enable_Audio || ((x.vdecoder == AviSynthScripting.Decoders.LSMASHVideoSource || x.vdecoder == AviSynthScripting.Decoders.LWLibavVideoSource) && Settings.LSMASH_Enable_Audio))) { string outext = Format.GetValidRAWAudioEXT(instream.codecshort); instream.audiopath = Settings.TempPath + "\\" + x.key + "_" + x.inaudiostream + outext; instream.audiofiles = new string[] { instream.audiopath }; instream = Format.GetValidADecoder(instream); } } } //Извлечение звука (если запрещено прямое декодирование из исходника, декодер этого не умеет или это автовыбор трека) if (x.vdecoder == AviSynthScripting.Decoders.FFmpegSource2 && !Settings.FFMS_Enable_Audio || x.vdecoder == AviSynthScripting.Decoders.DirectShowSource && !Settings.DSS_Enable_Audio || (x.vdecoder == AviSynthScripting.Decoders.LSMASHVideoSource || x.vdecoder == AviSynthScripting.Decoders.LWLibavVideoSource) && !Settings.LSMASH_Enable_Audio || x.vdecoder == AviSynthScripting.Decoders.DirectShowSource2 || ((AudioStream)x.inaudiostreams[x.inaudiostream]).audiopath != null && x.isvideo) { AudioStream instream = (AudioStream)x.inaudiostreams[x.inaudiostream]; if (instream.audiopath == null || !File.Exists(instream.audiopath)) { string outpath = (instream.audiopath == null) ? Settings.TempPath + "\\" + x.key + "_" + x.inaudiostream + Format.GetValidRAWAudioEXT(instream.codecshort) : instream.audiopath; //удаляем старый файл SafeDelete(outpath); //извлекаем новый файл if (Path.GetExtension(outpath) == ".wav") { Decoder dec = new Decoder(x, Decoder.DecoderModes.DecodeAudio, outpath); if (dec.IsErrors) throw new Exception("Decode to WAV: " + dec.error_message); } else { Demuxer dem = new Demuxer(x, Demuxer.DemuxerMode.ExtractAudio, outpath); if (dem.IsErrors) throw new Exception(dem.error_message); } //проверка на удачное завершение if (File.Exists(outpath) && new FileInfo(outpath).Length != 0) { instream.audiopath = outpath; instream.audiofiles = new string[] { outpath }; instream = Format.GetValidADecoder(instream); deletefiles.Add(outpath); } } } } //получаем выходной фреймрейт x = Format.GetValidFramerate(x); x = Calculate.UpdateOutFrames(x); //Получаем информацию через AviSynth и ловим ошибки Caching cach = new Caching(x, false); if (cach.m == null) return; x = cach.m.Clone(); //забиваем-обновляем аудио массивы x = FillAudio(x); //выбираем трек if (x.inaudiostreams.Count > 1 && Settings.EnableAudio && Settings.DefaultATrackMode == Settings.ATrackModes.Manual) { AudioOptions ao = new AudioOptions(x, this, AudioOptions.AudioOptionsModes.TracksOnly); if (ao.m == null) return; x = ao.m.Clone(); } //извлечение трека при badmixing if (x.inaudiostreams.Count == 1 && Settings.EnableAudio) { AudioStream instream = (AudioStream)x.inaudiostreams[x.inaudiostream]; if (instream.badmixing) { string outext = Format.GetValidRAWAudioEXT(instream.codecshort); instream.audiopath = Settings.TempPath + "\\" + x.key + "_" + x.inaudiostream + outext; instream.audiofiles = new string[] { instream.audiopath }; instream = Format.GetValidADecoder(instream); if (!File.Exists(instream.audiopath)) { Demuxer dem = new Demuxer(x, Demuxer.DemuxerMode.ExtractAudio, instream.audiopath); if (dem.IsErrors) throw new Exception(dem.error_message); } } } //забиваем видео настройки if (x.format != Format.ExportFormats.Audio) { x.vencoding = Settings.GetVEncodingPreset(Settings.FormatOut); x.outvcodec = PresetLoader.GetVCodec(x); x.vpasses = PresetLoader.GetVCodecPasses(x); } else { x.vencoding = "Disabled"; x.outvcodec = "Disabled"; x.vpasses.Clear(); combo_vencoding.SelectedItem = x.vencoding; } //забиваем аргументы к кодированию аудио и видео x = PresetLoader.DecodePresets(x); //автоматический деинтерлейс if (x.format != Format.ExportFormats.Audio) { //Клонируем деинтерлейс от предыдущего файла if (IsBatchOpening && m != null && Settings.BatchCloneDeint) { x.interlace = m.interlace; x.fieldOrder = m.fieldOrder; x.deinterlace = m.deinterlace; } else { if (Settings.AutoDeinterlaceMode == Settings.AutoDeinterlaceModes.AllFiles && x.outvcodec != "Copy" || Settings.AutoDeinterlaceMode == Settings.AutoDeinterlaceModes.MPEGs && Calculate.IsMPEG(x.infilepath) && x.outvcodec != "Copy" || Settings.AutoDeinterlaceMode == Settings.AutoDeinterlaceModes.MPEGs && ext == ".evo" && x.outvcodec != "Copy") { if (x.inframerate == "23.976") { x.interlace = SourceType.PROGRESSIVE; x = Format.GetOutInterlace(x); } else { //перепроверяем входной интерлейс SourceDetector sd = new SourceDetector(x); if (sd.m != null) x = sd.m.Clone(); } } else { x = Format.GetOutInterlace(x); } } } //ищем субтитры if (x.format != Format.ExportFormats.Audio) { string subs = Calculate.RemoveExtention(x.infilepath, true); if (File.Exists(subs + ".srt")) x.subtitlepath = subs + ".srt"; if (File.Exists(subs + ".sub")) x.subtitlepath = subs + ".sub"; if (File.Exists(subs + ".idx")) x.subtitlepath = subs + ".idx"; if (File.Exists(subs + ".ssa")) x.subtitlepath = subs + ".ssa"; if (File.Exists(subs + ".ass")) x.subtitlepath = subs + ".ass"; if (File.Exists(subs + ".psb")) x.subtitlepath = subs + ".psb"; if (File.Exists(subs + ".smi")) x.subtitlepath = subs + ".smi"; } //автокроп if (x.format != Format.ExportFormats.Audio) { //Клонируем разрешение от предыдущего файла if (IsBatchOpening && m != null && Settings.BatchCloneAR) { x.outresw = m.outresw; x.outresh = m.outresh; x.cropl = x.cropl_copy = m.cropl; x.cropt = x.cropt_copy = m.cropt; x.cropr = x.cropr_copy = m.cropr; x.cropb = x.cropb_copy = m.cropb; x.blackw = m.blackw; x.blackh = m.blackh; x.flipv = m.flipv; x.fliph = m.fliph; x.outaspect = m.outaspect; x.aspectfix = m.aspectfix; x.sar = m.sar; } else { if (Settings.AutocropMode == Autocrop.AutocropMode.AllFiles && x.outvcodec != "Copy" || Settings.AutocropMode == Autocrop.AutocropMode.MPEGOnly && Calculate.IsMPEG(x.infilepath) && x.outvcodec != "Copy") { if (x.format != Format.ExportFormats.BluRay) { Autocrop acrop = new Autocrop(x, this, -1); if (acrop.m != null) x = acrop.m.Clone(); } } //подправляем входной аспект x = AspectResolution.FixInputAspect(x); //забиваем видео параметры на выход x = Format.GetValidResolution(x); x = Format.GetValidOutAspect(x); x = AspectResolution.FixAspectDifference(x); } //Клонируем частоту кадров от предыдущего файла if (IsBatchOpening && m != null && Settings.BatchCloneFPS) { x.outframerate = m.outframerate; } else { x = Format.GetValidFramerate(x); } //обновление выходных битрейтов if (x.outvcodec == "Disabled") x.outvbitrate = 0; } else { //для звуковых заданий x.outframerate = x.inframerate; x.outresw = x.inresw; x.outresh = x.inresh; x.outaspect = x.inaspect; //обнуляем делей foreach (object o in x.outaudiostreams) { AudioStream s = (AudioStream)o; s.delay = 0; } //запрещаем видео разделы combo_vencoding.IsEnabled = false; button_edit_vencoding.IsEnabled = false; combo_sbc.IsEnabled = false; button_edit_sbc.IsEnabled = false; } //переполучаем параметры из профилей x = PresetLoader.DecodePresets(x); //Клонируем Трим от предыдущего файла if (IsBatchOpening && m != null && Settings.BatchCloneTrim) { x.trims = (ArrayList)m.trims.Clone(); x.trim_is_on = m.trim_is_on; x.trim_num = m.trim_num; } //Пересчитываем кол-во кадров и продолжительность x = Calculate.UpdateOutFrames(x); //создаём AviSynth скрипт x = AviSynthScripting.CreateAutoAviSynthScript(x); //Автогромкость if (x.inaudiostreams.Count > 0) { //определяем громкоcть x.volume = Settings.Volume; if (Settings.Volume != "Disabled" && Settings.AutoVolumeMode == Settings.AutoVolumeModes.OnImport) { Normalize norm = new Normalize(x); if (norm.m != null) { x = norm.m.Clone(); x = AviSynthScripting.CreateAutoAviSynthScript(x); } } } //проверка на размер x.outfilesize = Calculate.GetEncodingSize(x); //запрещаем профиль кодирования если нет звука if (x.inaudiostreams.Count == 0 || x.outaudiostreams.Count == 0) { combo_aencoding.SelectedItem = "Disabled"; } else { if (combo_aencoding.SelectedItem.ToString() == "Disabled") combo_aencoding.SelectedItem = Settings.GetAEncodingPreset(x.format); } //проверяем можно ли копировать данный формат if (x.vencoding == "Copy") { string CopyProblems = Format.ValidateCopyVideo(x); if (CopyProblems != null) { Message mess = new Message(this); mess.ShowMessage(Languages.Translate("The stream contains parameters incompatible with this format") + " " + Format.EnumToString(x.format) + ": " + CopyProblems + "." + Environment.NewLine + Languages.Translate("(You see this message because video encoder = Copy)"), Languages.Translate("Warning")); } } //передаём массив m = x.Clone(); x = null; finish: //снимаем выделение list_tasks.SelectedIndex = -1; //загружаем скрипт в форму if (!IsBatchOpening) { if (!PauseAfterFirst) { //Обновляем список недавно открытых файлов string source = (string.IsNullOrEmpty(m.infilepath_source)) ? m.infilepath : m.infilepath_source; string[] files = Settings.RecentFiles.Split(new string[] { ";" }, StringSplitOptions.None); string output = source + "; "; int items = 1; //Первый - source int count = Settings.RecentFilesCount; for (int i = 0; i < files.Length && items < count; i++) { string file = files[i].Trim(); if (file.Length > 0 && file != source) { output += (file + "; "); items += 1; } } Settings.RecentFiles = output; UpdateRecentFiles(); } LoadVideo(MediaLoad.load); } } catch (Exception ex) { //записываем плохой скрипт if (x != null && x.script != null) AviSynthScripting.WriteScriptToFile(x.script, "error"); x = null; if (ex.Message.Contains("DirectX")) { Message mess = new Message(this); mess.ShowMessage(Languages.Translate("Need update DirectX files! Do it now?"), Languages.Translate("Error"), Message.MessageStyle.YesNo); if (mess.result == Message.Result.Yes) { Process.Start(Calculate.StartupPath + "\\apps\\DirectX_Update\\dxwebsetup.exe"); Close(); } } else ErrorException("LoadFile: " + 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; } }