Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QmediaPlayer does not signal when mp3 (audio only) ends
Forum Updated to NodeBB v4.3 + New Features

QmediaPlayer does not signal when mp3 (audio only) ends

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 769 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Mosquito92
    wrote on last edited by
    #1

    QMediaPlayer EndOfMedia StoppedState mp3 audio QCoreApplication```

    The following short application plays mp3 audio files just fine, but when executed from a command line, I would like the application to block until the mp3 file (whose name is input thru argv[1]) ends. The app as written does not block, but immediately returns control to the console while the process remains running in memory. The process continues after the mp3 sound file has played to the end. The process does not end until it is killed.

    Questions:

    1. Why does QMediaPlayer not signal stoppedState?
    2. Why does QMediaPlayer not signal EndOfMedia?
    3. Is there a way to cause QCoreApplication to block return of the console until the process ends?
    #ifndef PLAYNEXIT_HPP
    #define PLAYNEXIT_HPP
    #include <QMediaPlayer>
    #include <QDebug>
    #include <Protos/qexp.h>
    
    class EXPQCLS playNexit: public QMediaPlayer{
      Q_OBJECT
      public:
       playNexit(QObject *parent = 0) : QMediaPlayer(parent){}
    
       public slots:
        void run(char* filename)
        {
         connect(this,SIGNAL(stateChanged(QMediaPlayer::State state)),this,SLOT(exitWhenStopped()));
         connect(this,SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus status)),this,SLOT(exitWhenStopped()));
         setMedia(QUrl::fromLocalFile(filename));
         setVolume(50);
         play();
         qInfo() << "Playing Media.";
        }
    
        void exitWhenStopped()
        {
         if (this->mediaStatus() ==QMediaPlayer::EndOfMedia)
         {
          qInfo() << "End of Media.";
          emit finished();
         }
         if (this->state()==QMediaPlayer::StoppedState)
         {
          qInfo() << "Stopped State.";
          emit finished();
         }
        }
    
      signals:
       void finished();
    };
    
    #endif // PLAYNEXIT_HPP
    
    
    #include <QtCore>
    #include <QCoreApplication>
    #include "playNexit.hpp"
    int main(int argc, char *argv[])
    {
      QCoreApplication a(argc, argv);
      playNexit pNe;
      QObject::connect(&pNe, &playNexit::finished,
                         &a, &QCoreApplication::quit,
                         Qt::QueuedConnection);
      pNe.run(argv[1]);
      return a.exec();
    }
    
    jsulmJ 1 Reply Last reply
    0
    • M Mosquito92

      QMediaPlayer EndOfMedia StoppedState mp3 audio QCoreApplication```

      The following short application plays mp3 audio files just fine, but when executed from a command line, I would like the application to block until the mp3 file (whose name is input thru argv[1]) ends. The app as written does not block, but immediately returns control to the console while the process remains running in memory. The process continues after the mp3 sound file has played to the end. The process does not end until it is killed.

      Questions:

      1. Why does QMediaPlayer not signal stoppedState?
      2. Why does QMediaPlayer not signal EndOfMedia?
      3. Is there a way to cause QCoreApplication to block return of the console until the process ends?
      #ifndef PLAYNEXIT_HPP
      #define PLAYNEXIT_HPP
      #include <QMediaPlayer>
      #include <QDebug>
      #include <Protos/qexp.h>
      
      class EXPQCLS playNexit: public QMediaPlayer{
        Q_OBJECT
        public:
         playNexit(QObject *parent = 0) : QMediaPlayer(parent){}
      
         public slots:
          void run(char* filename)
          {
           connect(this,SIGNAL(stateChanged(QMediaPlayer::State state)),this,SLOT(exitWhenStopped()));
           connect(this,SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus status)),this,SLOT(exitWhenStopped()));
           setMedia(QUrl::fromLocalFile(filename));
           setVolume(50);
           play();
           qInfo() << "Playing Media.";
          }
      
          void exitWhenStopped()
          {
           if (this->mediaStatus() ==QMediaPlayer::EndOfMedia)
           {
            qInfo() << "End of Media.";
            emit finished();
           }
           if (this->state()==QMediaPlayer::StoppedState)
           {
            qInfo() << "Stopped State.";
            emit finished();
           }
          }
      
        signals:
         void finished();
      };
      
      #endif // PLAYNEXIT_HPP
      
      
      #include <QtCore>
      #include <QCoreApplication>
      #include "playNexit.hpp"
      int main(int argc, char *argv[])
      {
        QCoreApplication a(argc, argv);
        playNexit pNe;
        QObject::connect(&pNe, &playNexit::finished,
                           &a, &QCoreApplication::quit,
                           Qt::QueuedConnection);
        pNe.run(argv[1]);
        return a.exec();
      }
      
      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Mosquito92 said in QmediaPlayer does not signal when mp3 (audio only) ends:

      connect(this,SIGNAL(stateChanged(QMediaPlayer::State state)),this,SLOT(exitWhenStopped()));

      Remove "state" parameter name from SIGNAL. Same for second connect.
      Better to use new Qt5 connect syntax: https://wiki.qt.io/New_Signal_Slot_Syntax

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      M 1 Reply Last reply
      1
      • jsulmJ jsulm

        @Mosquito92 said in QmediaPlayer does not signal when mp3 (audio only) ends:

        connect(this,SIGNAL(stateChanged(QMediaPlayer::State state)),this,SLOT(exitWhenStopped()));

        Remove "state" parameter name from SIGNAL. Same for second connect.
        Better to use new Qt5 connect syntax: https://wiki.qt.io/New_Signal_Slot_Syntax

        M Offline
        M Offline
        Mosquito92
        wrote on last edited by
        #3

        @jsulm Thank you so much for your reply!
        Your suggestion to remove the state variable from the SIGNAL statement made looking for the EndOfMedia signal superfluous, and now the process does stop when the mp3 sound file has finished.

        Is there any way to make QCoreApplication block until the quit is received? (In other words is there a way to alter QCoreApplication so it does not immediately return control to the console)?

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by SGaist
          #4

          Hi,

          If you to do some stuff after exec returns, just store the result of the call, do what you need and then return the value.

              int result = app.exec();
              // add fancy code
              return result; // or some other status code that make sense from your code.
          }
          

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          1
          • M Offline
            M Offline
            Mosquito92
            wrote on last edited by
            #5

            Thankyou for your reply, but I'm unable to see exactly what to do in this situation. Modified as below, the application generates no errors, and does play an mp3 sound only file to its completion which can take seconds. But the application also returns control of the console immediately (long before the sound file ends and long before main() exits???). I want the app to give control back to the console only after the mp3 has quit playing. Odd as it may seem, that is not what happens, and the mutex (which I thought would block main() from exiting does indeed do that, but it does not keep control from returning to the console almost immediately.

            Here is my main application with the changes described:

            #include <QtCore>
            #include <QCoreApplication> 
            #include "playNexit.hpp"
            
            int main(int argc, char *argv[])
            {
              QCoreApplication a(argc, argv);
              playNexit pNe;
              QMutex mutex;
              QObject::connect(&pNe, &playNexit::finished,
                                 &a, &QCoreApplication::quit,
                                 Qt::QueuedConnection);
            
              pNe.setMutex(&mutex);
              mutex.lock(); // 1st lock takes the semaphore
              pNe.run(argv[1]);
              a.exec();
              mutex.lock(); // 2nd lock should cause app to block until unlock.
              return 0;
            }
            

            And here is the playNexit class derived from QMediaPlayer:

            #ifndef PLAYNEXIT_HPP
            #define PLAYNEXIT_HPP
            #include <QMutex>
            #include <QMediaPlayer>
            #include <Protos/qexp.h>
            class EXPQCLS playNexit: public QMediaPlayer{
              Q_OBJECT
              public:
               playNexit(QObject *parent = 0) : QMediaPlayer(parent){}
            
               public slots:
                void run(char *filename)
                {
                 connect(this,SIGNAL(stateChanged(QMediaPlayer::State)),this,SLOT(exitWhenStopped()));
                 setMedia(QUrl::fromLocalFile(filename));
                 setVolume(50);
                 play();
                }
            
                void exitWhenStopped()
                {
                 if (this->state()==QMediaPlayer::StoppedState)
                 {
                  pMutex->unlock(); // main thread should release 2nd lock?
                  emit finished();
                 }
                }
            
              signals:
               void finished();
            
              public:
              QMutex *pMutex;
              void setMutex(QMutex *pm)
              {
               pMutex = pm;
              }
            
            };
            
            #endif // PLAYNEXIT_HPP
            
            

            I tried using a QMutex to lock the main after a.exec(), and to have a pointer to the mutex unlock() just before emit finished in the exitwhenStopped() function, but it did not seem to work. This still sounds like the right approach...

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              That should not be needed.

              Did you check all the states your QMediaPlayer goes through ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved