Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Play mp3 on QAudioOutput with Python
Forum Updated to NodeBB v4.3 + New Features

Play mp3 on QAudioOutput with Python

Scheduled Pinned Locked Moved Unsolved Qt for Python
15 Posts 3 Posters 2.5k 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.
  • F Offline
    F Offline
    Flanagan
    wrote on last edited by Flanagan
    #1

    I've been trying this for a week and can't get it.

    I need to play mp3 sounds through a specific device (not the default output of the operating system). For wav I have succeeded but when I need play mp3 I get into decoders everything becomes very complicated and superior to me.

    In the documentation I have only found this:
    https://doc.qt.io/qt-5/audiooverview.html

    QAudioFormat desiredFormat;
    desiredFormat.setChannelCount(2);
    desiredFormat.setCodec("audio/x-raw");
    desiredFormat.setSampleType(QAudioFormat::UnSignedInt);
    desiredFormat.setSampleRate(48000);
    desiredFormat.setSampleSize(16);
    
    QAudioDecoder *decoder = new QAudioDecoder(this);
    decoder->setAudioFormat(desiredFormat);
    decoder->setSourceFilename("level1.mp3");
    
    connect(decoder, SIGNAL(bufferReady()), this, SLOT(readBuffer()));
    decoder->start();
    
    // Now wait for bufferReady() signal and call decoder->read()
    

    But:

    1. I don't know if that's enough to read mp3.
    2. if it is enough, I don't know how to send the bytes data to the QAudioOutput.

    I have also found a couple of examples with c++:
    https://code.qt.io/cgit/qt/qtmultimedia.git/tree/examples/multimedia/audiodecoder/audiodecoder.cpp
    https://stackoverflow.com/questions/41197576/how-to-play-mp3-file-using-qaudiooutput-and-qaudiodecoder

    But when reading the decoder it returns a QAudioBuffer and I don't know how to transmit the data of said buffer to the QAudioOutput either.

    I am working on python app. I am not a c ++ expert and what little I have found is in that language...

    Thank you.

    JonBJ 1 Reply Last reply
    0
    • F Flanagan

      I've been trying this for a week and can't get it.

      I need to play mp3 sounds through a specific device (not the default output of the operating system). For wav I have succeeded but when I need play mp3 I get into decoders everything becomes very complicated and superior to me.

      In the documentation I have only found this:
      https://doc.qt.io/qt-5/audiooverview.html

      QAudioFormat desiredFormat;
      desiredFormat.setChannelCount(2);
      desiredFormat.setCodec("audio/x-raw");
      desiredFormat.setSampleType(QAudioFormat::UnSignedInt);
      desiredFormat.setSampleRate(48000);
      desiredFormat.setSampleSize(16);
      
      QAudioDecoder *decoder = new QAudioDecoder(this);
      decoder->setAudioFormat(desiredFormat);
      decoder->setSourceFilename("level1.mp3");
      
      connect(decoder, SIGNAL(bufferReady()), this, SLOT(readBuffer()));
      decoder->start();
      
      // Now wait for bufferReady() signal and call decoder->read()
      

      But:

      1. I don't know if that's enough to read mp3.
      2. if it is enough, I don't know how to send the bytes data to the QAudioOutput.

      I have also found a couple of examples with c++:
      https://code.qt.io/cgit/qt/qtmultimedia.git/tree/examples/multimedia/audiodecoder/audiodecoder.cpp
      https://stackoverflow.com/questions/41197576/how-to-play-mp3-file-using-qaudiooutput-and-qaudiodecoder

      But when reading the decoder it returns a QAudioBuffer and I don't know how to transmit the data of said buffer to the QAudioOutput either.

      I am working on python app. I am not a c ++ expert and what little I have found is in that language...

      Thank you.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @Flanagan said in Play mp3 on QAudioOutput with Python:

      But when reading the decoder it returns a QAudioBuffer and I don't know how to transmit the data of said buffer to the QAudioOutput either.

      With the proviso that I know nothing about this, so no point questioning me further... !

      I would say, given a bunch of bytes to send:

      • QIODevice *QAudioOutput::start() returns a QIODevice *, You can QIODevice::write() to this from a byte array.

      • void QAudioOutput::start(QIODevice *device) takes a QIODevice * argument, which could be a QBuffer "The QBuffer class provides a QIODevice interface for a QByteArray."

      F 1 Reply Last reply
      0
      • JonBJ JonB

        @Flanagan said in Play mp3 on QAudioOutput with Python:

        But when reading the decoder it returns a QAudioBuffer and I don't know how to transmit the data of said buffer to the QAudioOutput either.

        With the proviso that I know nothing about this, so no point questioning me further... !

        I would say, given a bunch of bytes to send:

        • QIODevice *QAudioOutput::start() returns a QIODevice *, You can QIODevice::write() to this from a byte array.

        • void QAudioOutput::start(QIODevice *device) takes a QIODevice * argument, which could be a QBuffer "The QBuffer class provides a QIODevice interface for a QByteArray."

        F Offline
        F Offline
        Flanagan
        wrote on last edited by
        #3

        @JonB But the problem is that reading the decoder returns a QAudioBuffer, not a QBuffer. They are different objects and do not inherit from each other.

        I can access the data from the QAudioBuffer with .consData () but it returns a pointer and I can't use that data to send it through a QAudioOutput.

        JonBJ 1 Reply Last reply
        0
        • F Flanagan

          @JonB But the problem is that reading the decoder returns a QAudioBuffer, not a QBuffer. They are different objects and do not inherit from each other.

          I can access the data from the QAudioBuffer with .consData () but it returns a pointer and I can't use that data to send it through a QAudioOutput.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @Flanagan
          Like I said, not my area. But I don't understand your response. For example, QBuffer runs off QByteArray/bytes/chars whatever, and QAudioBuffer::constData() provides access to the data, so I don't get

          I can't use that data to send it through a QAudioOutput

          but you may know better than I.

          F 1 Reply Last reply
          0
          • JonBJ JonB

            @Flanagan
            Like I said, not my area. But I don't understand your response. For example, QBuffer runs off QByteArray/bytes/chars whatever, and QAudioBuffer::constData() provides access to the data, so I don't get

            I can't use that data to send it through a QAudioOutput

            but you may know better than I.

            F Offline
            F Offline
            Flanagan
            wrote on last edited by
            #5

            @JonB QAudioBuffer::constData() returns a pointer, i dont know, with python, how to make QByteArray from that pointer or send that data otherwise to QAudioOutput.

            JonBJ 1 Reply Last reply
            0
            • F Flanagan

              @JonB QAudioBuffer::constData() returns a pointer, i dont know, with python, how to make QByteArray from that pointer or send that data otherwise to QAudioOutput.

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #6

              @Flanagan
              Ah, I forgot you were Python! I can see that might be a problem....

              You really should say whether you are PyQt5 or PySide2? Does yours have QAudioBuffer::constData() or QAudioBuffer::data()? What does that say it returns? Have you tried just slapping in things like:

              buf = QBuffer(audioBuf.constData())
              buf = bytes(audioBuf.data())
              

              and crossing your fingers?

              At which point maybe I should butt out, perhaps someone knows more about what is required for your issue.

              F 1 Reply Last reply
              0
              • JonBJ JonB

                @Flanagan
                Ah, I forgot you were Python! I can see that might be a problem....

                You really should say whether you are PyQt5 or PySide2? Does yours have QAudioBuffer::constData() or QAudioBuffer::data()? What does that say it returns? Have you tried just slapping in things like:

                buf = QBuffer(audioBuf.constData())
                buf = bytes(audioBuf.data())
                

                and crossing your fingers?

                At which point maybe I should butt out, perhaps someone knows more about what is required for your issue.

                F Offline
                F Offline
                Flanagan
                wrote on last edited by
                #7

                @JonB I use PySide2.
                QAudioBuffer.constData() and QAudioBuffer.data() return ´´´VoidPtr´´´ -> <class 'shiboken2.shiboken2.VoidPtr'>

                Apparently with your second option I do manage to create a QByteArray and, therefore, QBuffer but I don't hear anything.

                No error, but no sound.

                from PySide2 import QtWidgets, QtMultimedia
                from PySide2.QtCore import QBuffer, QByteArray
                from PySide2.QtMultimedia import QAudioOutput, QAudioDecoder
                
                
                def my_read():
                    audio_buffer = decoder.read()
                    data = bytes(audio_buffer.constData())
                    buffer = QBuffer(QByteArray(data))
                    output.start(buffer)
                
                app = QtWidgets.QApplication([])
                
                devices = QtMultimedia.QAudioDeviceInfo.availableDevices(QtMultimedia.QAudio.AudioOutput)
                device = devices[0]
                desire_audio_format = device.preferredFormat()
                
                output = QAudioOutput(device, desire_audio_format)
                
                decoder = QAudioDecoder()
                decoder.setAudioFormat(desire_audio_format)
                decoder.setSourceFilename('song.mp3')
                decoder.bufferReady.connect(my_read)
                decoder.start()
                
                app.exec_()
                
                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Hi,

                  Something worth checking: QAudioOutputSelectorControl.

                  Try to get the one from QMediaPlayer and change the output to the one you want to use. That way you do not need to go low level.

                  Hope it helps

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

                  F 1 Reply Last reply
                  0
                  • SGaistS SGaist

                    Hi,

                    Something worth checking: QAudioOutputSelectorControl.

                    Try to get the one from QMediaPlayer and change the output to the one you want to use. That way you do not need to go low level.

                    Hope it helps

                    F Offline
                    F Offline
                    Flanagan
                    wrote on last edited by
                    #9

                    @SGaist Thank you for the approach, i see QAudioOutputSelectorControl is deprecated9940b75f-f5a7-466e-ad74-de581d705a8a-image.png

                    Why is obsolete? There isn't alternative for change output of mediaplayer?

                    I have tried this but the output is not changed, I think I am not passing the correct string to the QAudioOutputSelectorControl :: setActiveOutput method.

                    I have found this example and have relied on it to do the following: https://stackoverflow.com/questions/28408590/qt5-how-to-set-default-audio-device-for-qmediaplayer
                    Sounds good but it sounds in the output of the operating system (devices[0]) and I want it in another (devices[1])

                    from PySide2 import QtWidgets, QtMultimedia
                    from PySide2.QtCore import QBuffer, QByteArray, QUrl
                    from PySide2.QtMultimedia import QAudioOutput, QAudioDecoder, QMediaPlayer
                    
                    app = QtWidgets.QApplication([])
                    
                    devices = QtMultimedia.QAudioDeviceInfo.availableDevices(QtMultimedia.QAudio.AudioOutput)
                    device = devices[1]
                    desire_audio_format = device.preferredFormat()
                    
                    player = QMediaPlayer()
                    player.setMedia(QUrl.fromLocalFile('song.mp3'))
                    player.play()
                    service = player.service()
                    control = service.requestControl('org.qt-project.qt.audiooutputselectorcontrol/5.0')
                    control.setActiveOutput(device.deviceName())
                    service.releaseControl(control)
                    
                    app.exec_()
                    
                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      That is don't know, I completely missed the obsolete warning.

                      Did you try to change the output before starting to play the file ?

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

                      F 1 Reply Last reply
                      0
                      • SGaistS SGaist

                        That is don't know, I completely missed the obsolete warning.

                        Did you try to change the output before starting to play the file ?

                        F Offline
                        F Offline
                        Flanagan
                        wrote on last edited by
                        #11

                        @SGaist Yes, it is the same :/. I read on stackoverflow i need device's id, not the name. I dont know where get that

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

                          Do you mean from the code on the stack overflow thread ?

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

                          F 1 Reply Last reply
                          0
                          • SGaistS SGaist

                            Do you mean from the code on the stack overflow thread ?

                            F Offline
                            F Offline
                            Flanagan
                            wrote on last edited by
                            #13

                            @SGaist I have these output devices on my pc:
                            d27c7048-9a2e-41ea-af5e-17daec4d6369-image.png

                            I have a output device (a virtual cable called CABLE Input) that emit sounds to a input device (called Cable Output). The list only show my output devices.

                            I want play mp3 on my second output -> CABLE Input (VB-Audio Virtual Cable)

                            It seems that is his name but not his ID, i saw in stackoverflow i need the ID and pass to the method QAudioOutputSelectorControl.setActiveOutput a string ID.

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

                              So you have an external application that allows you to do input/output mixing ?

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

                              F 1 Reply Last reply
                              0
                              • SGaistS SGaist

                                So you have an external application that allows you to do input/output mixing ?

                                F Offline
                                F Offline
                                Flanagan
                                wrote on last edited by
                                #15

                                @SGaist Yes, it's this: https://www.vb-audio.com/Cable/

                                Although it doesn't matter, I only want to play mp3 in any output of my choice. That virtual cable or any other that is not the default of the operating system.

                                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