3#include <QLoggingCategory>
4#include <QMediaDevices>
7#include <QDesktopServices>
11#include "BackendPlayer.h"
13static Q_LOGGING_CATEGORY(log,
"Player.Backend")
18 , m_bScreenShot(false)
23 qDebug(log) << Q_FUNC_INFO;
25 m_pParameters = qobject_cast<CParameterPlayer*>(pOperate->GetParameter());
28 check = connect(&m_VideoSink, &QVideoSink::videoFrameChanged,
29 pOperate->GetVideoSink(), &QVideoSink::videoFrameChanged);
34 &m_VideoSink, SIGNAL(videoFrameChanged(
const QVideoFrame&)),
35 this, SLOT(slotVideoFrameChanged(QVideoFrame)));
40 &m_AudioBufferOutput, &QAudioBufferOutput::audioBufferReceived,
41 this, [&](
const QAudioBuffer &buffer){
43 if(QMediaRecorder::RecordingState != m_Recorder.recorderState())
45 bool bRet = m_AudioBufferInput.sendAudioBuffer(buffer);
49 qDebug(log) <<
"m_AudioBufferInput.sendAudioBuffer fail";
55 check = connect(pOperate, &COperatePlayer::sigStart,
56 this, [&](
bool bStart){
64 pOperate, &COperatePlayer::sigPause,
65 this, [&](
bool bPause){
66 switch (m_pParameters->GetType()) {
67 case CParameterPlayer::TYPE::Camera:
69 if(m_pCamera->isActive())
73 if(!m_pCamera->isActive())
77 case CParameterPlayer::TYPE::Url:
79 if(QMediaPlayer::PlayingState == m_Player.playbackState())
83 if(QMediaPlayer::PausedState == m_Player.playbackState())
92 &m_Player, SIGNAL(positionChanged(qint64)),
93 this, SLOT(slotPositionChanged(qint64)));
96 &m_Player, SIGNAL(durationChanged(qint64)),
97 this, SLOT(slotDurationChanged(qint64)));
99 check = connect(pOperate, SIGNAL(sigChangePosition(qint64)),
100 &m_Player, SLOT(setPosition(qint64)));
102 check = connect(m_pParameters, &CParameterPlayer::sigEnableAudioInput,
103 this, &CBackendPlayer::slotEnableAudioInput);
105 check = connect(m_pParameters, &CParameterPlayer::sigEnableAudioOutput,
106 this, &CBackendPlayer::slotEnableAudioOutput);
110 &m_Player, &QMediaPlayer::errorOccurred,
111 this, [&](QMediaPlayer::Error error,
const QString &errorString){
112 qCritical(log) <<
"Player error occurred:" << error << errorString
113 << m_Player.source();
115 emit sigError(error, errorString);
118 check = connect(&m_Player, &QMediaPlayer::playbackStateChanged,
119 this, [&](QMediaPlayer::PlaybackState state){
120 qDebug(log) <<
"Player state changed:" << state
121 << m_Player.source();
123 if(QMediaPlayer::PlaybackState::PlayingState == state) {
130 if(-1 == m_Player.activeAudioTrack()
131 && m_Player.audioTracks().size() > 0) {
132 m_Player.setActiveAudioTrack(0);
134 if(-1 == m_Player.activeVideoTrack()
135 && m_Player.videoTracks().size() > 0) {
136 m_Player.setActiveVideoTrack(0);
138 if(m_pParameters->GetSubtitle()) {
139 if(m_Player.subtitleTracks().size() > 0) {
141 for(
int i = 0; i < m_Player.subtitleTracks().size(); i++) {
142 auto m = m_Player.subtitleTracks().at(i);
143 QVariant v = m.value(QMediaMetaData::Language);
144 if(!v.isValid())
continue;
145 if(v.toLocale().language() == QLocale::AnyLanguage
146 || v.toLocale().language() == QLocale::system().language()) {
151 m_Player.setActiveSubtitleTrack(nIndex);
159 check = connect(&m_Player, &QMediaPlayer::errorOccurred,
160 pOperate, &COperatePlayer::slotPlaybackError);
162 check = connect(&m_Player, &QMediaPlayer::playbackStateChanged,
163 pOperate, &COperatePlayer::slotPlaybackStateChanged);
165 check = connect(
this, SIGNAL(sigPositionChanged(qint64,qint64)),
166 pOperate, SLOT(slotPositionChanged(qint64,qint64)));
169 check = connect(&m_Recorder, &QMediaRecorder::recorderStateChanged,
170 pOperate, &COperatePlayer::slotRecordStateChanged);
175 check = connect(pOperate, &COperatePlayer::sigScreenShot,
177 m_bScreenShot =
true;
183CBackendPlayer::~CBackendPlayer()
185 qDebug(log) << Q_FUNC_INFO;
190 qDebug(log) << Q_FUNC_INFO;
192 return OnInitReturnValue::NotUseOnProcess;
197 qDebug(log) << Q_FUNC_INFO;
203void CBackendPlayer::slotStart()
205 qDebug(log) << Q_FUNC_INFO;
206 slotEnableAudioInput(m_pParameters->GetEnableAudioInput());
207 slotEnableAudioOutput(m_pParameters->GetEnableAudioOutput());
209 switch (m_pParameters->GetType()) {
210 case CParameterPlayer::TYPE::Camera: {
212 const QList<QCameraDevice> cameras = QMediaDevices::videoInputs();
214 || -1 > m_pParameters->GetCamera()
215 || m_pParameters->GetCamera() > QMediaDevices::videoInputs().size())
217 m_pCamera =
new QCamera(cameras.at(m_pParameters->GetCamera()));
218 emit sigServerName(cameras.at(m_pParameters->GetCamera()).description());
221 m_CaptureSession.setVideoSink(&m_VideoSink);
222 m_CaptureSession.setCamera(m_pCamera);
227 case CParameterPlayer::TYPE::Url: {
228 QString szFile = m_pParameters->GetUrl();
229 QFileInfo fi(szFile);
230 emit sigServerName(fi.fileName());
233 url = QUrl::fromLocalFile(szFile);
234 m_Player.setSource(url);
235 m_Player.setVideoSink(&m_VideoSink);
237 if(m_pParameters->m_Record.GetEnableAudio())
238 m_Player.setAudioBufferOutput(&m_AudioBufferOutput);
242 m_nPosition = m_Player.position();
243 m_nDuration = m_Player.duration();
251void CBackendPlayer::slotStop()
253 qDebug(log) << Q_FUNC_INFO;
254 switch (m_pParameters->GetType()) {
255 case CParameterPlayer::TYPE::Camera:
258 m_CaptureSession.setVideoSink(
nullptr);
260 case CParameterPlayer::TYPE::Url:
262 m_Player.setVideoSink(
nullptr);
263 m_Player.setVideoOutput(
nullptr);
279void CBackendPlayer::slotRecord(
bool bRecord)
281 qDebug(log) << Q_FUNC_INFO << bRecord;
284 if(QMediaRecorder::StoppedState != m_Recorder.recorderState()) {
288 auto &record = m_pParameters->m_Record;
289 switch (m_pParameters->GetType()) {
290 case CParameterPlayer::TYPE::Camera: {
291 record >> m_Recorder;
292 m_CaptureSession.setRecorder(&m_Recorder);
296 case CParameterPlayer::TYPE::Url: {
297 record >> m_Recorder;
298 if(record.GetEnableAudio()) {
299 m_CaptureSession.setAudioBufferInput(&m_AudioBufferInput);
301 qDebug(log) <<
"Record: disable audio";
302 if(record.GetEnableVideo())
303 m_CaptureSession.setVideoFrameInput(&m_VideoFrameInput);
305 qDebug(log) <<
"Record: disable video";
306 m_CaptureSession.setRecorder(&m_Recorder);
313#ifndef HAVE_QVideoWidget
314 emit sigRecordVideo(bRecord, m_pParameters->m_Record.GetVideoFrameRate());
319 if(QMediaRecorder::StoppedState != m_Recorder.recorderState()) {
321 m_CaptureSession.setRecorder(
nullptr);
322 m_CaptureSession.setVideoFrameInput(
nullptr);
323 m_CaptureSession.setAudioBufferInput(
nullptr);
328void CBackendPlayer::slotClipBoardChanged()
332void CBackendPlayer::slotVideoFrameChanged(
const QVideoFrame &frame)
334#ifndef HAVE_QVideoWidget
335 if(m_Video.width() != frame.width()
336 || m_Video.height() != frame.height())
338 m_Video = QRect(0, 0, frame.width(), frame.height());
339 emit sigSetDesktopSize(m_Video.width(), m_Video.height());
341 QImage img(frame.width(), frame.height(), QImage::Format_ARGB32);
342 QPainter painter(&img);
343 const QVideoFrame::PaintOptions option;
344 QVideoFrame f = frame;
345 f.paint(&painter, m_Video, option);
351 m_bScreenShot =
false;
352 QImage image = frame.toImage();
354 qCritical(log) <<
"frame.toImage() fail";
356 QString szFile = m_pParameters->m_Record.GetImageFile(
true);
357 if(!image.save(szFile,
"PNG"))
359 qCritical(log) <<
"Capture image save to file fail." << szFile;
362 qDebug(log) <<
"Capture image to file:" << szFile;
363 qDebug(log) <<
"End action:" << m_pParameters->m_Record.GetEndAction();
364 switch(m_pParameters->m_Record.GetEndAction())
366 case CParameterRecord::ENDACTION::OpenFile: {
367 bool bRet = QDesktopServices::openUrl(QUrl::fromLocalFile(szFile));
369 qCritical(log) <<
"Fail: Open capture image file" << szFile;
372 case CParameterRecord::ENDACTION::OpenFolder: {
373 QFileInfo fi(szFile);
374 QDesktopServices::openUrl(QUrl::fromLocalFile(fi.absolutePath()));
383#if defined(HAVE_QT6_RECORD) && defined(HAVE_QVideoWidget)
384 if(QMediaRecorder::RecordingState == m_Recorder.recorderState()) {
385 bool bRet = m_VideoFrameInput.sendVideoFrame(frame);
389 qDebug(log) <<
"m_VideoFrameInput.sendVideoFrame fail";
395void CBackendPlayer::slotEnableAudioInput(
bool bEnable)
397 if(bEnable && -1 < m_pParameters->GetAudioInput()
398 && m_pParameters->GetAudioInput() < QMediaDevices::audioInputs().size()) {
399 m_AudioInput.setDevice(QMediaDevices::audioInputs()
400 .at(m_pParameters->GetAudioInput()));
401 m_AudioInput.setMuted(m_pParameters->GetAudioInputMuted());
402 m_AudioInput.setVolume(m_pParameters->GetAudioInputVolume());
403 m_CaptureSession.setAudioInput(&m_AudioInput);
405 bool check = connect(m_pParameters,
406 &CParameterPlayer::sigAudioInputMuted,
407 &m_AudioInput, &QAudioInput::setMuted);
409 check = connect(m_pParameters, &CParameterPlayer::sigAudioInputVolume,
410 &m_AudioInput, &QAudioInput::setVolume);
412 check = connect(m_pParameters, &CParameterPlayer::sigAudioInput,
413 this, [&](
int nIndex) {
415 && nIndex < QMediaDevices::audioInputs().size())
416 m_AudioInput.setDevice(
417 QMediaDevices::audioInputs().at(nIndex));
421 qDebug(log) <<
"m_CaptureSession: disable audio input";
422 m_CaptureSession.setAudioInput(
nullptr);
426void CBackendPlayer::slotEnableAudioOutput(
bool bEnable)
428 if(bEnable && (-1 < m_pParameters->GetAudioOutput()
429 && m_pParameters->GetAudioOutput()
430 < QMediaDevices::audioInputs().size()))
432 m_AudioOutput.setDevice(
433 QMediaDevices::audioOutputs()
434 .at(m_pParameters->GetAudioOutput()));
435 m_AudioOutput.setMuted(m_pParameters->GetAudioOutputMuted());
436 m_AudioOutput.setVolume(m_pParameters->GetAudioOutputVolume());
437 m_AudioOutput.disconnect();
438 bool check = connect(m_pParameters,
439 &CParameterPlayer::sigAudioOutputMuted,
440 &m_AudioOutput, &QAudioOutput::setMuted);
442 check = connect(m_pParameters, &CParameterPlayer::sigAudioOutputVolume,
443 &m_AudioOutput, &QAudioOutput::setVolume);
445 check = connect(m_pParameters, &CParameterPlayer::sigAudioOutput,
446 this, [&](
int nIndex) {
448 && nIndex < QMediaDevices::audioOutputs().size())
449 m_AudioOutput.setDevice(
450 QMediaDevices::audioOutputs().at(nIndex));
453 switch (m_pParameters->GetType()) {
454 case CParameterPlayer::TYPE::Camera:
455 m_CaptureSession.setAudioOutput(&m_AudioOutput);
457 case CParameterPlayer::TYPE::Url:
458 m_Player.setAudioOutput(&m_AudioOutput);
464 m_Player.setAudioOutput(
nullptr);
465 m_CaptureSession.setAudioOutput(
nullptr);
466 m_AudioOutput.disconnect();
470void CBackendPlayer::slotPositionChanged(qint64 pos)
475 qint64 currentInfo = pos / 1000;
476 qint64 duration = m_nDuration / 1000;
478 if (currentInfo || duration) {
479 QTime currentTime((currentInfo / 3600) % 60, (currentInfo / 60) % 60, currentInfo % 60,
480 (currentInfo * 1000) % 1000);
481 QTime totalTime((duration / 3600) % 60, (duration / 60) % 60, duration % 60,
482 (duration * 1000) % 1000);
483 QString format =
"mm:ss";
486 szStr = currentTime.toString(format) +
" / " + totalTime.toString(format);
487 emit sigPositionChanged(m_nPosition, m_nDuration);
492void CBackendPlayer::slotDurationChanged(qint64 duration)
495 m_nDuration = duration;
void sigUpdateRect(const QRect &r, const QImage &image)
通知视图,图像更新
virtual int OnClean() override
清理
virtual OnInitReturnValue OnInit() override
初始化
void sigRunning()
当插件开始成功后触发。仅由插件触发
void sigFinished()
停止成功信号。仅由插件触发