FFmpegEncoder CreateEncoder()
        {
            FFmpegEncoder encoder = new FFmpegEncoder(Settings.FFmpegPath);

            try
            {
                encoder.FileFormat = fileFormatBox.Text;
                // Must be letters, numbers, and underscores only
                if (!Regex.IsMatch(encoder.FileFormat, @"^\w*$"))
                    throw new ControlValueException(fileFormatBox, "file format");

                encoder.FilenameExtension = fileExtBox.Text
                    .TrimStart('.');
                if (encoder.FilenameExtension.ContainsAny(Path.GetInvalidFileNameChars()))
                    throw new ControlValueException(fileExtBox, "file name extension");

                encoder.OutputFolder = outputFolderBox.Text
                    .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
                if (encoder.OutputFolder.ContainsAny(Path.GetInvalidPathChars()) ||
                    !Path.IsPathRooted(encoder.OutputFolder) ||
                    !Directory.Exists(encoder.OutputFolder))
                    throw new ControlValueException(outputFolderBox, "output folder");

                encoder.IncludeVideo = includeVideoCheck.Checked;
                if (encoder.IncludeVideo)
                {
                    if (!String.IsNullOrEmpty(videoStreamsBox.Text))
                    {
                        encoder.VideoStreams = videoStreamsBox.Text
                            .Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
                            .Select(index =>
                            {
                                int i;
                                if (!Int32.TryParse(index, out i) ||
                                    i < 0)
                                    throw new ControlValueException(videoStreamsBox, "video streams list");
                                return i;
                            })
                            .ToArray();
                    }

                    encoder.VideoCodec = videoCodecBox.Text;
                    // Must be letters, numbers, and underscores only
                    if (!Regex.IsMatch(encoder.VideoCodec, @"^\w*$"))
                        throw new ControlValueException(videoCodecBox, "video codec");

                    if (!String.IsNullOrEmpty(widthBox.Text))
                    {
                        int width;
                        if (!Int32.TryParse(widthBox.Text, out width) ||
                            width <= 0)
                            throw new ControlValueException(widthBox, "video width");
                        encoder.Width = width;
                    }

                    if (!String.IsNullOrEmpty(heightBox.Text))
                    {
                        int height;
                        if (!Int32.TryParse(heightBox.Text, out height) ||
                            height <= 0)
                            throw new ControlValueException(heightBox, "video height");
                        encoder.Height = height;
                    }

                    if (!String.IsNullOrEmpty(videoBitrateBox.Text))
                    {
                        double bitrate;
                        if (!Double.TryParse(videoBitrateBox.Text, out bitrate) ||
                            bitrate <= 0)
                            throw new ControlValueException(videoBitrateBox, "video bitrate");
                        encoder.VideoBitrate = bitrate;
                    }

                    if (!String.IsNullOrEmpty(darBox.Text))
                    {
                        var e = new ControlValueException(darBox, "display aspect ratio");
                        string[] parts = darBox.Text.Split(":/\\".ToCharArray(), 2);
                        double numerator;
                        if (!Double.TryParse(parts[0], out numerator))
                            throw e;
                        encoder.DisplayAspectRatio = numerator;
                        if (parts.Length > 1)
                        {
                            double denominator;
                            if (!Double.TryParse(parts[1], out denominator) ||
                                denominator == 0)
                                throw e;
                            encoder.DisplayAspectRatio /= denominator;
                        }
                        if (encoder.DisplayAspectRatio <= 0)
                            throw e;
                    }

                    if (!String.IsNullOrEmpty(frameRateBox.Text))
                    {
                        double frameRate;
                        if (!Double.TryParse(frameRateBox.Text, out frameRate) ||
                            frameRate <= 0)
                            throw new ControlValueException(frameRateBox, "frame rate");
                        encoder.FrameRate = frameRate;
                    }

                    if (!String.IsNullOrEmpty(topBox.Text))
                    {
                        int top;
                        if (!Int32.TryParse(topBox.Text, out top) ||
                            top < 0)
                            throw new ControlValueException(topBox, "top crop margin");
                        encoder.CropTop = top;
                    }

                    if (!String.IsNullOrEmpty(leftBox.Text))
                    {
                        int left;
                        if (!Int32.TryParse(leftBox.Text, out left) ||
                            left < 0)
                            throw new ControlValueException(leftBox, "left crop margin");
                        encoder.CropLeft = left;
                    }

                    if (!String.IsNullOrEmpty(rightBox.Text))
                    {
                        int right;
                        if (!Int32.TryParse(rightBox.Text, out right) ||
                            right < 0)
                            throw new ControlValueException(rightBox, "right crop margin");
                        encoder.CropRight = right;
                    }

                    if (!String.IsNullOrEmpty(bottomBox.Text))
                    {
                        int bottom;
                        if (!Int32.TryParse(bottomBox.Text, out bottom) ||
                            bottom < 0)
                            throw new ControlValueException(bottomBox, "bottom crop margin");
                        encoder.CropBottom = bottom;
                    }

                    encoder.VideoFilters = videoFiltersBox.Text;
                }

                encoder.IncludeAudio = includeAudioCheck.Checked;
                if (encoder.IncludeAudio)
                {
                    if (!String.IsNullOrEmpty(audioStreamsBox.Text))
                    {
                        encoder.AudioStreams = audioStreamsBox.Text
                            .Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
                            .Select(index =>
                            {
                                int i;
                                if (!Int32.TryParse(index, out i) ||
                                    i < 0)
                                    throw new ControlValueException(audioStreamsBox, "audio streams list");
                                return i;
                            })
                            .ToArray();
                    }

                    encoder.AudioCodec = audioCodecBox.Text;
                    // Must be letters, numbers, and underscores only
                    if (!Regex.IsMatch(encoder.AudioCodec, @"^\w*$"))
                        throw new ControlValueException(audioCodecBox, "audio codec");

                    if (!String.IsNullOrEmpty(audioBitrateBox.Text))
                    {
                        double bitrate;
                        if (!Double.TryParse(audioBitrateBox.Text, out bitrate) ||
                            bitrate <= 0)
                            throw new ControlValueException(audioBitrateBox, "audio bitrate");
                        encoder.AudioBitrate = bitrate;
                    }

                    if (!String.IsNullOrEmpty(channelCountBox.Text))
                    {
                        int channelCount;
                        if (!Int32.TryParse(channelCountBox.Text, out channelCount) ||
                            channelCount <= 0)
                            throw new ControlValueException(channelCountBox, "channel count");
                        encoder.ChannelCount = channelCount;
                    }

                    if (!String.IsNullOrEmpty(sampleRateBox.Text))
                    {
                        double sampleRate;
                        if (!Double.TryParse(sampleRateBox.Text, out sampleRate) ||
                            sampleRate <= 0)
                            throw new ControlValueException(sampleRateBox, "sample rate");
                        encoder.SampleRate = sampleRate;
                    }

                    if (!String.IsNullOrEmpty(volumeBox.Text))
                    {
                        double volume;
                        if (!Double.TryParse(volumeBox.Text, out volume) ||
                            volume < 0 ||
                            // LAME will violently crash if volume is increased too much
                            // Someone should probbably report that
                            volume > 10000000)
                            throw new ControlValueException(volumeBox, "volume");
                        encoder.Volume = volume / 100;
                    }

                    encoder.AudioFilters = audioFiltersBox.Text;
                }

                encoder.IncludeSubtitles = includeSubtitlesCheck.Checked;
                if (encoder.IncludeSubtitles &&
                    !String.IsNullOrEmpty(subtitlesStreamsBox.Text))
                {
                    encoder.SubtitlesStreams = subtitlesStreamsBox.Text
                        .Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
                        .Select(index =>
                        {
                            int i;
                            if (!Int32.TryParse(index, out i) ||
                                i < 0)
                                throw new ControlValueException(subtitlesStreamsBox, "subtitles streams list");
                            return i;
                        })
                        .ToArray();
                }

                encoder.GlobalParams = globalParamsBox.Text;
                encoder.InputParams = inputParamsBox.Text;
                encoder.OutputParams = outputParamsBox.Text;
            }
            catch (ControlValueException e)
            {
                e.Focus();
                e.ShowMessage(this);

                return null;
            }

            return encoder;
        }
