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;
 
Remote desktop interface.
 
void sigUpdateRect(const QRect &r, const QImage &image)
Notify the CFrmView update image.
 
virtual int OnClean() override
Clean.
 
virtual OnInitReturnValue OnInit() override
Initialization.
 
void sigRunning()
Emitted when the plugin is successfully started.
 
void sigFinished()
Successful stopped signal.