QMediaPlayer Not Loading Media And Not Emitting mediaStatusChanged() Signals

Viewed 3157

I've recently started working with Qt and am trying to play a sound file using QMediaPlayer.

My program compiles and runs but the sound file is not played, the QMediaPlayer seems stuck in the QMediaPlayer::LoadingMedia state.

Also - and possibly related - the QMediaPlayer doesn't ever seem to emit its mediaStatusChanged or its error signals (though perhaps this is me not connecting them properly?)

When I run the program as below, it reaches the while loop and never leaves. If I query for player->mediaStatus() inside the loop, it constantly returns 2 (QMediaPlayer::LoadingMedia).

When I run it with the while loop omitted, the program continues to run until it reaches end of execution with no run-time errors but - as you may expect - the file is not played.

Interestingly, the two couts before the while loop, which report player's mediaStatus and state show that the mediaStatus changes from 1 (in the first instance, before setting the media) to 2 (after setting the media) but my ChangedStatus slot is never called, despite connecting to the mediaStatusChanged at the start of the run function.

Running: Debian Jessie, Qt5.7/Qt5.9

AudioPlayer.h

#include <QThread>
#include <QMediaPlayer>

class AudioPlayer : public QThread {
    Q_OBJECT

public:
    AudioPlayer();

public slots:
    void ChangedStatus(QMediaPlayer::MediaStatus);
    void MediaError(QMediaPlayer::Error);

protected:
    void run();
};

AudioPlayer.cpp:

AudioPlayer::AudioPlayer(){}    
void AudioPlayer::run()
{
    QMediaPlayer* player = new QMediaPlayer();
    connect(player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(ChangedStatus(QMediaPlayer::MediaStatus)));
    connect(player, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(MediaError(QMediaPlayer::Error)));
    std::cout << "Got player!" << std::endl;

    std::cout << "\n\n\tPlayer state: " << player->state() << "\n\tMediaState: " << player->mediaStatus() << std::endl;

    player->setMedia(QUrl::fromLocalFile("/home/me/test.wav") );
    std::cout << "Set source" << std::endl;

    std::cout << "\n\n\tPlayer state: " << player->state() << "\n\tMediaState: " << player->mediaStatus() << std::endl;

    while(player->mediaStatus() != QMediaPlayer::MediaStatus::LoadedMedia)
    {//
    }

    player->setVolume(100);
    std::cout << "Set volume" << std::endl;

    player->play();
    std::cout << "Played" << std::endl;    
}    
void AudioPlayer::MediaError(QMediaPlayer::Error error)
{
    std::cout << "Media Error: " << error << std::endl;
}    
void AudioPlayer::ChangedStatus(QMediaPlayer::MediaStatus status)
{
    std::cout << "Status changed to: " << status << std::endl;
}

main.cpp:

#include "audioplayer.h"

using namespace std;

int main()
{
    cout << "Hello World!" << endl;

    AudioPlayer myAudioPlayer;
    myAudioPlayer.start();
    std::cout << "myAudioPlayer started. Waiting...." << std::endl;
    myAudioPlayer.wait();

    std::cout << "myAudioPlayer returned." << std::endl;

    return 0;
}

Extra Info:

Now, initially, I hadn't used QThread and was trying to do this all in main.cpp (just declaring a QMediaPlayer and attempting to set the media and play) but this was giving me QObject::startTimer: timers cannot be started from another thread warning run-time errors in a couple of places (declaration of the QMediaPlayer and, I think, the play command), so I adopted the above approach - although I'm not sure that subclassing QThread is, necessarily, the best way. This is also why everything (declarations etc.) is done in the run function - having the QMediaPlayer as a member of AudioPlayer and initialising it in the constructor gave the same error.

I have compiled and run Qt's Player example (from multimediawidgets) and, by browsing and selecting my test.wav, it can play the file so I don't think it's a compatibility issue. I looked through the Player example source but couldn't see anything jumping out which I had missed and which looked like the cause of my problem.

1 Answers
Related