前言
Qt6提供了更丰富的多媒体支持类,使用Qt6 QMediaCaptureSession、QScreenCapture、QMediaRecorder,来实现一个屏幕录制的demo,其中QScreenCapture 最低版本 Qt6.5。支持录制的清晰度设置,选择视频保存位置,UI使用QML来实现。
Qt6还有一个比较好用的类 QWindowCapture, 可以针对窗口录屏。使用静态函数 QList<QCapturableWindow> capturableWindows()
可以获取当前可用的录制窗口,选择窗口进行录制。可以在本demo的基础上进行扩展。
效果图
本demo使用Qt6.8 MinGW进行编译,注意QScreenCapture最低支持Qt6.5,所以版本不能低于6.5.
正文
主要使用Qt6 QMediaCaptureSession、QScreenCapture、QMediaRecorder这三个关键的多媒体类来实现。
关键代码:
开始录制和结束录制:
void ScreenRecorder::startRecording()
{if (m_isRecording) {qDebug() << __FUNCTION__ << "Already recording, ignoring request";return;}qDebug() << __FUNCTION__ << "Starting recording process...";// 选择保存文件QString defaultPath = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation);QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss");QString defaultFileName = QString("%1/ScreenRecording_%2.mp4").arg(defaultPath).arg(timestamp);qDebug() << __FUNCTION__ << "Default save path:" << defaultFileName;QString filePath = QFileDialog::getSaveFileName(nullptr,tr("Save Recording"),defaultFileName,tr("Video Files (*.mp4)"));if (filePath.isEmpty()) {qDebug() << __FUNCTION__ << "User cancelled file selection";m_statusMessage = tr("Recording cancelled");emit statusMessageChanged();return;}qDebug() << __FUNCTION__ << "Selected file path:" << filePath;// 确保目录存在QFileInfo fileInfo(filePath);QDir dir = fileInfo.dir();if (!dir.exists()) {qDebug() << __FUNCTION__ << "Creating directory:" << dir.path();if (!dir.mkpath(".")) {qDebug() << __FUNCTION__ << "Failed to create directory";m_statusMessage = tr("Error: Could not create directory");emit statusMessageChanged();return;}}// 设置输出位置QUrl fileUrl = QUrl::fromLocalFile(filePath);qDebug() << __FUNCTION__ << "Setting output location:" << fileUrl.toString();m_recorder.setOutputLocation(fileUrl);// 更新质量设置updateQualitySettings();// 开始录制qDebug() << __FUNCTION__ << "Starting recorder...";m_recorder.record();// 启动计时器m_elapsedTimer.start();m_timer.start(1000); // 每秒更新一次m_isRecording = true;m_statusMessage = tr("Recording started");emit isRecordingChanged();emit statusMessageChanged();qDebug() << __FUNCTION__ << "Recording started successfully";
}void ScreenRecorder::stopRecording()
{if (!m_isRecording) {return;}qDebug() << __FUNCTION__ << "Stopping recording...";// 获取当前输出位置,用于验证QUrl outputLocation = m_recorder.outputLocation();qDebug() << __FUNCTION__ << "Output location:" << outputLocation.toLocalFile();// 停止录制m_recorder.stop();// 停止计时器m_timer.stop();// 检查文件是否存在QString filePath = outputLocation.toLocalFile();QFileInfo fileInfo(filePath);if (fileInfo.exists()) {qDebug() << __FUNCTION__ << "File saved successfully at:" << filePath;qDebug() << __FUNCTION__ << "File size:" << fileInfo.size() << "bytes";m_statusMessage = tr("Recording saved to %1").arg(filePath);} else {qDebug() << __FUNCTION__ << "Error: File not created at:" << filePath;m_statusMessage = tr("Error: Recording file not created");}m_isRecording = false;emit isRecordingChanged();emit statusMessageChanged();
}
设置录制器:
void ScreenRecorder::setupRecorder()
{qDebug() << __FUNCTION__ << "Setting up recorder...";// 设置捕获会话m_captureSession.setScreenCapture(&m_screenCapture);m_captureSession.setRecorder(&m_recorder);// 设置屏幕捕获m_screenCapture.setScreen(QGuiApplication::primaryScreen());m_screenCapture.setActive(true); // 激活屏幕捕获qDebug() << __FUNCTION__ << "Screen set to:" << QGuiApplication::primaryScreen()->name();qDebug() << __FUNCTION__ << "Screen capture active:" << m_screenCapture.isActive();// 设置录制器QMediaFormat format;format.setFileFormat(QMediaFormat::FileFormat::MPEG4);format.setVideoCodec(QMediaFormat::VideoCodec::H264);// 检查编解码器是否支持QList<QMediaFormat::VideoCodec> supportedCodecs = format.supportedVideoCodecs(QMediaFormat::Encode);qDebug() << __FUNCTION__ << "Supported video codecs:" << supportedCodecs;if (!supportedCodecs.contains(QMediaFormat::VideoCodec::H264)) {qDebug() << __FUNCTION__ << "Warning: H264 codec may not be supported";// 尝试使用第一个可用的编解码器if (!supportedCodecs.isEmpty()) {format.setVideoCodec(supportedCodecs.first());qDebug() << __FUNCTION__ << "Using alternative codec:" << supportedCodecs.first();}}m_recorder.setMediaFormat(format);qDebug() << __FUNCTION__ << "Media format set:" << format.fileFormat() << format.videoCodec();// 应用当前质量设置updateQualitySettings();// 连接信号connect(&m_recorder, &QMediaRecorder::recorderStateChanged,this, &ScreenRecorder::handleRecorderStateChanged);connect(&m_recorder, &QMediaRecorder::errorOccurred,this, &ScreenRecorder::handleError);qDebug() << __FUNCTION__ << "Recorder setup complete";
}
该功能是Qt结合ffmpeg来实现的,运行时会输出相关信息:qt.multimedia.ffmpeg: Using Qt multimedia with FFmpeg version 7.1 LGPL version 2.1 or later
Qt6还提供了很多非常好用的多媒体类,可以实现很多丰富的功能。本文仅演示基础使用,在此demo上可进行更多的扩展。
本文demo下载