Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. QtonPi
  4. Connect QAudioProbe to QMediaPlayer with RaspberryPi0

Connect QAudioProbe to QMediaPlayer with RaspberryPi0

Scheduled Pinned Locked Moved Solved QtonPi
6 Posts 2 Posters 1.6k Views
  • 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.
  • D Offline
    D Offline
    davidino
    wrote on last edited by davidino
    #1

    Goodmorning,
    I'm using an image made with boot2qt version QT 5.12.0
    As shown in the code below I'm trying to get the audio level out of a mediaPlayer made in QML. I can correctly setSource to the mediaplayer but the slot processBuffer is never called.
    For information the audio is played via HDMI.
    Can you advice?

    #include <QObject>
    #include <QAudioProbe>
    #include <QMediaPlayer>
    #include <QTimer>
    #include <vector>
    #include <memory>
    
    #include "playListModel_global.h"
    
    class PLAYLISTMODEL_EXPORT VolumeLevel : public QObject
    {
        Q_OBJECT
    public:
        VolumeLevel(QObject *parent = nullptr);
        ~VolumeLevel();
    
        Q_INVOKABLE void initVolume(QString qmlObjectName);
        void initVolume(QMediaPlayer *player);
    
    public slots:
        void processBuffer(QAudioBuffer buffer);
        void timerExpired();
    
    private:
        QAudioProbe probe;
        QTimer timer;
        QMediaPlayer *player;
    };
    
    #endif // VOLUMELEVEL_H
    
    
    
    
    #include "volumelevel.h"
    #include <QDebug>
    
    #include <QAudioProbe>
    
    VolumeLevel::VolumeLevel(QObject *parent) :
        QObject(parent)
    {}
    
    void VolumeLevel::initVolume(QString qmlObjectName)
    {
        player = static_cast<QMediaPlayer*>(QObject::findChild<QObject*>(qmlObjectName));
        initVolume(player);
    }
    
    void VolumeLevel::initVolume(QMediaPlayer* player)
    {
        if(probe.setSource(player)) {
            connect(&probe, &QAudioProbe::audioBufferProbed, this, &VolumeLevel::processBuffer);
            connect(&timer, &QTimer::timeout, this, &VolumeLevel::timerExpired);
            qDebug()<<"Connection done";
            timer.start(1000);
        }
    }
    
    void VolumeLevel::processBuffer(QAudioBuffer buffer)
    {
        // With a 16bit sample buffer:
        const quint16 *data = buffer.constData<quint16>();
        qDebug()<<"Raw: "<<*data;
    }
    
    void VolumeLevel::timerExpired()
    {
        qDebug()<<"probe is active: "<<probe.isActive();
    }
    
    VolumeLevel::~VolumeLevel()
    {
    
    }
    
    
    
    jsulmJ 1 Reply Last reply
    0
    • D Offline
      D Offline
      davidino
      wrote on last edited by
      #6

      Here, you can find the solution.
      https://forum.qt.io/topic/115268/cast-a-qobject-to-qmediaplayer-with-qobject_cast

      Regards,
      Davidino

      1 Reply Last reply
      0
      • D davidino

        Goodmorning,
        I'm using an image made with boot2qt version QT 5.12.0
        As shown in the code below I'm trying to get the audio level out of a mediaPlayer made in QML. I can correctly setSource to the mediaplayer but the slot processBuffer is never called.
        For information the audio is played via HDMI.
        Can you advice?

        #include <QObject>
        #include <QAudioProbe>
        #include <QMediaPlayer>
        #include <QTimer>
        #include <vector>
        #include <memory>
        
        #include "playListModel_global.h"
        
        class PLAYLISTMODEL_EXPORT VolumeLevel : public QObject
        {
            Q_OBJECT
        public:
            VolumeLevel(QObject *parent = nullptr);
            ~VolumeLevel();
        
            Q_INVOKABLE void initVolume(QString qmlObjectName);
            void initVolume(QMediaPlayer *player);
        
        public slots:
            void processBuffer(QAudioBuffer buffer);
            void timerExpired();
        
        private:
            QAudioProbe probe;
            QTimer timer;
            QMediaPlayer *player;
        };
        
        #endif // VOLUMELEVEL_H
        
        
        
        
        #include "volumelevel.h"
        #include <QDebug>
        
        #include <QAudioProbe>
        
        VolumeLevel::VolumeLevel(QObject *parent) :
            QObject(parent)
        {}
        
        void VolumeLevel::initVolume(QString qmlObjectName)
        {
            player = static_cast<QMediaPlayer*>(QObject::findChild<QObject*>(qmlObjectName));
            initVolume(player);
        }
        
        void VolumeLevel::initVolume(QMediaPlayer* player)
        {
            if(probe.setSource(player)) {
                connect(&probe, &QAudioProbe::audioBufferProbed, this, &VolumeLevel::processBuffer);
                connect(&timer, &QTimer::timeout, this, &VolumeLevel::timerExpired);
                qDebug()<<"Connection done";
                timer.start(1000);
            }
        }
        
        void VolumeLevel::processBuffer(QAudioBuffer buffer)
        {
            // With a 16bit sample buffer:
            const quint16 *data = buffer.constData<quint16>();
            qDebug()<<"Raw: "<<*data;
        }
        
        void VolumeLevel::timerExpired()
        {
            qDebug()<<"probe is active: "<<probe.isActive();
        }
        
        VolumeLevel::~VolumeLevel()
        {
        
        }
        
        
        
        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #2

        @davidino said in Connect QAudioProbe to QMediaPlayer with RaspberryPi0:

        player = static_cast<QMediaPlayer*>(QObject::findChild<QObject*>(qmlObjectName));

        Did you check whether player is not nullptr?

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

        1 Reply Last reply
        1
        • D Offline
          D Offline
          davidino
          wrote on last edited by
          #3

          Hello @jsulm,
          you are right. I've modified the function as follow:

          void VolumeLevel::initVolume(QString qmlObjectName)
          {
              player = QObject::findChild<QMediaPlayer*>(qmlObjectName);
              if(player != nullptr)
                  initVolume(player);
              else
                  qDebug()<<"MediaPlayer not found "<<qmlObjectName;
          }
          

          Unfortunately I still get object not found. In QML the MediaPlayer is defined as follow:

              MediaPlayer {
                  id: playMusic
                  objectName: "mediaplayer"
                  autoLoad: true
                  autoPlay: true
                  playlist: Playlist{id:playerList}
                  property Volume volumeMeter : Volume {id: volume}
                  Component.onCompleted: volume.initVolume(playMusic.objectName)
              }
          

          I've register Volume in main.cpp as:
          qmlRegisterType<VolumeLevel>("VolumeLib", 1, 0, "Volume");

          jsulmJ 1 Reply Last reply
          0
          • D davidino

            Hello @jsulm,
            you are right. I've modified the function as follow:

            void VolumeLevel::initVolume(QString qmlObjectName)
            {
                player = QObject::findChild<QMediaPlayer*>(qmlObjectName);
                if(player != nullptr)
                    initVolume(player);
                else
                    qDebug()<<"MediaPlayer not found "<<qmlObjectName;
            }
            

            Unfortunately I still get object not found. In QML the MediaPlayer is defined as follow:

                MediaPlayer {
                    id: playMusic
                    objectName: "mediaplayer"
                    autoLoad: true
                    autoPlay: true
                    playlist: Playlist{id:playerList}
                    property Volume volumeMeter : Volume {id: volume}
                    Component.onCompleted: volume.initVolume(playMusic.objectName)
                }
            

            I've register Volume in main.cpp as:
            qmlRegisterType<VolumeLevel>("VolumeLib", 1, 0, "Volume");

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #4

            @davidino said in Connect QAudioProbe to QMediaPlayer with RaspberryPi0:

            QObject::findChild<QMediaPlayer*>(qmlObjectName);

            findChild() is not static! It finds children of a parent. You need to call findChild on the widget which is parent of your QML object.

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

            1 Reply Last reply
            1
            • D Offline
              D Offline
              davidino
              wrote on last edited by davidino
              #5

              Hello @jsulm ,
              you are right, I didn't read carefully the documentation. I tried several attempts and still I cannot figure it out. This is my last changing:

              void VolumeLevel::initVolume(QString qmlObjectName)
              {
                  if(parent() != nullptr) 
                  {
                      qDebug()<<"Parent name is: "<<parent()->objectName();
                      player = parent()->findChild<QMediaPlayer*>(qmlObjectName);
                      if(player != nullptr)
                          initVolume(player);
                      else
                          qDebug()<<"MediaPlayer not found "<<qmlObjectName;
                  }
              }
              
                  Item {
                      id: musicSystem
                      objectName: "musicSystem"
              
                      MediaPlayer {
                          id: playMusic
                          objectName: "mediaSystem"
                          autoLoad: true
                          autoPlay: true
                          playlist: Playlist{id:playerList}
                      }
                      Volume {id:volume; objectName: "volumeSystem"}
              
                      Component.onCompleted: volume.initVolume(playMusic.objectName)
                  }
              

              The result is the following, it can identify correctly musicSystem as the parent but not the mediaplayer
              Parent name is: "musicSystem"
              MediaPlayer not found "mediaSystem"

              I tried also with the approach:
              QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/music/MusicPage.qml")));
              QObject *object = component.create();
              but with no success.

              Thank you.
              Regards,
              Davide

              1 Reply Last reply
              0
              • D Offline
                D Offline
                davidino
                wrote on last edited by
                #6

                Here, you can find the solution.
                https://forum.qt.io/topic/115268/cast-a-qobject-to-qmediaplayer-with-qobject_cast

                Regards,
                Davidino

                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