Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@

本程序通过以下三个命令行参数进行控制:

* `--pid <PID>`: 指定目标进程的 ID。此参数在模式 `1` `2` 中为必需参数
* `--pid <PID>`: 指定目标进程的 ID。此参数在模式 `1` 中为必需参数。模式 `2` 如果没提供 PID,将会排除自身 (把自己的 PID 输入进去)
* `--mode <MODE>`: 设置录制模式。此参数必需。
* `0`: 全局环回模式
* `1`: 进程包含模式
Expand Down Expand Up @@ -101,6 +101,18 @@
ProcessAudioRecorder.exe --pid 9999 --mode 2 --path D:\meeting_audio.wav
```

**模式3增强模式:进程排除模式 (排除自身)**

* **场景**:您需要录制所有系统声音 (模式1),但录出来的音质很差,这时候就可尝试这种模式。
* **命令**:
```shell
ProcessAudioRecorder.exe --mode 2 --path d:\Recording.wav
```
也可以用简单写法:
```shell
ProcessAudioRecorder.exe d:\Recording.wav
```

##### **2.2.4 停止录制**

当命令执行成功后,程序将开始录音,您将在控制台窗口看到类似于如下实时状态信息:
Expand Down
62 changes: 53 additions & 9 deletions source/ProcessAudioRecorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ struct CommandLineArgs {
int captureMode = 1;
std::wstring outputPath;
bool isValid = false;
bool pidProvided = false;
std::wstring errorMessage;
};

Expand All @@ -46,6 +47,34 @@ CommandLineArgs ParseCommandLine(int argc, wchar_t* argv[]) {
args.errorMessage = L"Error: Too few arguments.";
return args;
}

bool hasOptionArgs = false;
for (int i = 1; i < argc; i++) {
std::wstring arg = argv[i];
if (arg.rfind(L"--", 0) == 0) {
hasOptionArgs = true;
break;
}
}

if (!hasOptionArgs) {
if (argc != 2) {
args.errorMessage = L"Error: Invalid positional arguments. Expected: <PATH>.";
return args;
}

args.outputPath = argv[1];
if (args.outputPath.empty()) {
args.errorMessage = L"Error: Output path cannot be empty.";
return args;
}

args.captureMode = 2;
args.processId = GetCurrentProcessId();
args.pidProvided = false;
args.isValid = true;
return args;
}
std::map<std::wstring, std::wstring> params;
for (int i = 1; i < argc; i++) {
std::wstring arg = argv[i];
Expand Down Expand Up @@ -89,14 +118,21 @@ CommandLineArgs ParseCommandLine(int argc, wchar_t* argv[]) {

if (args.captureMode == 1 || args.captureMode == 2) {
if (params.find(L"pid") == params.end()) {
args.errorMessage = L"Error: Missing required argument --pid for mode 1 or 2.";
return args;
if (args.captureMode == 1) {
args.errorMessage = L"Error: Missing required argument --pid for mode 1.";
return args;
}
args.processId = GetCurrentProcessId();
args.pidProvided = false;
}
args.processId = std::wcstoul(params[L"pid"].c_str(), &endPtr, 10);
if (endPtr == params[L"pid"].c_str() || *endPtr != L'\0' || args.processId == 0) {
args.errorMessage = L"Error: Invalid process ID: " + params[L"pid"] +
L"\nMust be a positive integer.";
return args;
else {
args.processId = std::wcstoul(params[L"pid"].c_str(), &endPtr, 10);
if (endPtr == params[L"pid"].c_str() || *endPtr != L'\0' || args.processId == 0) {
args.errorMessage = L"Error: Invalid process ID: " + params[L"pid"] +
L"\nMust be a positive integer.";
return args;
}
args.pidProvided = true;
}
}

Expand All @@ -106,7 +142,8 @@ CommandLineArgs ParseCommandLine(int argc, wchar_t* argv[]) {

void usage() {
std::wcout << L"Process Audio Recorder - Captures audio from processes or the entire system\n\n"
<< L"Usage: ProcessAudioRecorder [--pid <PID>] --mode <MODE> --path <FILEPATH>\n\n"
<< L"Usage: ProcessAudioRecorder [--pid <PID>] --mode <MODE> --path <FILEPATH>\n"
<< L" ProcessAudioRecorder <FILEPATH>\n\n"
<< L"Options:\n"
<< L" --pid <PID> Target process ID (required for mode 1 and 2)\n"
<< L" --mode <MODE> Capture mode (required):\n"
Expand All @@ -117,7 +154,10 @@ void usage() {
<< L"Examples:\n"
<< L" ProcessAudioRecorder --mode 0 --path C:\\system_audio.wav\n"
<< L" ProcessAudioRecorder --pid 1234 --mode 1 --path C:\\record.wav\n"
<< L" ProcessAudioRecorder --pid 5678 --path D:\\audio.wav\n\n"
<< L" ProcessAudioRecorder --pid 5678 --path D:\\audio.wav\n"
<< L" ProcessAudioRecorder --mode 2 --path D:\\audio.wav\n"
<< L" ProcessAudioRecorder --mode 2 --pid 12345 --path D:\\audio.wav\n"
<< L" ProcessAudioRecorder D:\\audio.wav\n\n"
<< L"Exit conditions:\n"
<< L" - Target process exits (for mode 1 and 2)\n"
<< L" - User presses Ctrl+C\n";
Expand Down Expand Up @@ -174,6 +214,10 @@ int wmain(int argc, wchar_t* argv[]) {
hr = loopbackCapture.StartGlobalCaptureAsync(args.outputPath.c_str());
}
else {
if (args.captureMode == 2 && !args.pidProvided) {
std::wcout << L"No --pid provided for mode 2. Defaulting to exclude self (PID "
<< args.processId << L")." << std::endl;
}
if (!IsProcessRunning(args.processId)) {
std::wcout << L"Error: Process with ID " << args.processId << L" does not exist or cannot be accessed." << std::endl;
return 3;
Expand Down