QT5 QMediaPlayer not displaying video in qt based C++ code built using visual Studio 2017

102 Views Asked by At

I have a C++ on windows GUI project which we build using visual studio 2017. The GUI is written using QT 5. We dont use qt creator. In one of the widget I have to play a video using QT for which I am trying to use QMediaPlayer. I took a code snippet from the documentation. In the gui we select a file and then click on the play button which is supposed to play the video.

Code builds properly but while running video is not displayed and the widget screen remains blank. The m_mediaPlayer->state() and m_mediaPlayer->mediaStatus() both are always 0.

After the call to API setMedia() we see a mediaplayer error 5 i.e. QMediaPlayer::ServiceMissingError

How to play the video using qt api in this c++ windows code?

blank screen

Code is as follows:

Header File

#include <QFileDialog>
#include <QStandardPaths>

#include <QtMultimedia/qmediacontent.h>
#include <QtMultimedia/qmediaplayer.h>
#include <QtMultimediaWidgets/qvideowidget.h>
#include <QtMultimedia/qmediaplaylist.h>

class signalWidget : public QWidget
{
public:
    QVideoWidget *videoWidget;
    QMediaPlayer* m_mediaPlayer;
    QAbstractButton *m_playButton;
    QSlider *m_positionSlider;
    QLabel *m_errorLabel;
    void setUrl(const QUrl &url);

public slots:
        void openFile();
        void play();    
        void mediaStateChanged(QMediaPlayer::State state);
        void positionChanged(qint64 position);
        void durationChanged(qint64 duration);
        void setPosition(int position);
        void handleError();
};

Source File

void signalWidget::handleError()
{
    m_playButton->setEnabled(false);
    const QString errorString = m_mediaPlayer->errorString();
    QString message = "Error: ";
    if (errorString.isEmpty())
        message += " #" + QString::number(int(m_mediaPlayer->error()));
    else
        message += errorString;
    m_errorLabel->setText(message);

    std::cout << " ERROR = " << message.toStdString() << "\n";
}

void signalWidget::positionChanged(qint64 position)
{
std::cout << " position = " << position << "\n";
    m_positionSlider->setValue(position);
}

void signalWidget::durationChanged(qint64 duration)
{
std::cout << " duration = " << duration << "\n";
    m_positionSlider->setRange(0, duration);
}

void signalWidget::setPosition(int position)
{
std::cout << " position = " << position << "\n";
    m_mediaPlayer->setPosition(position);
}

void signalWidget::mediaStateChanged(QMediaPlayer::State state)
{
    std::cout << " state = " << state << "\n";
    switch(state) {
    case QMediaPlayer::PlayingState:
        m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause));
        break;
    default:
        m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
        break;
    }
}

 void signalWidget::MediaError(QMediaPlayer::Error error)
 {
  std::cout << " Media Error: " << error << "\n";
 }

 void signalWidget::ChangedStatus(QMediaPlayer::MediaStatus status)
 {
  std::cout << " Status changed to: " << status << "\n";
 }

void signalWidget::play()
{
std::cout << " currentMedia = " << m_mediaPlayer->currentMedia().canonicalUrl().toString().toStdString() << 
                                                    ", playerState = " << m_mediaPlayer->state() << "   E\n";

    switch (m_mediaPlayer->state()) {
    case QMediaPlayer::PlayingState:
        m_mediaPlayer->pause();
        break;
    default:
        m_mediaPlayer->play();
        break;
    }

    std::cout << " playerState = " << m_mediaPlayer->state() << ", playerMediaState = " << m_mediaPlayer->mediaStatus() << "\n";
}

void signalWidget::setUrl(const QUrl &url)
{
    m_errorLabel->setText(QString());
    setWindowFilePath(url.isLocalFile() ? url.toLocalFile() : QString());
    m_mediaPlayer->setMedia(url);
    m_playButton->setEnabled(true);
std::cout << " currentMedia = " << m_mediaPlayer->currentMedia().canonicalUrl().toString().toStdString() << 
                                                    ", player State = " << m_mediaPlayer->state() <<
                                                    ", player ERROR = " << m_mediaPlayer->error();

}

void signalWidget::openFile()
{
    QFileDialog fileDialog(this);
    fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
    fileDialog.setWindowTitle(tr("Open Movie"));
    QStringList supportedMimeTypes = m_mediaPlayer->supportedMimeTypes();
    if (!supportedMimeTypes.isEmpty())
        fileDialog.setMimeTypeFilters(supportedMimeTypes);
    fileDialog.setDirectory(QStandardPaths::standardLocations(QStandardPaths::MoviesLocation).value(0, QDir::homePath()));
    if (fileDialog.exec() == QDialog::Accepted)
        setUrl(fileDialog.selectedUrls().constFirst());
}

Use of the above code

signalWidget::signalWidget(int widget_id)
{
        m_mediaPlayer = new QMediaPlayer(this, QMediaPlayer::VideoSurface);
        videoWidget = new QVideoWidget;
    
        QAbstractButton *openButton = new QPushButton(tr("Open..."));
        connect(openButton,SIGNAL(clicked()),this,SLOT(openFile()));

        m_playButton = new QPushButton;
        m_playButton->setEnabled(false);
        m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
        connect(m_playButton, SIGNAL(clicked()), this, SLOT(play()));

        m_positionSlider = new QSlider(Qt::Horizontal);
        m_positionSlider->setRange(0, 0);
        connect(m_positionSlider, SIGNAL(sliderMoved()), this, SLOT(setPosition()));

        m_errorLabel = new QLabel;
        m_errorLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);

        m_errorLabel->setAutoFillBackground(true); // IMPORTANT!
        m_errorLabel->setStyleSheet("QLabel { background-color : pink; color : blue; }");

        QBoxLayout *controlLayout = new QHBoxLayout;
        controlLayout->setMargin(0);
        controlLayout->addWidget(openButton);
        controlLayout->addWidget(m_playButton);
        controlLayout->addWidget(m_positionSlider);

        QBoxLayout *layout = new QVBoxLayout;
        layout->addWidget(videoWidget);
        layout->addLayout(controlLayout);
        layout->addWidget(m_errorLabel);
        layout->setMargin(0); //! to avoid wasting spaces with margins
        setLayout(layout);

        m_mediaPlayer->setVideoOutput(videoWidget);
        connect(m_mediaPlayer, SIGNAL(stateChanged()), this, SLOT(mediaStateChanged()));
        connect(m_mediaPlayer, SIGNAL(positionChanged()), this, SLOT(mediaStateChanged()));
        connect(m_mediaPlayer, SIGNAL(durationChanged()), this, SLOT(durationChanged()));
        connect(m_mediaPlayer, SIGNAL(Error()), this, SLOT(handleError()));

}
0

There are 0 best solutions below