add automated dumping. command line example:
bizhawk.multiclient --dump-type=ffmpeg --dump-name=foobar.avi --dump-length=1000 type is one of 'vfwavi' (doesn't work), 'ffmpeg', 'jmd', 'nut', 'wave' name is filename to dump to; might be auto-modified to add segment split names (_00, _01, etc) length is length of dump in frames after which it auto-stops. if omitted, set to be equal to the length of the movie loaded with --movie, or if not that, it runs forever (can be stopped from UI)
This commit is contained in:
parent
f9c764f5e5
commit
7db089fbbd
|
@ -29,10 +29,10 @@ namespace BizHawk.MultiClient
|
|||
/// </summary>
|
||||
public void SetVideoCodecToken(IDisposable token)
|
||||
{
|
||||
if (token is CodecToken)
|
||||
currVideoCodecToken = (CodecToken)token;
|
||||
else
|
||||
throw new ArgumentException("AviWriter only takes its own Codec Tokens!");
|
||||
if (token is CodecToken)
|
||||
currVideoCodecToken = (CodecToken)token;
|
||||
else
|
||||
throw new ArgumentException("AviWriter only takes its own Codec Tokens!");
|
||||
}
|
||||
|
||||
public static IEnumerator<string> CreateBasicNameProvider(string template)
|
||||
|
@ -55,58 +55,58 @@ namespace BizHawk.MultiClient
|
|||
/// </summary>
|
||||
public void OpenFile(string baseName) { OpenFile(CreateBasicNameProvider(baseName)); }
|
||||
|
||||
// thread communication
|
||||
// synchronized queue with custom messages
|
||||
// it seems like there are 99999 ways to do everything in C#, so i'm sure this is not the best
|
||||
System.Collections.Concurrent.BlockingCollection<Object> threadQ;
|
||||
System.Threading.Thread workerT;
|
||||
// thread communication
|
||||
// synchronized queue with custom messages
|
||||
// it seems like there are 99999 ways to do everything in C#, so i'm sure this is not the best
|
||||
System.Collections.Concurrent.BlockingCollection<Object> threadQ;
|
||||
System.Threading.Thread workerT;
|
||||
|
||||
void threadproc()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Object o = threadQ.Take();
|
||||
if (o is IVideoProvider)
|
||||
AddFrameEx((IVideoProvider)o);
|
||||
else if (o is short[])
|
||||
AddSamplesEx((short[])o);
|
||||
else
|
||||
// anything else is assumed to be quit time
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.Windows.Forms.MessageBox.Show("AVIFIL32 Thread died:\n\n" + e.ToString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
void threadproc()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Object o = threadQ.Take();
|
||||
if (o is IVideoProvider)
|
||||
AddFrameEx((IVideoProvider)o);
|
||||
else if (o is short[])
|
||||
AddSamplesEx((short[])o);
|
||||
else
|
||||
// anything else is assumed to be quit time
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.Windows.Forms.MessageBox.Show("AVIFIL32 Thread died:\n\n" + e.ToString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// we can't pass the IVideoProvider we get to another thread, because it doesn't actually keep a local copy of its data,
|
||||
// instead grabbing it from the emu as needed. this causes frame loss/dupping as a race condition
|
||||
// instead we pass this
|
||||
class VideoCopy : IVideoProvider
|
||||
{
|
||||
int[] vb;
|
||||
int bw, bh, bc;
|
||||
public int VirtualWidth { get { return bw; } }
|
||||
public int BufferWidth { get {return bw;} }
|
||||
public int BufferHeight { get { return bh; } }
|
||||
public int BackgroundColor { get { return bc; } }
|
||||
public VideoCopy(IVideoProvider c)
|
||||
{
|
||||
vb = (int []) c.GetVideoBuffer().Clone ();
|
||||
bw = c.BufferWidth;
|
||||
bh = c.BufferHeight;
|
||||
bc = c.BackgroundColor;
|
||||
}
|
||||
public int[] GetVideoBuffer()
|
||||
{
|
||||
return vb;
|
||||
}
|
||||
}
|
||||
// we can't pass the IVideoProvider we get to another thread, because it doesn't actually keep a local copy of its data,
|
||||
// instead grabbing it from the emu as needed. this causes frame loss/dupping as a race condition
|
||||
// instead we pass this
|
||||
class VideoCopy : IVideoProvider
|
||||
{
|
||||
int[] vb;
|
||||
int bw, bh, bc;
|
||||
public int VirtualWidth { get { return bw; } }
|
||||
public int BufferWidth { get { return bw; } }
|
||||
public int BufferHeight { get { return bh; } }
|
||||
public int BackgroundColor { get { return bc; } }
|
||||
public VideoCopy(IVideoProvider c)
|
||||
{
|
||||
vb = (int[])c.GetVideoBuffer().Clone();
|
||||
bw = c.BufferWidth;
|
||||
bh = c.BufferHeight;
|
||||
bc = c.BackgroundColor;
|
||||
}
|
||||
public int[] GetVideoBuffer()
|
||||
{
|
||||
return vb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
@ -120,27 +120,27 @@ namespace BizHawk.MultiClient
|
|||
if (currVideoCodecToken == null)
|
||||
throw new InvalidOperationException("Tried to start recording an AVI with no video codec token set");
|
||||
|
||||
threadQ = new System.Collections.Concurrent.BlockingCollection<Object>(30);
|
||||
workerT = new System.Threading.Thread(new System.Threading.ThreadStart(threadproc));
|
||||
workerT.Start();
|
||||
threadQ = new System.Collections.Concurrent.BlockingCollection<Object>(30);
|
||||
workerT = new System.Threading.Thread(new System.Threading.ThreadStart(threadproc));
|
||||
workerT.Start();
|
||||
}
|
||||
|
||||
public void CloseFile()
|
||||
{
|
||||
threadQ.Add(new Object ()); // acts as stop message
|
||||
workerT.Join();
|
||||
threadQ.Add(new Object()); // acts as stop message
|
||||
workerT.Join();
|
||||
if (currSegment != null)
|
||||
currSegment.Dispose();
|
||||
currSegment = null;
|
||||
}
|
||||
|
||||
public void AddFrame(IVideoProvider source)
|
||||
{
|
||||
if (!workerT.IsAlive)
|
||||
// signal some sort of error?
|
||||
return;
|
||||
threadQ.Add(new VideoCopy (source));
|
||||
}
|
||||
public void AddFrame(IVideoProvider source)
|
||||
{
|
||||
if (!workerT.IsAlive)
|
||||
// signal some sort of error?
|
||||
return;
|
||||
threadQ.Add(new VideoCopy(source));
|
||||
}
|
||||
void AddFrameEx(IVideoProvider source)
|
||||
{
|
||||
SetVideoParameters(source.BufferWidth, source.BufferHeight);
|
||||
|
@ -149,15 +149,15 @@ namespace BizHawk.MultiClient
|
|||
currSegment.AddFrame(source);
|
||||
}
|
||||
|
||||
public void AddSamples(short[] samples)
|
||||
{
|
||||
if (!workerT.IsAlive)
|
||||
// signal some sort of error?
|
||||
return;
|
||||
// as MainForm.cs is written now, samples is all ours (nothing else will use it for anything)
|
||||
// but that's a bad assumption to make and could change in the future, so copy it since we're passing to another thread
|
||||
threadQ.Add((short []) samples.Clone ());
|
||||
}
|
||||
public void AddSamples(short[] samples)
|
||||
{
|
||||
if (!workerT.IsAlive)
|
||||
// signal some sort of error?
|
||||
return;
|
||||
// as MainForm.cs is written now, samples is all ours (nothing else will use it for anything)
|
||||
// but that's a bad assumption to make and could change in the future, so copy it since we're passing to another thread
|
||||
threadQ.Add((short[])samples.Clone());
|
||||
}
|
||||
void AddSamplesEx(short[] samples)
|
||||
{
|
||||
ConsiderLengthSegment();
|
||||
|
@ -167,7 +167,7 @@ namespace BizHawk.MultiClient
|
|||
|
||||
void ConsiderLengthSegment()
|
||||
{
|
||||
if(currSegment == null) return;
|
||||
if (currSegment == null) return;
|
||||
long len = currSegment.GetLengthApproximation();
|
||||
const long segment_length_limit = 2 * 1000 * 1000 * 1000; //2GB
|
||||
//const long segment_length_limit = 10 * 1000 * 1000; //for testing
|
||||
|
@ -212,7 +212,7 @@ namespace BizHawk.MultiClient
|
|||
File.Delete(tempfile);
|
||||
tempfile = Path.ChangeExtension(tempfile, "avi");
|
||||
temp.OpenFile(tempfile, temp_params, null); //lastToken);
|
||||
CodecToken token = (CodecToken) temp.AcquireVideoCodecToken(hwnd.Handle);
|
||||
CodecToken token = (CodecToken)temp.AcquireVideoCodecToken(hwnd.Handle);
|
||||
temp.CloseFile();
|
||||
File.Delete(tempfile);
|
||||
return token;
|
||||
|
@ -263,7 +263,7 @@ namespace BizHawk.MultiClient
|
|||
public void SetMovieParameters(int fps, int fps_scale)
|
||||
{
|
||||
bool change = false;
|
||||
|
||||
|
||||
change |= fps != parameters.fps;
|
||||
parameters.fps = fps;
|
||||
|
||||
|
@ -352,13 +352,13 @@ namespace BizHawk.MultiClient
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// set metadata parameters; should be called before opening file
|
||||
/// NYI
|
||||
/// </summary>
|
||||
public void SetMetaData(string gameName, string authors, UInt64 lengthMS, UInt64 rerecords)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// set metadata parameters; should be called before opening file
|
||||
/// NYI
|
||||
/// </summary>
|
||||
public void SetMetaData(string gameName, string authors, UInt64 lengthMS, UInt64 rerecords)
|
||||
{
|
||||
}
|
||||
|
||||
unsafe class AviWriterSegment : IDisposable
|
||||
{
|
||||
|
@ -669,6 +669,19 @@ namespace BizHawk.MultiClient
|
|||
{
|
||||
return "avi";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void SetDefaultVideoCodecToken()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string ShortName()
|
||||
{
|
||||
return "vfwavi";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -232,6 +232,8 @@ namespace BizHawk.MultiClient
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
if (ffmpeg != null)
|
||||
CloseFile();
|
||||
}
|
||||
|
||||
|
||||
|
@ -274,5 +276,16 @@ namespace BizHawk.MultiClient
|
|||
// this needs to interface with the codec token
|
||||
return token.defaultext;
|
||||
}
|
||||
|
||||
|
||||
public void SetDefaultVideoCodecToken()
|
||||
{
|
||||
this.token = FFmpegWriterForm.FormatPreset.GetDefaultPreset();
|
||||
}
|
||||
|
||||
public string ShortName()
|
||||
{
|
||||
return "ffmpeg";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,6 +79,26 @@ namespace BizHawk.MultiClient
|
|||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// get the default format preset (from config files)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static FormatPreset GetDefaultPreset()
|
||||
{
|
||||
FormatPreset[] fps = GetPresets();
|
||||
|
||||
foreach (var fp in fps)
|
||||
{
|
||||
if (fp.ToString() == Global.Config.VideoWriter)
|
||||
{
|
||||
if (fp.custom)
|
||||
return fp;
|
||||
}
|
||||
}
|
||||
// default to xvid?
|
||||
return fps[1];
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using BizHawk.MultiClient;
|
||||
|
||||
namespace BizHawk
|
||||
{
|
||||
|
@ -11,6 +12,11 @@ namespace BizHawk
|
|||
/// </summary>
|
||||
void SetVideoCodecToken(IDisposable token);
|
||||
|
||||
/// <summary>
|
||||
/// sets to a default video codec token without calling any UI - for automated dumping
|
||||
/// </summary>
|
||||
void SetDefaultVideoCodecToken();
|
||||
|
||||
|
||||
// why no OpenFile(IEnumerator<string>) ?
|
||||
// different video writers may have different ideas of how and why splitting is to occur
|
||||
|
@ -83,5 +89,50 @@ namespace BizHawk
|
|||
/// what default extension this writer would like to put on its output
|
||||
/// </summary>
|
||||
string DesiredExtension();
|
||||
/// <summary>
|
||||
/// name that command line parameters can refer to
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
string ShortName();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// contains methods to find all IVideoWriter
|
||||
/// </summary>
|
||||
public static class VideoWriterInventory
|
||||
{
|
||||
public static IEnumerable<IVideoWriter> GetAllVideoWriters()
|
||||
{
|
||||
var ret = new IVideoWriter[]
|
||||
{
|
||||
new AviWriter(),
|
||||
new JMDWriter(),
|
||||
new WavWriterV(),
|
||||
new FFmpegWriter(),
|
||||
new NutWriter()
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// find an IVideoWriter by its short name
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public static IVideoWriter GetVideoWriter(string name)
|
||||
{
|
||||
IVideoWriter ret = null;
|
||||
|
||||
var vws = GetAllVideoWriters();
|
||||
|
||||
foreach (var vw in vws)
|
||||
if (vw.ShortName() == name)
|
||||
ret = vw;
|
||||
|
||||
foreach (var vw in vws)
|
||||
if (vw != ret)
|
||||
vw.Dispose();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -780,5 +780,26 @@ namespace BizHawk.MultiClient
|
|||
{
|
||||
return "jmd";
|
||||
}
|
||||
|
||||
|
||||
public void SetDefaultVideoCodecToken()
|
||||
{
|
||||
CodecToken ct = new CodecToken();
|
||||
|
||||
// load from config and sanitize
|
||||
int t = Math.Min(Math.Max(Global.Config.JMDThreads, 1), 6);
|
||||
|
||||
int c = Math.Min(Math.Max(Global.Config.JMDCompression, Deflater.NO_COMPRESSION), Deflater.BEST_COMPRESSION);
|
||||
|
||||
ct.compressionlevel = c;
|
||||
ct.numthreads = t;
|
||||
|
||||
token = ct;
|
||||
}
|
||||
|
||||
public string ShortName()
|
||||
{
|
||||
return "jmd";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ namespace BizHawk.MultiClient
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public void SetVideoCodecToken(IDisposable token)
|
||||
{
|
||||
// ignored
|
||||
|
@ -122,9 +121,11 @@ namespace BizHawk.MultiClient
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
if (current != null)
|
||||
endsegment();
|
||||
baseName = null;
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ".nut writer";
|
||||
|
@ -139,5 +140,16 @@ namespace BizHawk.MultiClient
|
|||
{
|
||||
return "nut";
|
||||
}
|
||||
|
||||
|
||||
public void SetDefaultVideoCodecToken()
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
public string ShortName()
|
||||
{
|
||||
return "nut";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,14 +25,17 @@ namespace BizHawk.MultiClient
|
|||
/// <param name="list">list of IVideoWriters to choose from</param>
|
||||
/// <param name="owner">parent window</param>
|
||||
/// <returns>user choice, or null on Cancel\Close\invalid</returns>
|
||||
public static IVideoWriter DoVideoWriterChoserDlg(IVideoWriter[] list, IWin32Window owner)
|
||||
public static IVideoWriter DoVideoWriterChoserDlg(IEnumerable<IVideoWriter> list, IWin32Window owner)
|
||||
{
|
||||
VideoWriterChooserForm dlg = new VideoWriterChooserForm();
|
||||
|
||||
dlg.label1.Text = "Description:";
|
||||
dlg.label2.Text = "";
|
||||
|
||||
dlg.listBox1.Items.AddRange(list);
|
||||
dlg.listBox1.BeginUpdate();
|
||||
foreach (var vw in list)
|
||||
dlg.listBox1.Items.Add(vw);
|
||||
dlg.listBox1.EndUpdate();
|
||||
|
||||
int i = dlg.listBox1.FindStringExact(Global.Config.VideoWriter);
|
||||
if (i != ListBox.NoMatches)
|
||||
|
@ -61,6 +64,5 @@ namespace BizHawk.MultiClient
|
|||
else
|
||||
label2.Text = "";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -283,5 +283,16 @@ namespace BizHawk.MultiClient
|
|||
{
|
||||
return "wav";
|
||||
}
|
||||
|
||||
|
||||
public void SetDefaultVideoCodecToken()
|
||||
{
|
||||
// don't use codec tokens, so don't care
|
||||
}
|
||||
|
||||
public string ShortName()
|
||||
{
|
||||
return "wave";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,6 +82,12 @@ namespace BizHawk.MultiClient
|
|||
public LuaConsole LuaConsole1 = new LuaConsole();
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// number of frames to autodump
|
||||
/// </summary>
|
||||
int autoDumpLength = 0;
|
||||
|
||||
|
||||
public MainForm(string[] args)
|
||||
{
|
||||
Global.MovieSession = new MovieSession();
|
||||
|
@ -168,6 +174,9 @@ namespace BizHawk.MultiClient
|
|||
string cmdRom = null;
|
||||
string cmdLoadState = null;
|
||||
string cmdMovie = null;
|
||||
string cmdDumpType = null;
|
||||
string cmdDumpName = null;
|
||||
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
//for some reason sometimes visual studio will pass this to us on the commandline. it makes no sense.
|
||||
|
@ -184,6 +193,12 @@ namespace BizHawk.MultiClient
|
|||
cmdLoadState = arg.Substring(arg.IndexOf('=') + 1);
|
||||
else if (arg.StartsWith("--movie="))
|
||||
cmdMovie = arg.Substring(arg.IndexOf('=') + 1);
|
||||
else if (arg.StartsWith("--dump-type="))
|
||||
cmdDumpType = arg.Substring(arg.IndexOf('=') + 1);
|
||||
else if (arg.StartsWith("--dump-name="))
|
||||
cmdDumpName = arg.Substring(arg.IndexOf('=') + 1);
|
||||
else if (arg.StartsWith("--dump-length="))
|
||||
int.TryParse(arg.Substring(arg.IndexOf('=') + 1), out autoDumpLength);
|
||||
else
|
||||
cmdRom = arg;
|
||||
}
|
||||
|
@ -208,6 +223,9 @@ namespace BizHawk.MultiClient
|
|||
{
|
||||
Movie m = new Movie(cmdMovie, MOVIEMODE.PLAY);
|
||||
ReadOnly = true;
|
||||
// if user is dumping and didnt supply dump length, make it as long as the loaded movie
|
||||
if (autoDumpLength == 0)
|
||||
autoDumpLength = m.LogLength();
|
||||
StartNewMovie(m, false);
|
||||
Global.Config.RecentMovies.Add(cmdMovie);
|
||||
}
|
||||
|
@ -268,6 +286,12 @@ namespace BizHawk.MultiClient
|
|||
debuggerToolStripMenuItem.Enabled = false;
|
||||
//luaConsoleToolStripMenuItem.Enabled = false;
|
||||
}
|
||||
|
||||
// start dumping, if appropriate
|
||||
if (cmdDumpType != null && cmdDumpName != null)
|
||||
{
|
||||
RecordAVI(cmdDumpType, cmdDumpName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1966,6 +1990,13 @@ namespace BizHawk.MultiClient
|
|||
|
||||
CurrAviWriter.AddFrame(Global.Emulator.VideoProvider);
|
||||
CurrAviWriter.AddSamples(temp);
|
||||
|
||||
if (autoDumpLength > 0)
|
||||
{
|
||||
autoDumpLength--;
|
||||
if (autoDumpLength == 0) // finish
|
||||
StopAVI();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2762,22 +2793,66 @@ namespace BizHawk.MultiClient
|
|||
if (Global.Config.SaveSlot == 9) StatusSlot9.BackColor = SystemColors.ControlLightLight;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// start avi recording, unattended
|
||||
/// </summary>
|
||||
/// <param name="videowritername">match the short name of an ivideowriter</param>
|
||||
/// <param name="filename">filename to save to</param>
|
||||
public void RecordAVI(string videowritername, string filename)
|
||||
{
|
||||
_RecordAVI(videowritername, filename, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// start avi recording, asking user for filename and options
|
||||
/// </summary>
|
||||
public void RecordAVI()
|
||||
{
|
||||
_RecordAVI(null, null, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// start avi recording
|
||||
/// </summary>
|
||||
/// <param name="videowritername"></param>
|
||||
/// <param name="filename"></param>
|
||||
/// <param name="unattended"></param>
|
||||
private void _RecordAVI(string videowritername, string filename, bool unattended)
|
||||
{
|
||||
if (CurrAviWriter != null) return;
|
||||
|
||||
// select IVideoWriter to use
|
||||
IVideoWriter aw = null;
|
||||
var writers = VideoWriterInventory.GetAllVideoWriters();
|
||||
|
||||
if (unattended)
|
||||
{
|
||||
foreach (var w in writers)
|
||||
{
|
||||
if (w.ShortName() == videowritername)
|
||||
{
|
||||
aw = w;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aw = VideoWriterChooserForm.DoVideoWriterChoserDlg(writers, Global.MainForm);
|
||||
}
|
||||
|
||||
var writers = new IVideoWriter[]{new AviWriter(), new JMDWriter(), new WavWriterV(), new FFmpegWriter(), new NutWriter()};
|
||||
IVideoWriter aw = VideoWriterChooserForm.DoVideoWriterChoserDlg(writers, Global.MainForm);
|
||||
foreach (var w in writers)
|
||||
{
|
||||
if (w != aw)
|
||||
w.Dispose();
|
||||
}
|
||||
|
||||
if (aw == null)
|
||||
{
|
||||
Global.OSD.AddMessage("A/V capture canceled.");
|
||||
if (unattended)
|
||||
Global.OSD.AddMessage(string.Format("Couldn't start video writer \"{0}\"", videowritername));
|
||||
else
|
||||
Global.OSD.AddMessage("A/V capture canceled.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2789,42 +2864,53 @@ namespace BizHawk.MultiClient
|
|||
|
||||
// select codec token
|
||||
// do this before save dialog because ffmpeg won't know what extension it wants until it's been configured
|
||||
|
||||
var token = aw.AcquireVideoCodecToken(Global.MainForm);
|
||||
if (token == null)
|
||||
if (unattended)
|
||||
{
|
||||
Global.OSD.AddMessage("A/V capture canceled.");
|
||||
aw.Dispose();
|
||||
return;
|
||||
}
|
||||
aw.SetVideoCodecToken(token);
|
||||
|
||||
// select file to save to
|
||||
|
||||
var sfd = new SaveFileDialog();
|
||||
if (!(Global.Emulator is NullEmulator))
|
||||
{
|
||||
sfd.FileName = PathManager.FilesystemSafeName(Global.Game);
|
||||
sfd.InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.AVIPath, "");
|
||||
aw.SetDefaultVideoCodecToken();
|
||||
}
|
||||
else
|
||||
{
|
||||
sfd.FileName = "NULL";
|
||||
sfd.InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.AVIPath, "");
|
||||
var token = aw.AcquireVideoCodecToken(Global.MainForm);
|
||||
if (token == null)
|
||||
{
|
||||
Global.OSD.AddMessage("A/V capture canceled.");
|
||||
aw.Dispose();
|
||||
return;
|
||||
}
|
||||
aw.SetVideoCodecToken(token);
|
||||
}
|
||||
sfd.Filter = String.Format("{0} (*.{0})|*.{0}|All Files|*.*", aw.DesiredExtension());
|
||||
|
||||
Global.Sound.StopSound();
|
||||
var result = sfd.ShowDialog();
|
||||
Global.Sound.StartSound();
|
||||
|
||||
if (result == DialogResult.Cancel)
|
||||
// select file to save to
|
||||
if (unattended)
|
||||
{
|
||||
aw.Dispose();
|
||||
return;
|
||||
aw.OpenFile(filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
var sfd = new SaveFileDialog();
|
||||
if (!(Global.Emulator is NullEmulator))
|
||||
{
|
||||
sfd.FileName = PathManager.FilesystemSafeName(Global.Game);
|
||||
sfd.InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.AVIPath, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
sfd.FileName = "NULL";
|
||||
sfd.InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.AVIPath, "");
|
||||
}
|
||||
sfd.Filter = String.Format("{0} (*.{0})|*.{0}|All Files|*.*", aw.DesiredExtension());
|
||||
|
||||
aw.OpenFile(sfd.FileName);
|
||||
Global.Sound.StopSound();
|
||||
var result = sfd.ShowDialog();
|
||||
Global.Sound.StartSound();
|
||||
|
||||
if (result == DialogResult.Cancel)
|
||||
{
|
||||
aw.Dispose();
|
||||
return;
|
||||
}
|
||||
aw.OpenFile(sfd.FileName);
|
||||
}
|
||||
|
||||
//commit the avi writing last, in case there were any errors earlier
|
||||
CurrAviWriter = aw;
|
||||
|
@ -2852,6 +2938,7 @@ namespace BizHawk.MultiClient
|
|||
return;
|
||||
}
|
||||
CurrAviWriter.CloseFile();
|
||||
CurrAviWriter.Dispose();
|
||||
CurrAviWriter = null;
|
||||
Global.OSD.AddMessage("AVI capture stopped");
|
||||
AVIStatusLabel.Image = BizHawk.MultiClient.Properties.Resources.Blank;
|
||||
|
|
Loading…
Reference in New Issue