Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Connect QAudioProbe to QMediaPlayer with RaspberryPi0



  • 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()
    {
    
    }
    
    
    



  • Qt Champions 2019

    @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?



  • 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");


  • Qt Champions 2019

    @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.



  • 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




Log in to reply