mirror of
https://github.com/ShareX/ShareX.git
synced 2024-10-06 05:05:42 +13:00
ffmpeg cli recording works now
This commit is contained in:
parent
b418f69169
commit
4678d6c9b5
6 changed files with 84 additions and 79 deletions
|
@ -43,21 +43,23 @@ public abstract class ExternalCLIManager : IDisposable
|
||||||
|
|
||||||
private Process process = new Process();
|
private Process process = new Process();
|
||||||
|
|
||||||
public virtual int Open(string cliPath, string args = null)
|
public virtual int Open(string path, string args = null)
|
||||||
{
|
{
|
||||||
if (File.Exists(cliPath))
|
DebugHelper.WriteLine("CLI path: \"{0}\" args: \"{1}\"", path, args);
|
||||||
|
|
||||||
|
if (File.Exists(path))
|
||||||
{
|
{
|
||||||
Output = new StringBuilder();
|
Output = new StringBuilder();
|
||||||
Errors = new StringBuilder();
|
Errors = new StringBuilder();
|
||||||
|
|
||||||
ProcessStartInfo psi = new ProcessStartInfo(cliPath);
|
ProcessStartInfo psi = new ProcessStartInfo(path);
|
||||||
psi.UseShellExecute = false;
|
psi.UseShellExecute = false;
|
||||||
psi.CreateNoWindow = true;
|
psi.CreateNoWindow = true;
|
||||||
psi.RedirectStandardInput = true;
|
psi.RedirectStandardInput = true;
|
||||||
psi.RedirectStandardOutput = true;
|
psi.RedirectStandardOutput = true;
|
||||||
psi.RedirectStandardError = true;
|
psi.RedirectStandardError = true;
|
||||||
psi.Arguments = args;
|
psi.Arguments = args;
|
||||||
psi.WorkingDirectory = Path.GetDirectoryName(cliPath);
|
psi.WorkingDirectory = Path.GetDirectoryName(path);
|
||||||
|
|
||||||
process.EnableRaisingEvents = true;
|
process.EnableRaisingEvents = true;
|
||||||
process.OutputDataReceived += cli_OutputDataReceived;
|
process.OutputDataReceived += cli_OutputDataReceived;
|
||||||
|
|
|
@ -125,23 +125,23 @@ public static void SetShellContextMenu(bool register)
|
||||||
|
|
||||||
public static void RegisterShellContextMenu()
|
public static void RegisterShellContextMenu()
|
||||||
{
|
{
|
||||||
CreateRegistryKey(ShellExtMenuFiles, ShellExtDesc);
|
CreateRegistry(ShellExtMenuFiles, ShellExtDesc);
|
||||||
AddRegistryValue(ShellExtMenuFiles, "Icon", ShellExtIcon);
|
CreateRegistry(ShellExtMenuFiles, "Icon", ShellExtIcon);
|
||||||
CreateRegistryKey(ShellExtMenuFilesCmd, ShellExtPath);
|
CreateRegistry(ShellExtMenuFilesCmd, ShellExtPath);
|
||||||
|
|
||||||
CreateRegistryKey(ShellExtMenuDirectory, ShellExtDesc);
|
CreateRegistry(ShellExtMenuDirectory, ShellExtDesc);
|
||||||
AddRegistryValue(ShellExtMenuDirectory, "Icon", ShellExtIcon);
|
CreateRegistry(ShellExtMenuDirectory, "Icon", ShellExtIcon);
|
||||||
CreateRegistryKey(ShellExtMenuDirectoryCmd, ShellExtPath);
|
CreateRegistry(ShellExtMenuDirectoryCmd, ShellExtPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UnregisterShellContextMenu()
|
public static void UnregisterShellContextMenu()
|
||||||
{
|
{
|
||||||
RemoveRegistryKey(ShellExtMenuFilesCmd);
|
RemoveRegistry(ShellExtMenuFilesCmd);
|
||||||
RemoveRegistryKey(ShellExtMenuFiles);
|
RemoveRegistry(ShellExtMenuFiles);
|
||||||
RemoveRegistryKey(ShellExtMenuDirectoryCmd);
|
RemoveRegistry(ShellExtMenuDirectoryCmd);
|
||||||
RemoveRegistryKey(ShellExtMenuDirectory);
|
RemoveRegistry(ShellExtMenuDirectory);
|
||||||
RemoveRegistryKey(ShellExtMenuFoldersCmd);
|
RemoveRegistry(ShellExtMenuFoldersCmd);
|
||||||
RemoveRegistryKey(ShellExtMenuFolders);
|
RemoveRegistry(ShellExtMenuFolders);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ExternalProgram FindProgram(string name, string filename)
|
public static ExternalProgram FindProgram(string name, string filename)
|
||||||
|
@ -192,18 +192,39 @@ public static ExternalProgram FindProgram(string name, string filename)
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CreateRegistryKey(string path, string value, string name = null)
|
public static void CreateRegistry(string path, string value)
|
||||||
|
{
|
||||||
|
CreateRegistry(path, null, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreateRegistry(string path, string name, string value)
|
||||||
{
|
{
|
||||||
using (RegistryKey rk = Registry.CurrentUser.CreateSubKey(path))
|
using (RegistryKey rk = Registry.CurrentUser.CreateSubKey(path))
|
||||||
{
|
{
|
||||||
if (rk != null)
|
if (rk != null)
|
||||||
{
|
{
|
||||||
rk.SetValue(name, value);
|
rk.SetValue(name, value, RegistryValueKind.String);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RemoveRegistryKey(string path)
|
public static void CreateRegistry(string path, int value)
|
||||||
|
{
|
||||||
|
CreateRegistry(path, null, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreateRegistry(string path, string name, int value)
|
||||||
|
{
|
||||||
|
using (RegistryKey rk = Registry.CurrentUser.CreateSubKey(path))
|
||||||
|
{
|
||||||
|
if (rk != null)
|
||||||
|
{
|
||||||
|
rk.SetValue(name, value, RegistryValueKind.DWord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RemoveRegistry(string path)
|
||||||
{
|
{
|
||||||
using (RegistryKey rk = Registry.CurrentUser.OpenSubKey(path))
|
using (RegistryKey rk = Registry.CurrentUser.OpenSubKey(path))
|
||||||
{
|
{
|
||||||
|
@ -214,18 +235,7 @@ private static void RemoveRegistryKey(string path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddRegistryValue(string path, string name, string value)
|
public static bool CheckRegistry(string path, string name = null, string value = null)
|
||||||
{
|
|
||||||
using (RegistryKey rk = Registry.CurrentUser.OpenSubKey(path, true))
|
|
||||||
{
|
|
||||||
if (rk != null)
|
|
||||||
{
|
|
||||||
rk.SetValue(name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool CheckRegistry(string path, string name = null, string value = null)
|
|
||||||
{
|
{
|
||||||
string registryValue = GetRegistryValue(path, name);
|
string registryValue = GetRegistryValue(path, name);
|
||||||
|
|
||||||
|
@ -237,7 +247,7 @@ private static bool CheckRegistry(string path, string name = null, string value
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetRegistryValue(string path, string name = null)
|
public static string GetRegistryValue(string path, string name = null)
|
||||||
{
|
{
|
||||||
using (RegistryKey rk = Registry.CurrentUser.OpenSubKey(path))
|
using (RegistryKey rk = Registry.CurrentUser.OpenSubKey(path))
|
||||||
{
|
{
|
||||||
|
|
|
@ -63,7 +63,6 @@
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Screencast\CLIEncoder.cs" />
|
|
||||||
<Compile Include="Enums.cs" />
|
<Compile Include="Enums.cs" />
|
||||||
<Compile Include="Screencast\FFmpegCLIHelper.cs" />
|
<Compile Include="Screencast\FFmpegCLIHelper.cs" />
|
||||||
<Compile Include="Screencast\ScreencastOptions.cs" />
|
<Compile Include="Screencast\ScreencastOptions.cs" />
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
#region License Information (GPL v3)
|
|
||||||
|
|
||||||
/*
|
|
||||||
ShareX - A program that allows you to take screenshots and share any file type
|
|
||||||
Copyright (C) 2008-2014 ShareX Developers
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
|
|
||||||
Optionally you can also view the license at <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endregion License Information (GPL v3)
|
|
||||||
|
|
||||||
using HelpersLib;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace ScreenCaptureLib
|
|
||||||
{
|
|
||||||
public abstract class CLIEncoder : ExternalCLIManager
|
|
||||||
{
|
|
||||||
public abstract bool Record();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -27,6 +27,7 @@ You should have received a copy of the GNU General Public License
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -34,7 +35,7 @@ You should have received a copy of the GNU General Public License
|
||||||
|
|
||||||
namespace ScreenCaptureLib
|
namespace ScreenCaptureLib
|
||||||
{
|
{
|
||||||
public class FFmpegCLIHelper : CLIEncoder
|
public class FFmpegCLIHelper : ExternalCLIManager
|
||||||
{
|
{
|
||||||
public ScreencastOptions Options { get; private set; }
|
public ScreencastOptions Options { get; private set; }
|
||||||
|
|
||||||
|
@ -50,23 +51,54 @@ public FFmpegCLIHelper(ScreencastOptions options)
|
||||||
Helpers.CreateDirectoryIfNotExist(Options.OutputPath);
|
Helpers.CreateDirectoryIfNotExist(Options.OutputPath);
|
||||||
|
|
||||||
// It is actually output data
|
// It is actually output data
|
||||||
ErrorDataReceived += FFmpegCLIHelper_ErrorDataReceived;
|
ErrorDataReceived += FFmpegCLIHelper_OutputDataReceived;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FFmpegCLIHelper_ErrorDataReceived(object sender, DataReceivedEventArgs e)
|
private void FFmpegCLIHelper_OutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
//DebugHelper.WriteLine(e.Data);
|
//DebugHelper.WriteLine(e.Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Record()
|
public bool Record(Rectangle captureRectangle)
|
||||||
{
|
{
|
||||||
|
// https://github.com/rdp/screen-capture-recorder-to-video-windows-free configuration section
|
||||||
|
string dshowRegistryPath = "Software\\screen-capture-recorder";
|
||||||
|
RegistryHelpers.CreateRegistry(dshowRegistryPath, "start_x", captureRectangle.X);
|
||||||
|
RegistryHelpers.CreateRegistry(dshowRegistryPath, "start_y", captureRectangle.Y);
|
||||||
|
RegistryHelpers.CreateRegistry(dshowRegistryPath, "capture_width", captureRectangle.Width);
|
||||||
|
RegistryHelpers.CreateRegistry(dshowRegistryPath, "capture_height", captureRectangle.Height);
|
||||||
|
|
||||||
StringBuilder args = new StringBuilder();
|
StringBuilder args = new StringBuilder();
|
||||||
args.Append("-f dshow -i video=\"screen-capture-recorder\"");
|
|
||||||
if (Options.FPS > 0)
|
if (Options.FPS > 0)
|
||||||
{
|
{
|
||||||
args.Append(string.Format(" -r {0}", Options.FPS));
|
// input FPS
|
||||||
|
args.AppendFormat("-r {0} ", Options.FPS);
|
||||||
}
|
}
|
||||||
args.Append(string.Format(" -c:v libx264 -crf 23 -preset medium -pix_fmt yuv420p -y \"{0}\"", Options.OutputPath));
|
|
||||||
|
args.Append("-f dshow -i ");
|
||||||
|
|
||||||
|
// dshow audio/video device: https://github.com/rdp/screen-capture-recorder-to-video-windows-free
|
||||||
|
//args.AppendFormat("audio=\"{0}\":", "virtual-audio-capturer");
|
||||||
|
args.AppendFormat("video=\"{0}\" ", "screen-capture-recorder");
|
||||||
|
|
||||||
|
if (Options.FPS > 0)
|
||||||
|
{
|
||||||
|
// output FPS
|
||||||
|
args.AppendFormat("-r {0} ", Options.FPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// x264 encoder
|
||||||
|
args.Append("-c:v libx264 ");
|
||||||
|
|
||||||
|
// TODO: Add crf, preset etc. to options
|
||||||
|
// https://trac.ffmpeg.org/wiki/x264EncodingGuide
|
||||||
|
args.AppendFormat("-crf {0} ", 23);
|
||||||
|
args.AppendFormat("-preset {0} ", "medium");
|
||||||
|
|
||||||
|
// -pix_fmt yuv420p required otherwise can't stream in Chrome
|
||||||
|
// -y for overwrite file
|
||||||
|
args.AppendFormat("-pix_fmt yuv420p -y \"{0}\"", Options.OutputPath);
|
||||||
|
|
||||||
int result = Open(Options.FFmpeg.CLIPath, args.ToString());
|
int result = Open(Options.FFmpeg.CLIPath, args.ToString());
|
||||||
return result == 0;
|
return result == 0;
|
||||||
|
|
|
@ -159,7 +159,7 @@ public void StartRecording()
|
||||||
private void RecordUsingFFmpegCLI()
|
private void RecordUsingFFmpegCLI()
|
||||||
{
|
{
|
||||||
ffMpegCli = new FFmpegCLIHelper(Options);
|
ffMpegCli = new FFmpegCLIHelper(Options);
|
||||||
ffMpegCli.Record();
|
ffMpegCli.Record(CaptureRectangle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecordUsingCache()
|
private void RecordUsingCache()
|
||||||
|
|
Loading…
Reference in a new issue