forked from Mercury/2dxAutoClip
Update 2dxAutoClip/iidxAutoClip.cs
Disable asio recording.
This commit is contained in:
parent
82fb949125
commit
cc70624b54
|
@ -3,25 +3,22 @@ using System.Net.WebSockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using NAudio.CoreAudioApi;
|
using NAudio.CoreAudioApi;
|
||||||
using NAudio.Wave;
|
using NAudio.Wave;
|
||||||
#pragma warning disable CA1416
|
|
||||||
|
|
||||||
namespace _2dxAutoClip
|
namespace _2dxAutoClip;
|
||||||
|
|
||||||
|
class Program
|
||||||
{
|
{
|
||||||
class Program
|
|
||||||
{
|
|
||||||
private static readonly string WebsocketAddress = "localhost";
|
private static readonly string WebsocketAddress = "localhost";
|
||||||
private static readonly int WebsocketPort = 10573;
|
private static readonly int WebsocketPort = 10573;
|
||||||
private static Process? _ffmpegProcess;
|
private static Process? _ffmpegProcess;
|
||||||
private static string _ffmpegFolderPath = GetDefaultVideosFolderPath();
|
private static string _ffmpegFolderPath = GetDefaultVideosFolderPath();
|
||||||
private static WasapiCapture? _waveSource;
|
private static WasapiCapture? _waveSource;
|
||||||
private static AsioOut? _asioSource;
|
|
||||||
private static WaveFileWriter _writer = null!;
|
private static WaveFileWriter _writer = null!;
|
||||||
private static string _audioFilePath = null!;
|
private static string _audioFilePath = null!;
|
||||||
private static string _videoFilePath = null!;
|
private static string _videoFilePath = null!;
|
||||||
private static string _resolution = "1920x1080"; // Default resolution
|
private static string _resolution = "1920x1080"; // Default resolution
|
||||||
private static int _framerate = 60; // Default framerate
|
private static int _framerate = 60; // Default framerate
|
||||||
private static float _crf = 23; // Default CRF value
|
private static float _crf = 23; // Default CRF value
|
||||||
private static bool _useAsio = false;
|
|
||||||
private static string _gameProcessName = "spice64"; // Default game process name
|
private static string _gameProcessName = "spice64"; // Default game process name
|
||||||
|
|
||||||
private static async Task Main(string[] args)
|
private static async Task Main(string[] args)
|
||||||
|
@ -56,43 +53,33 @@ namespace _2dxAutoClip
|
||||||
if (Directory.Exists(path))
|
if (Directory.Exists(path))
|
||||||
{
|
{
|
||||||
_ffmpegFolderPath = path; // Recording path
|
_ffmpegFolderPath = path; // Recording path
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Console.WriteLine(
|
Console.WriteLine($"The path specified in {filePath} does not exist. Using default recording path.");
|
||||||
$"The path specified in {filePath} does not exist. Using default recording path.");
|
|
||||||
_ffmpegFolderPath = GetDefaultVideosFolderPath();
|
_ffmpegFolderPath = GetDefaultVideosFolderPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.StartsWith("resolution:"))
|
if (line.StartsWith("resolution:"))
|
||||||
{
|
{
|
||||||
_resolution = line["resolution:".Length..].Trim();
|
_resolution = line["resolution:".Length..].Trim();
|
||||||
Console.WriteLine($"Custom Resolution: {_resolution}");
|
Console.WriteLine($"Custom Resolution: {_resolution}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.StartsWith("framerate:"))
|
if (line.StartsWith("framerate:"))
|
||||||
{
|
{
|
||||||
_framerate = int.Parse(line["framerate:".Length..].Trim());
|
_framerate = int.Parse(line["framerate:".Length..].Trim());
|
||||||
Console.WriteLine($"Custom framerate: {_framerate}");
|
Console.WriteLine($"Custom framerate: {_framerate}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.StartsWith("crf:"))
|
if (line.StartsWith("crf:"))
|
||||||
{
|
{
|
||||||
_crf = float.Parse(line["crf:".Length..].Trim());
|
_crf = float.Parse(line["crf:".Length..].Trim());
|
||||||
Console.WriteLine($"Custom crf: {_crf}");
|
Console.WriteLine($"custom crf: {_crf}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.StartsWith("game_process_name:"))
|
if (line.StartsWith("game_process_name:"))
|
||||||
{
|
{
|
||||||
_gameProcessName = line["game_process_name:".Length..].Trim();
|
_gameProcessName = line["game_process_name:".Length..].Trim();
|
||||||
Console.WriteLine($"Custom process name: {_gameProcessName}");
|
Console.WriteLine($"custom process name: {_gameProcessName}");
|
||||||
}
|
|
||||||
|
|
||||||
if (line.StartsWith("useAsio"))
|
|
||||||
{
|
|
||||||
_useAsio = line.Split('=')[1].Trim().ToLower() == "true";
|
|
||||||
Console.WriteLine("ASIO Recording is enabled");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,7 +112,6 @@ namespace _2dxAutoClip
|
||||||
await Task.Delay(10000);
|
await Task.Delay(10000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attempt == maxRetries)
|
if (attempt == maxRetries)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Failed to connect after 5 attempts.");
|
Console.WriteLine("Failed to connect after 5 attempts.");
|
||||||
|
@ -216,24 +202,6 @@ namespace _2dxAutoClip
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void StartAudioRecording(string songName)
|
private static void StartAudioRecording(string songName)
|
||||||
{
|
|
||||||
if (_useAsio)
|
|
||||||
{
|
|
||||||
var staThread = new Thread(() =>
|
|
||||||
{
|
|
||||||
StartAsioAudioRecording(songName);
|
|
||||||
});
|
|
||||||
staThread.SetApartmentState(ApartmentState.STA);
|
|
||||||
staThread.Start();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StartWasapiAudioRecording(songName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static void StartWasapiAudioRecording(string songName)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -242,7 +210,10 @@ namespace _2dxAutoClip
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(_audioFilePath)!);
|
Directory.CreateDirectory(Path.GetDirectoryName(_audioFilePath)!);
|
||||||
_waveSource = new WasapiLoopbackCapture();
|
_waveSource = new WasapiLoopbackCapture();
|
||||||
_writer = new WaveFileWriter(_audioFilePath, _waveSource.WaveFormat);
|
_writer = new WaveFileWriter(_audioFilePath, _waveSource.WaveFormat);
|
||||||
_waveSource.DataAvailable += (sender, args) => { _writer.Write(args.Buffer, 0, args.BytesRecorded); };
|
_waveSource.DataAvailable += (sender, args) =>
|
||||||
|
{
|
||||||
|
_writer.Write(args.Buffer, 0, args.BytesRecorded);
|
||||||
|
};
|
||||||
_waveSource.RecordingStopped += (sender, args) =>
|
_waveSource.RecordingStopped += (sender, args) =>
|
||||||
{
|
{
|
||||||
_writer.Dispose();
|
_writer.Dispose();
|
||||||
|
@ -253,51 +224,34 @@ namespace _2dxAutoClip
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Error starting WASAPI audio recording: {ex.Message}");
|
Console.WriteLine($"Error starting audio recording: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void StartAsioAudioRecording(string songName)
|
private static void StartFfmpegRecording(string songName)
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var date = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
|
var date = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
|
||||||
_audioFilePath = $"{_ffmpegFolderPath}\\{songName}_{date}.wav";
|
_videoFilePath = $"{_ffmpegFolderPath}\\{songName}_{date}.mkv";
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(_audioFilePath)!);
|
var ffmpegArguments = $"-framerate {_framerate} " +
|
||||||
|
$"-filter_complex \"ddagrab=framerate={_framerate},hwdownload,format=bgra\" " +
|
||||||
_asioSource = new AsioOut(0);
|
$"-c:v libx264 -tune zerolatency -crf {_crf} -video_size {_resolution} -movflags +faststart -y \"{_videoFilePath}\"";
|
||||||
_asioSource.InitRecordAndPlayback(null, 0, 48000);
|
_ffmpegProcess = new Process
|
||||||
|
|
||||||
_writer = new WaveFileWriter(_audioFilePath, new WaveFormat(44100, 16, 2));
|
|
||||||
|
|
||||||
_asioSource.AudioAvailable += (s, e) =>
|
|
||||||
{
|
{
|
||||||
var buffer = new byte[e.SamplesPerBuffer * 4];
|
StartInfo = new ProcessStartInfo
|
||||||
int bufferIndex = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < e.SamplesPerBuffer; i++)
|
|
||||||
{
|
{
|
||||||
short sampleL = (short)(e.GetAsInterleavedSamples()[i * 2] * short.MaxValue);
|
FileName = "ffmpeg",
|
||||||
short sampleR = (short)(e.GetAsInterleavedSamples()[i * 2 + 1] * short.MaxValue);
|
Arguments = ffmpegArguments,
|
||||||
|
UseShellExecute = false,
|
||||||
buffer[bufferIndex++] = (byte)(sampleL & 0xFF);
|
RedirectStandardError = true,
|
||||||
buffer[bufferIndex++] = (byte)((sampleL >> 8) & 0xFF);
|
CreateNoWindow = true
|
||||||
buffer[bufferIndex++] = (byte)(sampleR & 0xFF);
|
|
||||||
buffer[bufferIndex++] = (byte)((sampleR >> 8) & 0xFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_writer.Write(buffer, 0, buffer.Length);
|
|
||||||
};
|
};
|
||||||
|
_ffmpegProcess.ErrorDataReceived += (_, args) => Console.WriteLine(args.Data);
|
||||||
|
_ffmpegProcess.Start();
|
||||||
|
_ffmpegProcess.BeginErrorReadLine();
|
||||||
|
|
||||||
_asioSource.Play();
|
Console.WriteLine("FFmpeg recording started.");
|
||||||
Console.WriteLine("ASIO Audio recording started.");
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Error starting ASIO audio recording: {ex.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static void StopRecording(string songName)
|
private static void StopRecording(string songName)
|
||||||
{
|
{
|
||||||
|
@ -307,45 +261,9 @@ namespace _2dxAutoClip
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void StopAudioRecording()
|
private static void StopAudioRecording()
|
||||||
{
|
|
||||||
if (_useAsio)
|
|
||||||
{
|
|
||||||
StopAsioAudioRecording();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StopWasapiAudioRecording();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void StopWasapiAudioRecording()
|
|
||||||
{
|
{
|
||||||
_waveSource?.StopRecording();
|
_waveSource?.StopRecording();
|
||||||
_waveSource = null;
|
Console.WriteLine("WASAPI Audio recording stopped.");
|
||||||
}
|
|
||||||
|
|
||||||
private static void StopAsioAudioRecording()
|
|
||||||
{
|
|
||||||
_asioSource?.Stop();
|
|
||||||
_asioSource?.Dispose();
|
|
||||||
_asioSource = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void StartFfmpegRecording(string songName)
|
|
||||||
{
|
|
||||||
var date = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
|
|
||||||
_videoFilePath = $"{_ffmpegFolderPath}\\{songName}_{date}.mkv";
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(_videoFilePath)!);
|
|
||||||
var ffmpegArgs =
|
|
||||||
$"-f dshow -framerate {_framerate} -i video=\"screen-capture-recorder\" -c:v libx264 -preset ultrafast -crf {_crf} -r {_framerate} -s {_resolution} \"{_videoFilePath}\"";
|
|
||||||
var startInfo = new ProcessStartInfo
|
|
||||||
{
|
|
||||||
FileName = "ffmpeg",
|
|
||||||
Arguments = ffmpegArgs,
|
|
||||||
UseShellExecute = false,
|
|
||||||
CreateNoWindow = true
|
|
||||||
};
|
|
||||||
_ffmpegProcess = Process.Start(startInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void StopFfmpegRecording()
|
private static void StopFfmpegRecording()
|
||||||
|
@ -353,8 +271,9 @@ namespace _2dxAutoClip
|
||||||
if (_ffmpegProcess != null && !_ffmpegProcess.HasExited)
|
if (_ffmpegProcess != null && !_ffmpegProcess.HasExited)
|
||||||
{
|
{
|
||||||
_ffmpegProcess.Kill();
|
_ffmpegProcess.Kill();
|
||||||
_ffmpegProcess.Dispose();
|
_ffmpegProcess.WaitForExit();
|
||||||
_ffmpegProcess = null;
|
_ffmpegProcess = null!;
|
||||||
|
Console.WriteLine("FFmpeg recording stopped.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static void CombineAudioAndVideo(string videoFilePath, string audioFilePath, string songName)
|
private static void CombineAudioAndVideo(string videoFilePath, string audioFilePath, string songName)
|
||||||
|
@ -392,5 +311,4 @@ namespace _2dxAutoClip
|
||||||
File.Delete(videoFilePath);
|
File.Delete(videoFilePath);
|
||||||
File.Delete(audioFilePath);
|
File.Delete(audioFilePath);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue