Bahramdun Adil
Bahramdun Adil

Reputation: 6079

Unable to play QMediaPlayer from a different thread

I am wondering why the QMediaPlayer not playing from another thread, but it starts play while the caller thread stopped.

For example:

Thread A call (calling is done by signals-slot) to thread B start to play MP3, but thread A continues his job, but thread B although receiving the play command, but still not playing, but when I stop the thread A, then the player starts playing. So thread A and B cannot be run at the same time.

Why it is like this, there is no any relation between these two threads, just a simple signal to thread B to start playing.

Code: Header

class Alarm : public QObject
{
    Q_OBJECT
public:
    Alarm();
    ~Alarm();

signals:
    void play();
    void stop();

private:
    QMediaPlayer *player;
    QThread alarmThread;
};

.cpp

Alarm::Alarm() : QObject()
{
    player = new QMediaPlayer;
    player->setMedia(QUrl("qrc:/media/alarm_music.mp3"));
    player->setVolume(80);
    connect(this, &Alarm::play, this, [this]() {
        if(player->state() == QMediaPlayer::PlayingState) {
            return;
        }
        player->play();
    });
    connect(this, &Alarm::stop, player, &QMediaPlayer::stop);

    moveToThread(&alarmThread);
    alarmThread.start();
}

Alarm::~Alarm()
{
    alarmThread.quit();
    alarmThread.wait();
    delete player;
}

Upvotes: 0

Views: 1146

Answers (1)

Ivan Belyaev
Ivan Belyaev

Reputation: 21

Since you instantiating QMediaPlayer without setting its parent, it continues to "live" in the thread where the Alarm object was constructed. If that thread has no event loop, QMediaPlayer will not function properly.

Also, it's unsafe to call start/stop from a thread that QMediaPlayer is not bound to.

Also, it is legit to construct a QObject by value; you don't have to use new to instantiate every single QObject.

Upvotes: 1

Related Questions