在OSX中使用CGDisplayStream指定录屏文件路径并添加时间戳
Hey there! Great job getting your C++ command-line screen recorder up and running. Let's walk through how to add custom save paths and timestamped filenames, plus some optimizations to make your tool even better.
1. Adding Custom Save Paths & Timestamped Filenames
First, we'll use C++17's <filesystem> library (cross-platform, works on Windows/Linux/macOS) to handle path operations and <chrono> to generate precise timestamps. Here's how to integrate this into your code:
Step 1: Include Required Headers
Add these to your existing includes:
#include <iostream> #include <filesystem> #include <chrono> #include <iomanip> #include <string> // Keep your existing screen capture headers (e.g., <Windows.h> for Windows, X11 headers for Linux)
Step 2: Generate Timestamped Filenames
This function creates a filename with a human-readable timestamp (e.g., screen_recording_20240520_154230.mp4):
std::string generate_timestamped_filename(const std::string& extension = ".mp4") { auto now = std::chrono::system_clock::now(); auto time_t_now = std::chrono::system_clock::to_time_t(now); // Format timestamp as YYYYMMDD_HHMMSS for sorting and readability std::ostringstream oss; oss << std::put_time(std::localtime(&time_t_now), "%Y%m%d_%H%M%S"); return "screen_recording_" + oss.str() + extension; }
Step 3: Handle Custom Save Paths
Validate and prepare the user-specified path (or use a default if none is provided):
std::filesystem::path get_save_path(const std::string& user_path = "") { std::filesystem::path save_path; if (!user_path.empty()) { save_path = std::filesystem::absolute(user_path); // Create directory if it doesn't exist if (!std::filesystem::exists(save_path)) { std::filesystem::create_directories(save_path); std::cout << "Created directory: " << save_path << std::endl; } } else { // Default to current working directory save_path = std::filesystem::current_path(); } // Append the timestamped filename to the path save_path /= generate_timestamped_filename(); return save_path; }
Step 4: Integrate Into Your Recording Logic
Use the generated path when writing your recording to disk:
int main() { // Get user-specified path (we'll improve this with command-line args below) std::string user_input_path; std::cout << "Enter save path (leave blank for current directory): "; std::getline(std::cin, user_input_path); std::filesystem::path output_path = get_save_path(user_input_path); std::cout << "Recording will be saved to: " << output_path << std::endl; // Your existing screen recording logic here... // Example file write: FILE* fp = fopen(output_path.string().c_str(), "wb"); return 0; }
2. Better Implementation Suggestions
Here are some tweaks to make your tool more robust and user-friendly:
- Command-Line Argument Parsing: Replace manual stdin input with
getopt(POSIX) or a lightweight library likecxxoptsto handle flags like--outputor-ofor the save path. This makes it scriptable and easier to use. - Error Handling: Add checks for write permissions, disk space, and invalid path characters. Print clear error messages (e.g., "Permission denied for path: X") instead of silently failing.
- Cross-Platform Abstraction: If targeting multiple OSes, split screen capture logic into platform-specific modules (e.g.,
WindowsCapture.h,LinuxCapture.h) so path handling stays consistent. - Configurable Formats: Let users specify video extensions (
.avi,.mkv) via command line, and adjust your recording logic to match the format. - Threaded I/O: Offload file writing to a separate thread to avoid frame drops from slow disk operations. Use a thread-safe queue to pass captured frames between the recording and writing threads.
Notes
- Ensure your compiler supports C17 or later (add
-std=c++17to GCC/Clang flags, or set the C standard in Visual Studio) to use<filesystem>. - For older C++ versions, use
std::time+strftimefor timestamps and platform-specific path functions (e.g.,CreateDirectoryon Windows,mkdiron Linux) instead of<filesystem>.
内容的提问来源于stack exchange,提问作者Nikhil Nilawar

