Skip to content

Commit 4bba3b6

Browse files
committed
Plugins::WebBrowser: modify record
1 parent 91f2225 commit 4bba3b6

File tree

5 files changed

+122
-36
lines changed

5 files changed

+122
-36
lines changed

App/Client/main.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
// Author: Kang Lin <[email protected]>
22

33
/*!
4-
* \~english \defgroup VIEWER_APP Rabbit remote control programe
4+
* \~english
5+
* \defgroup VIEWER_APP Rabbit remote control programe
56
* \brief Rabbit remote control programe
6-
*
7-
* \~chinese \defgroup VIEWER_APP 玉兔远程控制程序
7+
*
8+
* \~chinese
9+
* \defgroup VIEWER_APP 玉兔远程控制程序
810
* \brief 玉兔远程控制程序
11+
*
912
* \~
1013
* \ingroup APP
11-
*
1214
*/
1315

1416
#include <QLoggingCategory>
@@ -20,6 +22,9 @@
2022
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
2123
#include <QRegularExpression>
2224
#endif
25+
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
26+
#include <QRandomGenerator>
27+
#endif
2328
#if defined(Q_OS_ANDROID) && (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
2429
#include <QtAndroid>
2530
#endif
@@ -44,7 +49,7 @@ int main(int argc, char *argv[])
4449

