2025-04-29 16:23:41 +08:00

99 lines
2.5 KiB
C++

#include <iostream>
#include <opencv2/opencv.hpp>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <atomic>
// 全局变量
std::queue<cv::Mat> frameQueue;
std::mutex queueMutex;
std::condition_variable queueCondition;
std::atomic<bool> isRecording(false);
std::atomic<bool> stopRecording(false);
// 帧获取线程函数
void frameCaptureThread() {
cv::VideoCapture cap("/dev/video2");
if (!cap.isOpened()) {
std::cerr << "无法打开摄像头" << std::endl;
return;
}
// 设置分辨率和帧率
cap.set(cv::CAP_PROP_FRAME_WIDTH, 1920);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 1080);
cap.set(cv::CAP_PROP_FPS, 25);
cv::Mat frame;
while (isRecording) {
if (cap.read(frame)) {
std::unique_lock<std::mutex> lock(queueMutex);
frameQueue.push(frame.clone());
lock.unlock();
queueCondition.notify_one();
}
}
cap.release();
}
// 帧保存线程函数
void frameSavingThread(const std::string& outputPath) {
cv::Size frameSize(1920, 1080);
int fps = 25;
cv::VideoWriter writer(outputPath, cv::VideoWriter::fourcc('H', '2', '6', '4'), fps, frameSize);
if (!writer.isOpened()) {
std::cerr << "无法打开视频写入器" << std::endl;
return;
}
while (!stopRecording || !frameQueue.empty()) {
std::unique_lock<std::mutex> lock(queueMutex);
queueCondition.wait(lock, [] { return!frameQueue.empty() || stopRecording; });
while (!frameQueue.empty()) {
cv::Mat frame = frameQueue.front();
frameQueue.pop();
writer.write(frame);
}
}
writer.release();
}
// 开始录像函数
void startRecording(const std::string& outputPath) {
isRecording = true;
stopRecording = false;
std::thread captureThread(frameCaptureThread);
std::thread savingThread(frameSavingThread, outputPath);
captureThread.detach();
savingThread.detach();
}
// 停止录像函数
void stopRecordingFunction() {
isRecording = false;
stopRecording = true;
{
std::unique_lock<std::mutex> lock(queueMutex);
queueCondition.notify_one();
}
}
int main() {
// 定义输出视频的参数
std::string outputPath = "output.mp4";
// 开始录像
startRecording(outputPath);
// 模拟录制一段时间
std::this_thread::sleep_for(std::chrono::seconds(10));
// 停止录像
stopRecordingFunction();
return 0;
}