-
Notifications
You must be signed in to change notification settings - Fork 29
Expand file tree
/
Copy pathccap_cli.cpp
More file actions
193 lines (164 loc) · 6.59 KB
/
Copy pathccap_cli.cpp
File metadata and controls
193 lines (164 loc) · 6.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/**
* @file ccap_cli.cpp
* @brief CLI tool for CameraCapture (ccap) library - Main entry point
* @author wysaid (this@wysaid.org)
* @date 2025-12
*
* A command-line interface for camera capture operations.
* Supports camera enumeration, capture, format conversion, and optional window preview.
*
* This file serves as the main entry point, with functionality split into modules:
* - args_parser: Command-line argument parsing
* - ccap_cli_utils: Device management, format conversion, and preview utilities
*/
#include "args_parser.h"
#include "ccap_cli_utils.h"
#include <ccap.h>
#include <iostream>
namespace {
void logWindowsCameraBackendOverride(const ccap_cli::CLIOptions& opts) {
#if defined(_WIN32) || defined(_WIN64)
if (opts.windowsCameraBackend.empty() || !ccap::infoLogEnabled()) {
return;
}
if (!opts.videoFilePath.empty() || !opts.convertInput.empty()) {
std::cout << "Ignoring Windows camera backend override for non-camera input: "
<< opts.windowsCameraBackend << std::endl;
return;
}
std::cout << "Using Windows camera backend override from CLI: " << opts.windowsCameraBackend << std::endl;
#else
(void)opts;
#endif
}
} // namespace
int main(int argc, char* argv[]) {
if (argc < 2) {
ccap_cli::printUsage(argv[0]);
return 0;
}
auto opts = ccap_cli::parseArgs(argc, argv);
if (opts.showHelp) {
ccap_cli::printUsage(argv[0]);
return 0;
}
if (opts.showVersion) {
ccap_cli::printVersion();
return 0;
}
// Check for conflicting options
if (opts.captureCountSpecified && opts.enableLoop) {
std::cerr << "Error: -c/--count and --loop are mutually exclusive." << std::endl;
std::cerr << "Use -c to limit captured frames, or --loop for video looping, but not both." << std::endl;
return 1;
}
if (opts.fpsSpecified && opts.playbackSpeedSpecified) {
std::cerr << "Error: -f/--fps and --speed are mutually exclusive." << std::endl;
std::cerr << "Use -f/--fps for camera frame rate or video playback rate, or --speed for explicit playback speed control, but not both." << std::endl;
return 1;
}
// --loop only applies to video mode
if (opts.enableLoop && opts.videoFilePath.empty()) {
std::cerr << "Warning: --loop option is only effective for video file playback." << std::endl;
}
// --save requires -o
if (opts.saveFrames && opts.outputDir.empty()) {
std::cerr << "Error: --save requires -o/--output to specify output directory." << std::endl;
return 1;
}
// Set log level based on options
if (opts.verbose) {
ccap::setLogLevel(ccap::LogLevel::Verbose);
} else {
// Check if -q/--quiet was specified by looking at argv
bool quietMode = false;
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
if (arg == "-q" || arg == "--quiet") {
quietMode = true;
break;
}
}
if (quietMode) {
ccap::setLogLevel(ccap::LogLevel::Error);
} else {
ccap::setLogLevel(ccap::LogLevel::Info);
}
}
// Set error callback
ccap::setErrorCallback([](ccap::ErrorCode errorCode, std::string_view description) {
std::cerr << "Camera Error - Code: " << static_cast<int>(errorCode)
<< ", Description: " << description << std::endl;
});
logWindowsCameraBackendOverride(opts);
// Handle different modes
if (opts.listDevices) {
return ccap_cli::listDevices(opts);
}
if (opts.showDeviceInfo) {
return ccap_cli::showDeviceInfo(opts, opts.deviceInfoIndex);
}
if (!opts.convertInput.empty()) {
return ccap_cli::convertYuvToImage(opts);
}
// Check if we should just print info (no action specified)
bool hasAction = opts.enablePreview || opts.saveFrames || opts.captureCountSpecified || !opts.outputDir.empty();
// Check if video file playback is requested but not supported on Linux
#if defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
if (!opts.videoFilePath.empty()) {
if (!hasAction) {
return ccap_cli::printVideoInfo(opts, opts.videoFilePath);
}
std::cerr << "Error: Video file playback is not supported on Linux.\n"
<< "\n"
<< "Video file playback is currently only available on:\n"
<< " - Windows (using Media Foundation)\n"
<< " - macOS (using AVFoundation)\n"
<< "\n"
<< "Linux support may be added in future versions.\n"
<< "For now, you can:\n"
<< " - Use Windows or macOS for video processing\n"
<< " - Download pre-built binaries from: https://ccap.work\n"
<< std::endl;
return 1;
}
#endif
// If video file specified without action, print video info
if (!opts.videoFilePath.empty() && !hasAction) {
return ccap_cli::printVideoInfo(opts, opts.videoFilePath);
}
// If camera device specified without action, print camera info
if (opts.videoFilePath.empty() && !hasAction &&
(opts.inputSource.empty() || !opts.deviceName.empty() || opts.deviceIndex >= 0)) {
// Print camera info (equivalent to --device-info)
if (!opts.deviceName.empty()) {
return ccap_cli::showDeviceInfo(opts, opts.deviceName);
}
return ccap_cli::showDeviceInfo(opts, opts.deviceIndex);
}
#ifdef CCAP_CLI_WITH_GLFW
if (opts.enablePreview) {
return ccap_cli::runPreview(opts);
}
#else
if (opts.enablePreview) {
std::cerr << "Error: Preview feature is not available in this build.\n"
<< "\n"
<< "To use --preview functionality:\n"
<< " 1. Download a pre-built version with preview support from: https://ccap.work\n"
<< " 2. Or rebuild the CLI tool with GLFW support:\n"
<< " - Install GLFW development library: sudo apt-get install libglfw3-dev\n"
<< " (or equivalent package manager command for your system)\n"
<< " - Rebuild with: cmake -DCCAP_CLI_WITH_GLFW=ON ..\n"
<< std::endl;
return 1;
}
#endif
// Default: capture mode
if (!opts.outputDir.empty() || opts.captureCountSpecified || opts.saveFrames) {
return ccap_cli::captureFrames(opts);
}
// No specific action, show help
ccap_cli::printUsage(argv[0]);
return 0;
}