4550
qDebug(log) << "Version:" << RabbitRemoteControl_VERSION;
4651
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
47-
52+
4853
/* 移到 snapcraft.yaml 和 io.github.KangLin.RabbitRemoteControl.yml
4954
// 修复 qtwebengine 沙箱权限问题
5055
if(!qEnvironmentVariable("SNAP").isEmpty()) {

Plugins/WebBrowser/FrmWebBrowser.cpp

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ CFrmWebBrowser::CFrmWebBrowser(CParameterWebBrowser *pPara, bool bMenuBar, QWidg
6464
, m_pCapturePage(nullptr)
6565
, m_pCaptureFulPage(nullptr)
6666
, m_pRecord(nullptr)
67-
, m_MultimediaRecord(pPara)
67+
, m_pMultimediaRecord(nullptr)
6868
{
6969
qDebug(log) << Q_FUNC_INFO;
7070
bool check = false;
@@ -710,16 +710,23 @@ int CFrmWebBrowser::InitMenu(QMenu *pMenu)
710710
}
711711

712712
pMenu->addSeparator();
713-
m_pCapturePage = pMenu->addAction(QIcon::fromTheme("screen-shot"), tr("Capture page"),
714-
this, &CFrmWebBrowser::slotCapturePage);
713+
m_pCapturePage = pMenu->addAction(
714+
QIcon::fromTheme("screen-shot"), tr("Capture page"),
715+
this, &CFrmWebBrowser::slotCapturePage);
715716
m_pCapturePage->setStatusTip(tr("Capture page"));
716-
m_pCaptureFulPage = pMenu->addAction(QIcon::fromTheme("screen-shot"), tr("Capture full page"),
717-
this, &CFrmWebBrowser::slotCaptureFullPage);
717+
m_pCaptureFulPage = pMenu->addAction(
718+
QIcon::fromTheme("screen-shot"), tr("Capture full page"),
719+
this, &CFrmWebBrowser::slotCaptureFullPage);
718720
m_pCaptureFulPage->setStatusTip(tr("Capture full page"));
719721
m_pRecord = pMenu->addAction(QIcon::fromTheme("media-record"), tr("Record"),
720722
this, &CFrmWebBrowser::slotRecord);
721723
m_pRecord->setCheckable(true);
722724
m_pRecord->setStatusTip(tr("Record"));
725+
#ifdef HAVE_QT6_RECORD
726+
m_pRecord->setEnabled(true);
727+
#else
728+
m_pRecord->setEnabled(false);
729+
#endif
723730

724731
EnableAction(false);
725732
return 0;
@@ -1118,31 +1125,54 @@ void CFrmWebBrowser::slotRecord()
11181125
if(m_pRecord->isChecked()) {
11191126
m_pRecord->setText(tr("Stop record"));
11201127
m_pRecord->setIcon(QIcon::fromTheme("media-stop"));
1121-
m_MultimediaRecord.start();
1128+
1129+
Q_ASSERT(!m_pMultimediaRecord);
1130+
// Note: It automatically releases memory when exiting.
1131+
// See: CMultimediaRecordThread::CMultimediaRecordThread()
1132+
m_pMultimediaRecord = new CMultimediaRecordThread(m_pPara);
1133+
if(m_pMultimediaRecord) {
1134+
connect(m_pMultimediaRecord, &CMultimediaRecordThread::finished,
1135+
this, [this]() {
1136+
m_pMultimediaRecord = nullptr;
1137+
if(m_pRecord->isChecked()) {
1138+
m_pRecord->activate(QAction::Trigger);
1139+
emit sigError(RV::FailRecordPage, tr("Fail record web page"));
1140+
}
1141+
});
1142+
m_pMultimediaRecord->start();
1143+
}
1144+
11221145
// modify interval
11231146
qreal rate = m_pPara->m_Record.GetVideoFrameRate();
11241147
if(rate <= 0)
11251148
rate = 24;
11261149
m_tmRecord.start(qreal(1000) / rate);
1127-
//slotRecordTimeout();
1150+
emit sigInformation(tr("Start record web page"));
11281151
} else {
11291152
m_pRecord->setIcon(QIcon::fromTheme("media-record"));
11301153
m_pRecord->setText(tr("Record"));
11311154
m_tmRecord.stop();
1132-
m_MultimediaRecord.quit();
1155+
if(m_pMultimediaRecord) {
1156+
QMetaObject::invokeMethod(m_pMultimediaRecord,
1157+
"slotQuit",
1158+
Qt::AutoConnection);
1159+
m_pMultimediaRecord = nullptr;
1160+
emit sigInformation(tr("Record web page is stoped"));
1161+
}
11331162
}
11341163
m_pRecord->setStatusTip(m_pRecord->text());
11351164
}
11361165

11371166
void CFrmWebBrowser::slotRecordTimeout()
11381167
{
11391168
//qDebug(log) << Q_FUNC_INFO;
1169+
if(!m_pMultimediaRecord) return;
11401170
auto pWeb = CurrentView();
11411171
if(!pWeb) return;
11421172
QPixmap pixmap = pWeb->grab();
11431173
QImage image = pixmap.toImage();
11441174
if(image.isNull()) return;
1145-
QMetaObject::invokeMethod(&m_MultimediaRecord,
1175+
QMetaObject::invokeMethod(m_pMultimediaRecord,
11461176
"slotUpdateVideoFrame",
11471177
Qt::AutoConnection,
11481178
Q_ARG(QImage, image));

Plugins/WebBrowser/FrmWebBrowser.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class CFrmWebBrowser : public QWidget
3030
Fail = -1,
3131
FailCapturePage = -2,
3232
FailCaptureFullPage = -3,
33+
FailRecordPage = -4
3334
};
3435
Q_ENUM(RV)
3536

@@ -122,6 +123,6 @@ public Q_SLOTS:
122123
QString m_szStyleSheet;
123124
friend CFrmWebView;
124125

125-
CMultimediaRecordThread m_MultimediaRecord;
126+
CMultimediaRecordThread* m_pMultimediaRecord;
126127
QTimer m_tmRecord;
127128
};

Plugins/WebBrowser/MultimediaRecord.cpp

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ static Q_LOGGING_CATEGORY(log, "WebBrowser.Record")
99

1010
CMultimediaRecord::CMultimediaRecord(CParameterWebBrowser *pPara, QObject *parent)
1111
: QObject{parent}
12-
, m_pParaRecord(nullptr)
1312
, m_pMediaDevices(nullptr)
1413
, m_VideoFrameStartTime(0)
1514
{
1615
bool check = false;
16+
qDebug(log) << Q_FUNC_INFO;
1717
if(pPara) {
18-
m_pParaRecord = &pPara->m_Record;
18+
m_ParaRecord = pPara->m_Record;
1919
m_pMediaDevices = &pPara->m_MediaDevices;
2020
}
2121
#if HAVE_QT6_RECORD
@@ -28,35 +28,46 @@ CMultimediaRecord::CMultimediaRecord(CParameterWebBrowser *pPara, QObject *paren
2828
#endif // #if HAVE_QT6_RECORD
2929
}
3030

31+
CMultimediaRecord::~CMultimediaRecord()
32+
{
33+
qDebug(log) << Q_FUNC_INFO;
34+
}
35+
3136
void CMultimediaRecord::slotStart()
3237
{
33-
// 配置音频输入(捕获系统音频或麦克风)
38+
#ifdef HAVE_QT6_RECORD
39+
// 配置音频输入(捕获系统音频输入或麦克风)
3440
if(m_pMediaDevices) {
3541
const auto inputs = QMediaDevices::audioInputs();
3642
foreach(auto input, inputs) {
3743
if(input.id() == m_pMediaDevices->m_Para.m_AudioInput) {
3844
m_AudioInput.setDevice(input);
45+
m_CaptureSession.setAudioInput(&m_AudioInput);
3946
break;
4047
}
4148
}
4249
}
43-
m_CaptureSession.setAudioInput(&m_AudioInput);
4450
m_CaptureSession.setVideoFrameInput(&m_VideoFrameInput);
4551
// 配置录制器, 设置录制参数:输出文件、编码、质量等
46-
if(m_pParaRecord)
47-
*m_pParaRecord >> m_Recorder;
52+
m_ParaRecord >> m_Recorder;
4853
m_CaptureSession.setRecorder(&m_Recorder);
4954
m_VideoFrameStartTime = 0;
5055
m_Recorder.record();
56+
#endif
5157
}
5258

5359
void CMultimediaRecord::slotStop()
5460
{
61+
#ifdef HAVE_QT6_RECORD
5562
m_Recorder.stop();
63+
#endif
64+
m_pMediaDevices = nullptr;
5665
}
5766

5867
void CMultimediaRecord::slotUpdateVideoFrame(const QImage image)
5968
{
69+
//qDebug(log) << Q_FUNC_INFO;
70+
#ifdef HAVE_QT6_RECORD
6071
// 将 QImage 转换为 QVideoFrame
6172
QImage img = image;
6273
//qDebug(log) << "Image format:" << img.format();
@@ -74,12 +85,13 @@ void CMultimediaRecord::slotUpdateVideoFrame(const QImage image)
7485
if (m_VideoFrameStartTime == 0) m_VideoFrameStartTime = QDateTime::currentMSecsSinceEpoch() * 1000;
7586
qint64 currentTime = QDateTime::currentMSecsSinceEpoch() * 1000 - m_VideoFrameStartTime;
7687
frame.setStartTime(currentTime);
77-
qreal rate = m_pParaRecord->GetVideoFrameRate();
88+
qreal rate = m_ParaRecord.GetVideoFrameRate();
7889
if(rate <= 0)
7990
rate = 24;
8091
frame.setEndTime(currentTime + qreal(1000000) / rate);
81-
frame.setStreamFrameRate(m_pParaRecord->GetVideoFrameRate());//*/
92+
frame.setStreamFrameRate(m_ParaRecord.GetVideoFrameRate());//*/
8293
m_VideoFrameInput.sendVideoFrame(frame);
94+
#endif
8395
}
8496