Example #2
0
        FFmpegEncoder CreateEncoder()
        {
            FFmpegEncoder encoder = new FFmpegEncoder(Settings.FFmpegPath);

            try
            {
                encoder.FileFormat = fileFormatBox.Text;
                // Must be letters, numbers, and underscores only
                if (!Regex.IsMatch(encoder.FileFormat, @"^\w*$"))
                {
                    throw new ControlValueException(fileFormatBox, "file format");
                }

                encoder.FilenameExtension = fileExtBox.Text
                                            .TrimStart('.');
                if (encoder.FilenameExtension.ContainsAny(Path.GetInvalidFileNameChars()))
                {
                    throw new ControlValueException(fileExtBox, "file name extension");
                }

                encoder.OutputFolder = outputFolderBox.Text
                                       .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
                if (encoder.OutputFolder.ContainsAny(Path.GetInvalidPathChars()) ||
                    !Path.IsPathRooted(encoder.OutputFolder) ||
                    !Directory.Exists(encoder.OutputFolder))
                {
                    throw new ControlValueException(outputFolderBox, "output folder");
                }

                encoder.IncludeVideo = includeVideoCheck.Checked;
                if (encoder.IncludeVideo)
                {
                    if (!String.IsNullOrEmpty(videoStreamsBox.Text))
                    {
                        encoder.VideoStreams = videoStreamsBox.Text
                                               .Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
                                               .Select(index =>
                        {
                            int i;
                            if (!Int32.TryParse(index, out i) ||
                                i < 0)
                            {
                                throw new ControlValueException(videoStreamsBox, "video streams list");
                            }
                            return(i);
                        })
                                               .ToArray();
                    }

                    encoder.VideoCodec = videoCodecBox.Text;
                    // Must be letters, numbers, and underscores only
                    if (!Regex.IsMatch(encoder.VideoCodec, @"^\w*$"))
                    {
                        throw new ControlValueException(videoCodecBox, "video codec");
                    }

                    if (!String.IsNullOrEmpty(widthBox.Text))
                    {
                        int width;
                        if (!Int32.TryParse(widthBox.Text, out width) ||
                            width <= 0)
                        {
                            throw new ControlValueException(widthBox, "video width");
                        }
                        encoder.Width = width;
                    }

                    if (!String.IsNullOrEmpty(heightBox.Text))
                    {
                        int height;
                        if (!Int32.TryParse(heightBox.Text, out height) ||
                            height <= 0)
                        {
                            throw new ControlValueException(heightBox, "video height");
                        }
                        encoder.Height = height;
                    }

                    if (!String.IsNullOrEmpty(videoBitrateBox.Text))
                    {
                        double bitrate;
                        if (!Double.TryParse(videoBitrateBox.Text, out bitrate) ||
                            bitrate <= 0)
                        {
                            throw new ControlValueException(videoBitrateBox, "video bitrate");
                        }
                        encoder.VideoBitrate = bitrate;
                    }

                    if (!String.IsNullOrEmpty(darBox.Text))
                    {
                        var      e     = new ControlValueException(darBox, "display aspect ratio");
                        string[] parts = darBox.Text.Split(":/\\".ToCharArray(), 2);
                        double   numerator;
                        if (!Double.TryParse(parts[0], out numerator))
                        {
                            throw e;
                        }
                        encoder.DisplayAspectRatio = numerator;
                        if (parts.Length > 1)
                        {
                            double denominator;
                            if (!Double.TryParse(parts[1], out denominator) ||
                                denominator == 0)
                            {
                                throw e;
                            }
                            encoder.DisplayAspectRatio /= denominator;
                        }
                        if (encoder.DisplayAspectRatio <= 0)
                        {
                            throw e;
                        }
                    }

                    if (!String.IsNullOrEmpty(frameRateBox.Text))
                    {
                        double frameRate;
                        if (!Double.TryParse(frameRateBox.Text, out frameRate) ||
                            frameRate <= 0)
                        {
                            throw new ControlValueException(frameRateBox, "frame rate");
                        }
                        encoder.FrameRate = frameRate;
                    }

                    if (!String.IsNullOrEmpty(topBox.Text))
                    {
                        int top;
                        if (!Int32.TryParse(topBox.Text, out top) ||
                            top < 0)
                        {
                            throw new ControlValueException(topBox, "top crop margin");
                        }
                        encoder.CropTop = top;
                    }

                    if (!String.IsNullOrEmpty(leftBox.Text))
                    {
                        int left;
                        if (!Int32.TryParse(leftBox.Text, out left) ||
                            left < 0)
                        {
                            throw new ControlValueException(leftBox, "left crop margin");
                        }
                        encoder.CropLeft = left;
                    }

                    if (!String.IsNullOrEmpty(rightBox.Text))
                    {
                        int right;
                        if (!Int32.TryParse(rightBox.Text, out right) ||
                            right < 0)
                        {
                            throw new ControlValueException(rightBox, "right crop margin");
                        }
                        encoder.CropRight = right;
                    }

                    if (!String.IsNullOrEmpty(bottomBox.Text))
                    {
                        int bottom;
                        if (!Int32.TryParse(bottomBox.Text, out bottom) ||
                            bottom < 0)
                        {
                            throw new ControlValueException(bottomBox, "bottom crop margin");
                        }
                        encoder.CropBottom = bottom;
                    }

                    encoder.VideoFilters = videoFiltersBox.Text;
                }

                encoder.IncludeAudio = includeAudioCheck.Checked;
                if (encoder.IncludeAudio)
                {
                    if (!String.IsNullOrEmpty(audioStreamsBox.Text))
                    {
                        encoder.AudioStreams = audioStreamsBox.Text
                                               .Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
                                               .Select(index =>
                        {
                            int i;
                            if (!Int32.TryParse(index, out i) ||
                                i < 0)
                            {
                                throw new ControlValueException(audioStreamsBox, "audio streams list");
                            }
                            return(i);
                        })
                                               .ToArray();
                    }

                    encoder.AudioCodec = audioCodecBox.Text;
                    // Must be letters, numbers, and underscores only
                    if (!Regex.IsMatch(encoder.AudioCodec, @"^\w*$"))
                    {
                        throw new ControlValueException(audioCodecBox, "audio codec");
                    }

                    if (!String.IsNullOrEmpty(audioBitrateBox.Text))
                    {
                        double bitrate;
                        if (!Double.TryParse(audioBitrateBox.Text, out bitrate) ||
                            bitrate <= 0)
                        {
                            throw new ControlValueException(audioBitrateBox, "audio bitrate");
                        }
                        encoder.AudioBitrate = bitrate;
                    }

                    if (!String.IsNullOrEmpty(channelCountBox.Text))
                    {
                        int channelCount;
                        if (!Int32.TryParse(channelCountBox.Text, out channelCount) ||
                            channelCount <= 0)
                        {
                            throw new ControlValueException(channelCountBox, "channel count");
                        }
                        encoder.ChannelCount = channelCount;
                    }

                    if (!String.IsNullOrEmpty(sampleRateBox.Text))
                    {
                        double sampleRate;
                        if (!Double.TryParse(sampleRateBox.Text, out sampleRate) ||
                            sampleRate <= 0)
                        {
                            throw new ControlValueException(sampleRateBox, "sample rate");
                        }
                        encoder.SampleRate = sampleRate;
                    }

                    if (!String.IsNullOrEmpty(volumeBox.Text))
                    {
                        double volume;
                        if (!Double.TryParse(volumeBox.Text, out volume) ||
                            volume < 0 ||
                            // LAME will violently crash if volume is increased too much
                            // Someone should probbably report that
                            volume > 10000000)
                        {
                            throw new ControlValueException(volumeBox, "volume");
                        }
                        encoder.Volume = volume / 100;
                    }

                    encoder.AudioFilters = audioFiltersBox.Text;
                }

                encoder.IncludeSubtitles = includeSubtitlesCheck.Checked;
                if (encoder.IncludeSubtitles &&
                    !String.IsNullOrEmpty(subtitlesStreamsBox.Text))
                {
                    encoder.SubtitlesStreams = subtitlesStreamsBox.Text
                                               .Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
                                               .Select(index =>
                    {
                        int i;
                        if (!Int32.TryParse(index, out i) ||
                            i < 0)
                        {
                            throw new ControlValueException(subtitlesStreamsBox, "subtitles streams list");
                        }
                        return(i);
                    })
                                               .ToArray();
                }

                encoder.GlobalParams = globalParamsBox.Text;
                encoder.InputParams  = inputParamsBox.Text;
                encoder.OutputParams = outputParamsBox.Text;
            }
            catch (ControlValueException e)
            {
                e.Focus();
                e.ShowMessage(this);

                return(null);
            }

            return(encoder);
        }
Example #3
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);
        }