internal ConvertProcess(string filename, string newExtension, ConvertProgress convertProgress) : base("ffmpeg", $"-i \"{filename}\" \"{Path.ChangeExtension(filename, newExtension)}\"", ParameterMonitorings) { _filename = filename; _convertProgress = convertProgress; }
/// <summary> /// Декодируем файлы сохранений /// </summary> /// <param name="moveOriginal">Флаг переноса оригинальных файлов</param> /// <param name="path">Путь для поиска webp файлов</param> /// <returns>True - запуск успешен. False - папка не найдена.</returns> public bool DecodeFiles(string path, bool moveOriginal) { bool ex = false; //Если папка действительно существует if (Directory.Exists(path)) { //Папка успешно получена ex = true; //Запускаем работу в отдельном потоке new Thread(() => { //Обнуляем количество сконвертированных файлов int converted = 1; //Инициализируем информацию о директории DirectoryInfo di = new DirectoryInfo(path); //Получаем список *.webp файлов в директории List <FileInfo> FileList = di.GetFiles("*.webp").ToList(); //Проходимся по всем файлам директории foreach (var file in FileList) { //Выполняем операции над файлом FileWork(file, moveOriginal); //Если работа была отменена if (!isWork) { //Выходим из цикла break; } //Вызываем ивент обновления ConvertProgress?.Invoke(converted++, FileList.Count); } //Если работа всё ещё идёт if (isWork) { //Открываем папку Process.Start(savePath); //Вызываем ивент завершения конвертации ConvertComplete?.Invoke(); } }).Start(); } return(ex); }
public void Initialise(IVideoViewModel videoViewModel, ConvertProcess process, ConvertProgress convertProgress) { Initialise(videoViewModel, process); ConvertProgress = convertProgress; }
public IConvertProcessViewModel MakeConvertProcessViewModel(IVideoViewModel videoViewModel, ConvertProcess process, ConvertProgress progress) { IConvertProcessViewModel convertProcessViewModel = IoC.Get <IConvertProcessViewModel>(); convertProcessViewModel.Initialise(videoViewModel, process, progress); return(convertProcessViewModel); }
void BeginConvert() { FFmpegEncoder encoder = CreateEncoder(); if (encoder == null) { return; } if (fileListBox.Items.Count <= 0) { MessageBox.Show(this, "The list of files to convert is empty.", "No Files", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } InputFile[] files = fileListBox.Items .OfType <InputFile>() .ToArray(); bool saveLog = saveLogCheck.Checked; BackgroundWorker worker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true, }; ProgressDialog progressDialog = new ProgressDialog { TotalFiles = files.Length, Worker = worker, }; Log log = new Log(); Log errorLog = new Log(); string error = null; bool critical = false; bool runErrors = false; worker.DoWork += (sender, e) => { DateTime startTime = DateTime.Now; if (saveLog) { log.OpenFile(String.Format( "{0}{1}Yaffmi Log {2:yyyy'.'MM'.'dd HH'.'mm'.'ss}.txt", encoder.OutputFolder, Path.DirectorySeparatorChar, startTime)); if (!log.FileIsOpen) { error = String.Format("Could not save \"{0}\".", log.FilePath); critical = true; return; } } log.WriteLine(Settings.Title); log.WriteLine("Start time: {0:G}", startTime); log.WriteLine("FFmpeg path: {0}", encoder.FFmpegPath); log.WriteLine("Output directory: {0}", encoder.OutputFolder); log.WriteLine(); int fileCtr = 0; foreach (InputFile file in files) { DateTime fileStartTime = DateTime.Now; int tempFileCtr = fileCtr; log.WriteLine("Item {0} of {1}", tempFileCtr + 1, files.Length); log.WriteLine("Item start time: {0:G}", fileStartTime); FFmpegOperation operation = encoder.BeginEncode(file.FilePath); log.WriteLine("Input file: {0}", operation.InputFilePath); log.WriteLine("Output file: {0}", operation.OutputFilePath); log.WriteLine("Command: \"{0}\" {1}", operation.FFmpegPath, operation.Arguments); if (operation.Status != FFmpegOperationStatus.ProcessStartError) { operation.ProgressChanged += (operation_sender, operation_e) => worker.ReportProgress(0, new ConvertProgress(tempFileCtr, // Don't let it hit 100% until we are done (operation.Progress < 0.994) ? operation.Progress : 0.994)); operation.BeginStatusReporting(); // This seems kind of ugly, but BackgroundWorker doesn't expose any other method of // detecting cancelations besides polling CancellationPending while (true) { if (worker.CancellationPending) { operation.Cancel(); operation.WaitForFinish(); break; } if (operation.WaitForFinish(15)) { break; } } } DateTime fileEndTime = DateTime.Now; foreach (string line in operation.Log) { log.WriteLine("> {0}", line); } log.WriteLine("Result: {0}", operation.Status); log.WriteLine("Item end time: {0:G}", fileEndTime); log.WriteLine(); if (worker.CancellationPending) { break; } // If the first file fails before processing starts, don't try to keep going if (!Settings.NeverAbortOnError && tempFileCtr == 0 && (operation.Status == FFmpegOperationStatus.ProcessStartError || operation.Status == FFmpegOperationStatus.InitializationError)) { error = operation.Error; critical = operation.Status == FFmpegOperationStatus.ProcessStartError; break; } // If something fails later on, log it and continue if (operation.Status != FFmpegOperationStatus.Success) { // If we don't have a log file yet, create an error log if (!log.FileIsOpen && !errorLog.FileIsOpen) { errorLog.OpenFile(String.Format( "{0}{1}Yaffmi Errors {2:yyyy'.'MM'.'dd HH'.'mm'.'ss}.txt", encoder.OutputFolder, Path.DirectorySeparatorChar, startTime)); errorLog.WriteLine(Settings.Title); errorLog.WriteLine("Error log"); errorLog.WriteLine(); } errorLog.WriteLine("Item {0} of {1}", tempFileCtr + 1, files.Length); errorLog.WriteLine("Input file: {0}", operation.InputFilePath); errorLog.WriteLine("Error: {0}", operation.Error); errorLog.WriteLine(); runErrors = true; } worker.ReportProgress(0, new ConvertProgress(tempFileCtr, 1)); fileCtr++; } DateTime endTime = DateTime.Now; errorLog.CloseFile(); log.WriteLine("Yaffmi finished."); log.WriteLine("End time: {0:G}", endTime); log.CloseFile(); }; worker.ProgressChanged += (sender, e) => { ConvertProgress progress = (ConvertProgress)e.UserState; progressDialog.CurrentFile = progress.FileCtr + 1; progressDialog.CurrentFileProgress = progress.FileProgress; }; worker.RunWorkerCompleted += (sender, e) => { progressDialog.Finished = true; if (error != null) { progressDialog.Close(); MessageBox.Show(this, error, "Convert Error", MessageBoxButtons.OK, (critical) ? MessageBoxIcon.Error : MessageBoxIcon.Warning); return; } if (runErrors) { if ((errorLog.FilePath != null && errorLog.GetLastError(false) == null) || (log.FilePath != null && log.GetLastError(false) == null)) { MessageBox.Show(this, String.Format( "One or more files were not converted successfully. See \"{0}\" in the output folder for more information.", Path.GetFileName(errorLog.FilePath ?? log.FilePath)), "Convert Errors", MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { MessageBox.Show(this, "One or more files were not converted successfully. There was a problem creating files in the output folder.", "Convert Errors", MessageBoxButtons.OK, MessageBoxIcon.Error); } } }; progressDialog.ShowDialog(this); }
public void Dispatch(IViewModelBase viewModel) { ProcessTransferType nextTransfer; IProcessViewModel dispatch; void DispatchToDownload(IVideoViewModel videoViewModel) { nextTransfer = ProcessTransferType.Download; dispatch = _processFactory.MakeDownloadProcessViewModel(videoViewModel); } void DispatchToComplete(IVideoViewModel videoViewModel, DownloadState downloadState) { nextTransfer = ProcessTransferType.Complete; dispatch = _processFactory.MakeCompleteProcessViewModel(videoViewModel, downloadState); } switch (viewModel) { case IVideoViewModel videoViewModel: { string videoTitle = videoViewModel.Video.Title; if (Directory.GetFiles(_settings.DownloadPath).Select(Path.GetFileNameWithoutExtension).Any(filename => filename == videoTitle)) { DispatchToComplete(videoViewModel, DownloadState.Exited); } else { DispatchToDownload(videoViewModel); } } break; case IDownloadProcessViewModel downloadProcessViewModel: { if (downloadProcessViewModel.Process.Killed) { DispatchToComplete(downloadProcessViewModel.VideoViewModel, DownloadState.Exited); break; } string destinationFilename = (string)downloadProcessViewModel.Process.ProcessMonitor.ParameterMonitorings["Destination"].Value; FileInfo fileInfo = new FileInfo(destinationFilename); if (_settings.OutputFormat == OutputFormat.Auto || _settings.OutputFormat == OutputFormat.Mp4 && fileInfo.Extension == ".mp4" || _settings.OutputFormat == OutputFormat.Mp3 && fileInfo.Extension == ".mp3") { DispatchToComplete(downloadProcessViewModel.VideoViewModel, DownloadState.Completed); } else { nextTransfer = ProcessTransferType.Convert; ConvertProgress convertProgress = new ConvertProgress(fileInfo.Length); ConvertProcess convertProcess = new ConvertProcess(fileInfo.FullName, _settings.OutputFormat.ToString().ToLower(), convertProgress); dispatch = _processFactory.MakeConvertProcessViewModel(downloadProcessViewModel.VideoViewModel, convertProcess, convertProgress); } } break; case IConvertProcessViewModel convertProcessViewModel: DispatchToComplete(convertProcessViewModel.VideoViewModel, convertProcessViewModel.Process.Killed ? DownloadState.Exited : DownloadState.Completed); break; default: throw new InvalidOperationException("Cannot dispatch non-download or non-convert process."); } if (dispatch is IActiveProcessViewModel activeProcessViewModel) { void ProcessStarted(object sender, EventArgs e) { switch (dispatch) { case IDownloadProcessViewModel _: dispatch.DownloadState = DownloadState.Downloading; break; case IConvertProcessViewModel _: dispatch.DownloadState = DownloadState.Converting; break; } } void ProcessExited(object sender, EventArgs e) { activeProcessViewModel.Process.Started -= ProcessStarted; activeProcessViewModel.Process.Exited -= ProcessExited; } activeProcessViewModel.Process.Started += ProcessStarted; activeProcessViewModel.Process.Exited += ProcessExited; } _eventAggregator.BeginPublishOnUIThread(new ProcessTransferMessage(nextTransfer, dispatch.ToEnumerable())); }
private void ReadingProgress(long arg1, long arg2) { ConvertProgress?.Invoke(arg1, arg2); }