8597
#if HAVE_QT6_RECORD
@@ -89,7 +101,7 @@ void CMultimediaRecord::slotRecordStateChanged(QMediaRecorder::RecorderState sta
89101
switch(state) {
90102
case QMediaRecorder::RecorderState::StoppedState: {
91103
QString szFile = m_Recorder.actualLocation().toLocalFile();
92-
switch(m_pParaRecord->GetEndAction())
104+
switch(m_ParaRecord.GetEndAction())
93105
{
94106
case CParameterRecord::ENDACTION::OpenFile: {
95107
bool bRet = QDesktopServices::openUrl(QUrl::fromLocalFile(szFile));
@@ -125,30 +137,45 @@ void CMultimediaRecord::slotRecordError(QMediaRecorder::Error error, const QStri
125137
}
126138
#endif // HAVE_QT6_RECORD
127139

128-
CMultimediaRecordThread::CMultimediaRecordThread(CParameterWebBrowser* pPara, QObject *parent)
140+
CMultimediaRecordThread::CMultimediaRecordThread(
141+
CParameterWebBrowser* pPara, QObject *parent)
129142
: QThread(parent)
130143
, m_pPara(pPara)
131144
, m_pRecord(nullptr)
132-
{}
145+
{
146+
qDebug(log) << Q_FUNC_INFO;
147+
connect(this, &QThread::finished, this, &QObject::deleteLater);
148+
}
149+
150+
CMultimediaRecordThread::~CMultimediaRecordThread()
151+
{
152+
qDebug(log) << Q_FUNC_INFO;
153+
}
133154

134155
void CMultimediaRecordThread::run()
135156
{
136157
m_pRecord = new CMultimediaRecord(m_pPara);
137158
if(!m_pRecord) return;
138159
connect(m_pRecord, &CMultimediaRecord::sigFinished,
139-
this, &CMultimediaRecordThread::quit);
160+
this, &QThread::quit);
140161
m_pRecord->slotStart();
141162
exec();
142-
m_pRecord->slotStop();
143-
exec();
144163
delete m_pRecord;
164+
m_pRecord = nullptr;
145165
}
146166

147167
void CMultimediaRecordThread::slotUpdateVideoFrame(const QImage image)
148168
{
149169
if(!m_pRecord) return;
170+
m_pRecord->slotUpdateVideoFrame(image);
171+
}
172+
173+
void CMultimediaRecordThread::slotQuit()
174+
{
175+
if(!m_pRecord) return;
176+
m_pRecord->slotStop();
177+
/*
150178
QMetaObject::invokeMethod(m_pRecord,
151-
"slotUpdateVideoFrame",
152-
Qt::AutoConnection,
153-
Q_ARG(QImage, image));
179+
"slotStop",
180+
Qt::AutoConnection);*/
154181
}

Plugins/WebBrowser/MultimediaRecord.h

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class CMultimediaRecord : public QObject
2626
Q_OBJECT
2727
public:
2828
explicit CMultimediaRecord(CParameterWebBrowser* pPara, QObject *parent = nullptr);
29+
~CMultimediaRecord();
2930

3031
enum RV {
3132
Success = 0,
@@ -43,32 +44,54 @@ public Q_SLOTS:
4344
void sigFinished();
4445

4546
private:
46-
CParameterRecord* m_pParaRecord;
47+
CParameterRecord m_ParaRecord;
4748
CParameterMediaDevices* m_pMediaDevices;
4849
#if HAVE_QT6_MULTIMEDIA
4950
QMediaCaptureSession m_CaptureSession;
5051
#endif
52+
qint64 m_VideoFrameStartTime;
5153
#ifdef HAVE_QT6_RECORD
5254
QAudioInput m_AudioInput;
5355
QVideoFrameInput m_VideoFrameInput;
5456
QAudioBufferInput m_AudioBufferInput;
5557
QAudioBufferOutput m_AudioBufferOutput;
5658
QMediaRecorder m_Recorder;
57-
qint64 m_VideoFrameStartTime;
5859
private Q_SLOTS:
5960
void slotRecordStateChanged(QMediaRecorder::RecorderState state);
6061
void slotRecordError(QMediaRecorder::Error error, const QString &errorString);
61-
#endif
62+
#endif
6263
};
6364

65+
/*!
66+
* \brief The CMultimediaRecordThread class
67+
* \details Must use pointer. eg:
68+
* - New object:
69+
* \code
70+
* CMultimediaRecordThread* pThread = new CMultimediaRecordThread(m_pPara);
71+
* \endcode
72+
* - Start thread:
73+
* \code
74+
* if(pThread)
75+
* pThread->start();
76+
* \endcode
77+
* - Stop thread.
78+
* \code
79+
* pThread->slotQuit();
80+
* \endcode
81+
*
82+
* \note
83+
* - It automatically releases memory when exiting.
84+
* - To stop a thread, you must use slotQuit(), and cannot use quit().
85+
*/
6486
class CMultimediaRecordThread : public QThread
6587
{
6688
Q_OBJECT
6789
public:
6890
explicit CMultimediaRecordThread(CParameterWebBrowser* pPara, QObject *parent = nullptr);
69-
91+
~CMultimediaRecordThread();
7092
public Q_SLOTS:
7193
void slotUpdateVideoFrame(const QImage image);
94+
void slotQuit();
7295
protected:
7396
virtual void run() override;
7497
private:

0 commit comments

Comments
 (0)