using System; using System.Windows.Forms; using BizHawk.Client.Common; namespace BizHawk.Client.EmuHawk { /// /// configures the FFmpegWriter /// public partial class FFmpegWriterForm : Form { /// /// stores a single format preset /// public class FormatPreset : IDisposable { /// /// Gets the name for the listbox /// public string Name { get; } /// /// Gets the long human readable description /// public string Desc { get; } /// /// Gets the actual portion of the ffmpeg commandline /// public string Commandline { get; set; } /// /// Gets a value indicating whether or not it can be edited /// public bool Custom { get; } /// /// Gets the default file extension /// public string Extension { get; set; } /// /// get a list of canned presets /// public static FormatPreset[] GetPresets() { return new[] { new FormatPreset("AVI Lossless AVC", "Lossless AVC video and uncompressed audio in an AVI container. High speed and compression, compatible with AVISource().", "-c:a pcm_s16le -c:v libx264rgb -qp 0 -preset ultrafast -g 10 -pix_fmt rgb24 -f avi", false, "avi"), new FormatPreset("AVI Lossless FFV1", "Lossless FFV1 video and uncompressed audio in an AVI container. Compatible with AVISource(), if ffmpeg based decoder is installed.", "-c:a pcm_s16le -c:v ffv1 -pix_fmt bgr0 -level 1 -g 1 -coder 1 -context 1 -f avi", false, "avi"), new FormatPreset("AVI Uncompressed", "Uncompressed video and audio in an AVI container. Very large, don't use!", "-c:a pcm_s16le -c:v rawvideo -f avi", false, "avi"), new FormatPreset("Matroska Lossless", "Lossless AVC video and uncompressed audio in a Matroska container.", "-c:a pcm_s16le -c:v libx264rgb -qp 0 -pix_fmt rgb24 -f matroska", false, "mkv"), new FormatPreset("Matroska", "AVC video and Vorbis audio in a Matroska container.", "-c:a libvorbis -c:v libx264 -f matroska", false, "mkv"), new FormatPreset("MP4", "AVC video and AAC audio in an MP4 container.", "-c:a aac -c:v libx264 -f mp4", false, "mp4"), new FormatPreset("WebM", "VP8 video and Vorbis audio in a WebM container.", "-c:a libvorbis -c:v libvpx -auto-alt-ref 0 -f webm", false, "webm"), new FormatPreset("Ogg", "Theora video and Vorbis audio in an Ogg contrainer.", "-c:a libvorbis -c:v libtheora -f ogg", false, "ogg"), new FormatPreset("Xvid", "Xvid video and MP3 audio in an AVI container.", "-c:a libmp3lame -c:v libxvid -f avi", false, "avi"), new FormatPreset("QuickTime", "AVC video and AAC audio in a QuickTime container.", "-c:a aac -c:v libx264 -f mov", false, "mov"), new FormatPreset("FLV", "AVC video and AAC audio in a Flash Video container.", "-c:a aac -c:v libx264 -f flv", false, "flv"), new FormatPreset("[Custom]", "Write your own ffmpeg command. For advanced users only.", "-c:a foo -c:v bar -f baz", true, "foobar"), }; } /// /// get the default format preset (from config files) /// public static FormatPreset GetDefaultPreset() { FormatPreset[] fps = GetPresets(); foreach (var fp in fps) { if (fp.ToString() == Global.Config.FFmpegFormat) { if (fp.Custom) { return fp; } } } // default to xvid? return fps[1]; } public override string ToString() { return Name; } public void Dispose() { } public void DeduceFormat(string commandline) { string formatkey = "-f "; Extension = commandline.Substring(commandline.IndexOf(formatkey) + formatkey.Length); // are there other formats that don't match their file extensions? if (Extension == "matroska") { Extension = "mkv"; } } private FormatPreset(string name, string desc, string commandline, bool custom, string ext) { Name = name; Desc = desc; Custom = custom; Commandline = Custom ? Global.Config.FFmpegCustomCommand : commandline; DeduceFormat(Commandline); } } private FFmpegWriterForm() { InitializeComponent(); } private void ListBox1_SelectedIndexChanged(object sender, EventArgs e) { if (listBox1.SelectedIndex != -1) { var f = (FormatPreset)listBox1.SelectedItem; label5.Text = $"Extension: {f.Extension}"; label3.Text = f.Desc; textBox1.Text = f.Commandline; } } /// /// return a FormatPreset corresponding to the user's choice /// public static FormatPreset DoFFmpegWriterDlg(IWin32Window owner) { FFmpegWriterForm dlg = new FFmpegWriterForm(); dlg.listBox1.Items.AddRange(FormatPreset.GetPresets()); int i = dlg.listBox1.FindStringExact(Global.Config.FFmpegFormat); if (i != ListBox.NoMatches) { dlg.listBox1.SelectedIndex = i; } DialogResult result = dlg.ShowDialog(owner); FormatPreset ret; if (result != DialogResult.OK || dlg.listBox1.SelectedIndex == -1) { ret = null; } else { ret = (FormatPreset)dlg.listBox1.SelectedItem; Global.Config.FFmpegFormat = ret.ToString(); if (ret.Custom) { ret.Commandline = Global.Config.FFmpegCustomCommand = dlg.textBox1.Text; ret.DeduceFormat(ret.Commandline); } } dlg.Dispose(); return ret; } } }