Qt6+QML實(shí)現(xiàn)Windows屏幕錄制功能
前言
Qt6提供了更豐富的多媒體支持類(lèi),使用Qt6 QMediaCaptureSession、QScreenCapture、QMediaRecorder,來(lái)實(shí)現(xiàn)一個(gè)屏幕錄制的demo,其中QScreenCapture 最低版本 Qt6.5。支持錄制的清晰度設(shè)置,選擇視頻保存位置,UI使用QML來(lái)實(shí)現(xiàn)。
Qt6還有一個(gè)比較好用的類(lèi) QWindowCapture, 可以針對(duì)窗口錄屏。使用靜態(tài)函數(shù) QList<QCapturableWindow> capturableWindows()
可以獲取當(dāng)前可用的錄制窗口,選擇窗口進(jìn)行錄制??梢栽诒綿emo的基礎(chǔ)上進(jìn)行擴(kuò)展。
效果圖
本demo使用Qt6.8 MinGW進(jìn)行編譯,注意QScreenCapture最低支持Qt6.5,所以版本不能低于6.5.
完整代碼
主要使用Qt6 QMediaCaptureSession、QScreenCapture、QMediaRecorder這三個(gè)關(guān)鍵的多媒體類(lèi)來(lái)實(shí)現(xiàn)。
關(guān)鍵代碼:
開(kāi)始錄制和結(jié)束錄制:
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; } } // 設(shè)置輸出位置 QUrl fileUrl = QUrl::fromLocalFile(filePath); qDebug() << __FUNCTION__ << "Setting output location:" << fileUrl.toString(); m_recorder.setOutputLocation(fileUrl); // 更新質(zhì)量設(shè)置 updateQualitySettings(); // 開(kāi)始錄制 qDebug() << __FUNCTION__ << "Starting recorder..."; m_recorder.record(); // 啟動(dòng)計(jì)時(shí)器 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..."; // 獲取當(dāng)前輸出位置,用于驗(yàn)證 QUrl outputLocation = m_recorder.outputLocation(); qDebug() << __FUNCTION__ << "Output location:" << outputLocation.toLocalFile(); // 停止錄制 m_recorder.stop(); // 停止計(jì)時(shí)器 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(); }
設(shè)置錄制器:
void ScreenRecorder::setupRecorder() { qDebug() << __FUNCTION__ << "Setting up recorder..."; // 設(shè)置捕獲會(huì)話(huà) m_captureSession.setScreenCapture(&m_screenCapture); m_captureSession.setRecorder(&m_recorder); // 設(shè)置屏幕捕獲 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(); // 設(shè)置錄制器 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"; // 嘗試使用第一個(gè)可用的編解碼器 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(); // 應(yīng)用當(dāng)前質(zhì)量設(shè)置 updateQualitySettings(); // 連接信號(hào) connect(&m_recorder, &QMediaRecorder::recorderStateChanged, this, &ScreenRecorder::handleRecorderStateChanged); connect(&m_recorder, &QMediaRecorder::errorOccurred, this, &ScreenRecorder::handleError); qDebug() << __FUNCTION__ << "Recorder setup complete"; }
該功能是Qt結(jié)合ffmpeg來(lái)實(shí)現(xiàn)的,運(yùn)行時(shí)會(huì)輸出相關(guān)信息:qt.multimedia.ffmpeg: Using Qt multimedia with FFmpeg version 7.1 LGPL version 2.1 or later
Qt6還提供了很多非常好用的多媒體類(lèi),可以實(shí)現(xiàn)很多豐富的功能。
到此這篇關(guān)于Qt6+QML實(shí)現(xiàn)Windows屏幕錄制功能的文章就介紹到這了,更多相關(guān)Qt6屏幕錄制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++基類(lèi)指針和派生類(lèi)指針之間的轉(zhuǎn)換方法講解
今天小編就為大家分享一篇關(guān)于C++基類(lèi)指針和派生類(lèi)指針之間的轉(zhuǎn)換方法講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-04-04C語(yǔ)言中#pragma?pack(1)的用法與注意點(diǎn)
#pragma用于指示編譯器完成一些特定的動(dòng)作,下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言中#pragma?pack(1)的用法與注意點(diǎn)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02C++ Boost Thread線(xiàn)程使用示例詳解
Boost是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱(chēng)。Boost庫(kù)是一個(gè)可移植、提供源代碼的C++庫(kù),作為標(biāo)準(zhǔn)庫(kù)的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開(kāi)發(fā)引擎之一,是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱(chēng)2022-11-11使用C++實(shí)現(xiàn)一個(gè)高效的線(xiàn)程池
在多線(xiàn)程編程中,線(xiàn)程池是一種常見(jiàn)且高效的設(shè)計(jì)模式,本文將詳細(xì)介紹如何使用C++實(shí)現(xiàn)一個(gè)線(xiàn)程池,并解析相關(guān)代碼實(shí)現(xiàn)細(xì)節(jié),需要的小伙伴可以參考下2024-12-12C/C++?for?語(yǔ)句的要點(diǎn)與注意事項(xiàng)小結(jié)
C/C++ 中的?for?語(yǔ)句是一種常用的循環(huán)結(jié)構(gòu),用于重復(fù)執(zhí)行一段代碼,直到滿(mǎn)足某個(gè)條件為止,這篇文章主要介紹了C/C++?for?語(yǔ)句的要點(diǎn)與注意事項(xiàng),需要的朋友可以參考下2024-06-06C++實(shí)現(xiàn)掃雷游戲(控制臺(tái)不閃屏版)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)掃雷游戲,控制臺(tái)不閃屏版,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-03-03