7#include <QDesktopServices>
8#include <QLoggingCategory>
11#include "BackendDesktop.h"
14static Q_LOGGING_CATEGORY(log,
"Backend.Desktop")
15static Q_LOGGING_CATEGORY(logKey,
"Backend.Desktop.Key")
16static Q_LOGGING_CATEGORY(logMouse,
"Backend.Desktop.Mouse")
17static Q_LOGGING_CATEGORY(logInputMethod,
"Backend.Desktop.InputMethod")
19#define TypeRecordVideo (QEvent::User + 1)
20class QRecordVideoEvent :
public QEvent
23 QRecordVideoEvent(
const QImage& img): QEvent((QEvent::Type)TypeRecordVideo)
40int g_QtKeyboardModifiers = qRegisterMetaType<Qt::KeyboardModifiers>(
"KeyboardModifiers");
41int g_QtMouseButtons = qRegisterMetaType<Qt::MouseButtons>(
"MouseButtons");
42int g_QtMouseButton = qRegisterMetaType<Qt::MouseButton>(
"MouseButton");
43int g_QMessageBox_Icon = qRegisterMetaType<QMessageBox::Icon>(
"QMessageBox::Icon");
48 , m_pParameterRecord(nullptr)
49 , m_VideoFrameInput(this)
50 , m_AudioBufferInput(this)
51 , m_AudioBufferOutput(this)
54 qDebug(log) << Q_FUNC_INFO;
62 QString szErr = pOperate->metaObject()->className();
63 szErr +=
"::GetViewer() is not CFrmViewer";
64 qWarning(log) << szErr.toStdString().c_str();
67 QString szErr = pOperate->metaObject()->className();
68 szErr +=
"::GetViewer() is not CFrmScroll";
69 qWarning(log) << szErr.toStdString().c_str();
76 &m_Recorder, &QMediaRecorder::errorOccurred,
77 this, [&](QMediaRecorder::Error error,
const QString &errorString) {
78 qDebug(log) <<
"Recorder error occurred:" << error << errorString;
80 emit sigError(error, errorString);
84 &m_Recorder, &QMediaRecorder::recorderStateChanged,
85 this, [&](QMediaRecorder::RecorderState state){
86 qDebug(log) <<
"Recorder state changed:" << state;
87 if(QMediaRecorder::StoppedState == state)
90 if(m_pParameterRecord) {
91 qDebug(log) <<
"End action:"
92 << m_pParameterRecord->GetEndAction()
93 << m_Recorder.actualLocation();
94 switch(m_pParameterRecord->GetEndAction())
96 case CParameterRecord::ENDACTION::OpenFile:
97 QDesktopServices::openUrl(m_Recorder.actualLocation());
99 case CParameterRecord::ENDACTION::OpenFolder: {
100 QFileInfo fi(m_Recorder.actualLocation().toLocalFile());
101 QDesktopServices::openUrl(
102 QUrl::fromLocalFile(fi.absolutePath()));
112 check = connect(&m_Recorder, &QMediaRecorder::actualLocationChanged,
113 this, [&](
const QUrl &location){
114 qInfo(log) <<
"Recorder actual location changed:" << location;
120CBackendDesktop::~CBackendDesktop()
122 qDebug(log) << Q_FUNC_INFO;
129 if(!pOperate)
return -1;
132 check = connect(
this, SIGNAL(sigServerName(
const QString&)),
133 pOperate, SLOT(slotSetServerName(
const QString&)));
135 check = connect(pOperate, SIGNAL(sigClipBoardChanged()),
138 check = connect(
this, SIGNAL(sigSetClipboard(QMimeData*)),
139 pOperate, SLOT(slotSetClipboard(QMimeData*)));
143 m_pParameterRecord = &pOperate->
GetParameter()->m_Record;
144 check = connect(pOperate, SIGNAL(sigRecord(
bool)),
145 this, SLOT(slotRecord(
bool)));
148 check = connect(pOperate, SIGNAL(sigRecordPause(
bool)),
149 this, SLOT(slotRecordPause(
bool)));
153 SIGNAL(recorderStateChanged(QMediaRecorder::RecorderState)),
154 pOperate, SLOT(slotRecorderStateChanged(QMediaRecorder::RecorderState)));
164 if(!pView)
return -1;
167 check = connect(
this, SIGNAL(
sigRunning()), pView, SLOT(slotRunning()));
169 check = connect(
this, SIGNAL(sigSetDesktopSize(
int,
int)),
170 pView, SLOT(slotSetDesktopSize(
int,
int)));
172 check = connect(
this, SIGNAL(sigServerName(
const QString&)),
173 pView, SLOT(slotSetName(
const QString&)));
176 check = connect(
this, SIGNAL(
sigUpdateRect(
const QRect&,
const QImage&)),
177 pView, SLOT(slotUpdateRect(
const QRect&,
const QImage&)));
180 pView, SLOT(slotUpdateRect(
const QImage&)));
182 check = connect(
this, SIGNAL(sigUpdateCursor(
const QCursor&)),
183 pView, SLOT(slotUpdateCursor(
const QCursor&)));
185 check = connect(
this, SIGNAL(sigUpdateCursorPosition(
const QPoint&)),
186 pView, SLOT(slotUpdateCursorPosition(
const QPoint&)));
188 check = connect(
this, SIGNAL(sigUpdateLedState(
unsigned int)),
189 pView, SLOT(slotUpdateLedState(
unsigned int)));
193 check = connect(
this, SIGNAL(sigRecordVideo(
bool, qreal)),
194 pView, SLOT(slotRecordVideo(
bool, qreal)));
196 check = connect(pView, SIGNAL(sigRecordVideo(QImage)),
197 this, SLOT(slotRecordVideo(QImage)),
198 Qt::DirectConnection);
209 check = connect(pView, SIGNAL(sigMousePressEvent(QMouseEvent*, QPoint)),
210 this, SLOT(slotMousePressEvent(QMouseEvent*, QPoint)),
211 Qt::DirectConnection);
213 check = connect(pView, SIGNAL(sigMouseReleaseEvent(QMouseEvent*, QPoint)),
214 this, SLOT(slotMouseReleaseEvent(QMouseEvent*, QPoint)),
215 Qt::DirectConnection);
217 check = connect(pView, SIGNAL(sigMouseMoveEvent(QMouseEvent*, QPoint)),
218 this, SLOT(slotMouseMoveEvent(QMouseEvent*, QPoint)),
219 Qt::DirectConnection);
221 check = connect(pView, SIGNAL(sigWheelEvent(QWheelEvent*, QPoint)),
222 this, SLOT(slotWheelEvent(QWheelEvent*, QPoint)),
223 Qt::DirectConnection);
225 check = connect(pView, SIGNAL(sigKeyPressEvent(QKeyEvent*)),
226 this, SLOT(slotKeyPressEvent(QKeyEvent*)),
227 Qt::DirectConnection);
229 check = connect(pView, SIGNAL(sigKeyReleaseEvent(QKeyEvent*)),
230 this, SLOT(slotKeyReleaseEvent(QKeyEvent*)),
231 Qt::DirectConnection);
233 check = connect(pView, SIGNAL(sigInputMethodEvent(QInputMethodEvent*)),
234 this, SLOT(slotInputMethodEvent(QInputMethodEvent*)),
235 Qt::DirectConnection);
241void CBackendDesktop::slotWheelEvent(QWheelEvent *event, QPoint pos)
243 QWheelEvent* e =
new QWheelEvent(
245#
if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
246 event->globalPosition(),
250 event->pixelDelta(), event->angleDelta(), event->buttons(),
251 event->modifiers(), event->phase(), event->inverted(), event->source());
252 QCoreApplication::postEvent(
this, e);
256void CBackendDesktop::slotMouseMoveEvent(QMouseEvent *event, QPoint pos)
258#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0)
259 QMouseEvent* e =
new QMouseEvent(event->type(), pos, event->button(),
260 event->buttons(), event->modifiers());
262 QMouseEvent* e =
new QMouseEvent(event->type(), pos, pos, event->button(),
263 event->buttons(), event->modifiers());
265 QCoreApplication::postEvent(
this, e);
269void CBackendDesktop::slotMousePressEvent(QMouseEvent *event, QPoint pos)
271#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0)
272 QMouseEvent* e =
new QMouseEvent(event->type(), pos, event->button(),
273 event->buttons(), event->modifiers());
275 QMouseEvent* e =
new QMouseEvent(event->type(), pos, pos, event->button(),
276 event->buttons(), event->modifiers());
278 QCoreApplication::postEvent(
this, e);
282void CBackendDesktop::slotMouseReleaseEvent(QMouseEvent *event, QPoint pos)
284#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0)
285 QMouseEvent* e =
new QMouseEvent(event->type(), pos, event->button(),
286 event->buttons(), event->modifiers());
288 QMouseEvent* e =
new QMouseEvent(event->type(), pos, pos, event->button(),
289 event->buttons(), event->modifiers());
291 QCoreApplication::postEvent(
this, e);
295void CBackendDesktop::slotKeyPressEvent(QKeyEvent *event)
297 QKeyEvent* e =
new QKeyEvent(event->type(), event->key(),
298 event->modifiers(), event->text());
299 QCoreApplication::postEvent(
this, e);
303void CBackendDesktop::slotKeyReleaseEvent(QKeyEvent *event)
305 QKeyEvent* e =
new QKeyEvent(event->type(), event->key(),
306 event->modifiers(), event->text());
307 QCoreApplication::postEvent(
this, e);
311void CBackendDesktop::slotInputMethodEvent(QInputMethodEvent *event)
314 if(event->commitString().isEmpty())
return;
315 QInputMethodEvent* e =
new QInputMethodEvent(event->preeditString(), event->attributes());
316 e->setCommitString(event->commitString(), event->replacementStart(), event->replacementLength());
317 QCoreApplication::postEvent(
this, e);
321bool CBackendDesktop::event(QEvent *event)
324 switch (event->type()) {
325 case QEvent::MouseButtonPress:
326 case QEvent::MouseButtonDblClick:
327 mousePressEvent((QMouseEvent*)event);
329 case QEvent::MouseButtonRelease:
330 mouseReleaseEvent((QMouseEvent*)event);
332 case QEvent::MouseMove:
333 mouseMoveEvent((QMouseEvent*)event);
336 wheelEvent((QWheelEvent*)event);
338 case QEvent::KeyPress:
339 keyPressEvent((QKeyEvent*)event);
341 case QEvent::KeyRelease:
342 keyReleaseEvent((QKeyEvent*)event);
344 case QEvent::InputMethod:
345 InputMethodEvent((QInputMethodEvent*) event);
348 case TypeRecordVideo:
349 RecordVideo((QRecordVideoEvent*)event);
353 return QObject::event(event);
361void CBackendDesktop::slotRecord(
bool bRecord)
363 qDebug(log) << Q_FUNC_INFO << bRecord;
365 if(QMediaRecorder::RecordingState == m_Recorder.recorderState())
367 (*m_pParameterRecord) >> m_Recorder;
368 m_CaptureSession.setVideoFrameInput(&m_VideoFrameInput);
369 m_CaptureSession.setRecorder(&m_Recorder);
373 m_CaptureSession.setVideoFrameInput(
nullptr);
374 m_CaptureSession.setAudioBufferInput(
nullptr);
375 m_CaptureSession.setRecorder(
nullptr);
377 emit sigRecordVideo(bRecord, m_pParameterRecord->GetVideoFrameRate());
380void CBackendDesktop::slotRecordPause(
bool bPause)
382 qDebug(log) << Q_FUNC_INFO << bPause;
384 if(m_Recorder.recorderState() == QMediaRecorder::RecordingState)
387 if(m_Recorder.recorderState() == QMediaRecorder::PausedState)
392void CBackendDesktop::slotRecordVideo(
const QImage &img)
394 QRecordVideoEvent* e =
new QRecordVideoEvent(img);
396 QCoreApplication::postEvent(
this, e);
404 if(QMediaRecorder::RecordingState != m_Recorder.recorderState()) {
405 qCritical(log) <<
"Recorder is inavailable";
408 QVideoFrame frame(e->GetImage());
409 bool bRet = m_VideoFrameInput.sendVideoFrame(frame);
413 qDebug(log) <<
"m_VideoFrameInput.sendVideoFrame fail";
void sigUpdateRect(const QRect &r, const QImage &image)
通知视图,图像更新
int SetViewer(CFrmViewer *pView)
virtual void slotClipBoardChanged()=0
当剪切板发生改变时调用
后端接口。它由协议插件实现。 它默认启动一个定时器来开启一个非 Qt 事件循环(就是普通的循环处理)。 详见: Start()、 slotTimeOut()、 OnProcess() 。 当然,它仍然支...
virtual int WakeUp()=0
唤醒后台线程。
void sigRunning()
当插件开始成功后触发。仅由插件触发
用于显示从 CConnectDesktop 输出的图像,和向 CConnectDesktop 发送键盘、鼠标事件。
virtual CParameterDesktop * GetParameter() const
Get parameter
virtual QWidget * GetViewer() override
得到显示视图