コード例 #1
0
 internal ConvertProcess(string filename, string newExtension, ConvertProgress convertProgress)
     :
     base("ffmpeg",
          $"-i \"{filename}\" \"{Path.ChangeExtension(filename, newExtension)}\"",
          ParameterMonitorings)
 {
     _filename        = filename;
     _convertProgress = convertProgress;
 }
コード例 #2
0
        /// <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);
        }
コード例 #3
0
 public void Initialise(IVideoViewModel videoViewModel, ConvertProcess process, ConvertProgress convertProgress)
 {
     Initialise(videoViewModel, process);
     ConvertProgress = convertProgress;
 }
コード例 #4
0
        public IConvertProcessViewModel MakeConvertProcessViewModel(IVideoViewModel videoViewModel, ConvertProcess process, ConvertProgress progress)
        {
            IConvertProcessViewModel convertProcessViewModel = IoC.Get <IConvertProcessViewModel>();

            convertProcessViewModel.Initialise(videoViewModel, process, progress);

            return(convertProcessViewModel);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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()));
        }
コード例 #7
0
 private void ReadingProgress(long arg1, long arg2)
 {
     ConvertProgress?.Invoke(arg1, arg2);
 }