QMediaPlayer in Altro Thread, non produce suono



  • Salve a tutti,
    ho fatto una ricerca nel forum ma non ho trovato nulla a riguardo.
    Ho realizzato un programma per simulare una slot Machine.
    Tutto funziona più o meno bene se non fosse che il suono della slot che ho messo non viene riprodotto nel thread scondario.
    Documentandomi ho visto che per poter eseguire il suono senza interrompere l'esecuzione del Thread principale è quello di utilizzare un Thread secondario.
    Ho testato la cosa sotto Windows e funziona, ma sotto Linux non c'è verso di riprodurre il suono.

    Questo il codice che ho scritto :
    mainWindow.h

    ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QTimer>
    #include <QSound>
    #include <QThread>
    #include <QMediaPlayer>
    #include <QMediaPlaylist>
    #include "ritardo.h"
    #include "roller.h"
    
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private slots:
        void on_pushButton_clicked();
        int getRand(int,int);
    
        void on_pushButton_2_clicked();
    
    private:
        Ui::MainWindow *ui;
        WorkerThread *workerThread;
    
    };
    
    #endif // MAINWINDOW_H
    
    

    roller.h

    ifndef ROLLER_H
    #define ROLLER_H
    #include <QThread>
    #include <QMediaPlayer>
    #include <QFileInfo>
    #include <QSound>
    
    
    
    class WorkerThread : public QThread
    {
        Q_OBJECT
        void run() override {
            QString result;
    
            this->playerM = new QMediaPlayer();
            this->playerM->setMedia(QUrl("file:///home/lemoeb/sound/roll.mp3"));
            
            this->playerM->setVolume(100);
         
            emit resultReady(result);
        }
    
    signals:
        void resultReady(const QString &s);
    private:
        QMediaPlayer *playerM;
        QSound *test;
    public:
        WorkerThread(){};
        ~WorkerThread(){
    
        }
        void stopPlayer(){
            this->playerM->stop();
    
        }
        void startPlayer(){
            this->playerM->play();
        }
    
    
    };
    
    
    #endif // ROLLER_H
    
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QTime>
    
    
    
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
    
        ui->setupUi(this);
        workerThread = new WorkerThread();
        workerThread->start();
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    int MainWindow::getRand(int low,int high){
    
        return qrand() % ((high + 1) - low) + low;
    }
    
    
    
    void MainWindow::on_pushButton_clicked()
    {
    
        int a,b,c,d=0;
        int stop1,stop2,stop3,stop4=0;
        int exit=0;
    
       workerThread->startPlayer();
    
    
        QTime time = QTime::currentTime();
        qsrand((uint)time.msec());
        for (int i=500;i>1;i--){
            if (i>470){
                exit=0;
              while (exit==0){
                 int n=getRand(1,9);
                 if (a!=n){
                     a=n;
                     exit=1;
                 }
              }
              QString immagine=QString::number(getRand(1,9));
              QPixmap pixmap("./image/" + immagine +".png");
              ui->label1->setPixmap(pixmap);
              ui->label1->repaint();
    
    
            }
            else
            {
                if (stop1==0){
    
                    stop1=1;
                }
            }
            if (i>440){
              exit=0;
              while (exit==0){
                 int n=getRand(1,9);
                 if (b!=n){
                     b=n;
                     exit=1;
                 }
              }
             // b=getRand(1,9);
    
              QPixmap pixmap2("./image/" + QString::number(getRand(1,9)) +".png");
              ui->label2->setPixmap(pixmap2);
              ui->label2->repaint();
            }
            if (i>410){
              //c=getRand(1,9);
              exit=0;
              while (exit==0){
                 int n=getRand(1,9);
                 if (c!=n){
                     c=n;
                     exit=1;
                 }
              }
              QPixmap pixmap3("./image/" + QString::number(getRand(1,9)) +".png");
              ui->label3->setPixmap(pixmap3);
              ui->label3->repaint();
            }
            if (i>380){
              d=getRand(1,9);
              exit=0;
              while (exit==0){
                 int n=getRand(1,9);
                 if (d!=n){
                     d=n;
                     exit=1;
                 }
              }
              QPixmap pixmap4("./image/" + QString::number(getRand(1,9)) +".png");
              ui->label4->setPixmap(pixmap4);
              ui->label4->repaint();
            }
            ui->lblCount->setText(QString::number(i));
            if (i>380){
                QTime timeStart = QTime::currentTime();
                QTime timeStop=timeStart.addMSecs(50);
                while (timeStart < timeStop){
                    timeStart = QTime::currentTime();
                }
            }
            else
            {
                //this->workerThread->stopPlayer();
                ui->lblCount->setText("STOP");
            }
    
    
        }
    
    
        //QPixmap pixmap("./image/" + immagine +".png");
    
    }
    
    void MainWindow::on_pushButton_2_clicked()
    {
        //QSound::play("./sound/stop.wav");
    
       // roll.play();
    }
    

    SlotMachine.pro

    #
    # Project created by QtCreator 2017-12-11T22:07:06
    #
    #-------------------------------------------------
    
    QT       += core gui
    QT += multimedia
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = SlotMachine
    TEMPLATE = app
    
    # The following define makes your compiler emit warnings if you use
    # any feature of Qt which has been marked as deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    
    # You can also make your code fail to compile if you use deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    
    SOURCES += \
            main.cpp \
            mainwindow.cpp
    
    HEADERS += \
            mainwindow.h \
        ritardo.h \
        roller.h
    
    FORMS += \
            mainwindow.ui
    
    

    Qualcuno sa aiutarmi a riguardo?

    Vi ringrazio in anticipo.

    Leandro



  • Il problema e' nel thread. la soluzione veloce e':

    • aggiungi exec() come ultima linea di run()
    • in stopPlayer cancella quello che hai e aggiungi QTimer::singleSot(0,playerM,&QMediaPlayer::stop);
    • in startPlayer cancella quello che hai e aggiungi QTimer::singleSot(0,playerM,&QMediaPlayer::play);
    • Aggiungi delete playerM; in ~WorkerThread()
    • Aggiungi workerThread->quit(); workerThread->wait(); delete workerThread;
      in ~MainWindow()

    Se vuoi un po' piu' di dettagli: https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

    P.S.

    Documentandomi ho visto che per poter eseguire il suono senza interrompere l'esecuzione del Thread principale è quello di utilizzare un Thread secondario.

    Non sono sicuro che questo sia vero ma ti credo sulla parola



  • @VRonin Grazie per le informazioni, proverò le tue indicazioni e ti farò sapere.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.