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

Mp3 not being played on android



  • OK, We've wasted quite a few hours on this one. Bumping on forums around opinions that one shouldn't be creating life-time objects on heap but on stack instead. what the heck?

    Anyway. We tried both approaches.

    The mp3 file is is within a resource file. Declared as follows:

    <file alias="syncing.mp3">voices/SFX/syncing.mp3</file>
    

    We try playing multiple ways:

    if(player->state()== QMediaPlayer::PlayingState)
                return false;
              file = prefix+file;
              QString path = CTools::getInstance()->stringToQstring(file);
              QUrl url = QUrl("qrc:///syncing.mp3");// QUrl(path);
              if(!url.isValid())
                  return false;
             bool islocal =  url.isLocalFile();
    
            player->setMedia(url);
            player->setVolume(100);
            player->play();
    
            QMediaPlayer playerL;
            playerL.setMedia(url);
            playerL.setVolume(100);
            playerL.play();
    
            QMediaPlayer playerL2;
            playerL2.setMedia(QUrl("qrc:/voices/SFX/syncing.mp3"));
            playerL2.setVolume(100);
            playerL2.play();
    

    No sound ever comes out from an Android device.

    Pro file includes:

    QT +=core gui
    QT += multimedia multimediawidgets
    QT += quickwidgets
    QT += gui-private
    QTPLUGIN += qtaudio_coreaudio
    QT += androidextras
        QT += widgets
        QT += quickcontrols2
    


  • After enabling plugging debagging through env variable only such warning can be seen

    W libGRIDNEToken_arm64-v8a.so: Found metadata in lib /data/app/org.gridnetproject.GRIDNEToken-cbPgHvvnQyOXOLsGnsZrNw==/lib/arm64/libplugins_mediaservice_qtmedia_android_arm64-v8a.so, metadata=
    W libGRIDNEToken_arm64-v8a.so: {
    W libGRIDNEToken_arm64-v8a.so:     "IID": "org.qt-project.qt.mediaserviceproviderfactory/5.0",
    W libGRIDNEToken_arm64-v8a.so:     "MetaData": {
    W libGRIDNEToken_arm64-v8a.so:         "Keys": [
    W libGRIDNEToken_arm64-v8a.so:             "androidmultimedia"
    W libGRIDNEToken_arm64-v8a.so:         ],
    W libGRIDNEToken_arm64-v8a.so:         "Services": [
    W libGRIDNEToken_arm64-v8a.so:             "org.qt-project.qt.camera",
    W libGRIDNEToken_arm64-v8a.so:             "org.qt-project.qt.mediaplayer",
    W libGRIDNEToken_arm64-v8a.so:             "org.qt-project.qt.audiosource"
    W libGRIDNEToken_arm64-v8a.so:         ]
    W libGRIDNEToken_arm64-v8a.so:     },
    W libGRIDNEToken_arm64-v8a.so:     "archreq": 0,
    W libGRIDNEToken_arm64-v8a.so:     "className": "QAndroidMediaServicePlugin",
    W libGRIDNEToken_arm64-v8a.so:     "debug": false,
    W libGRIDNEToken_arm64-v8a.so:     "version": 331520
    W libGRIDNEToken_arm64-v8a.so: }
    06-16 15:25:31.380  6640  6700 W li
    

    followed by

    D libGRIDNEToken_arm64-v8a.so: Got keys from plugin meta data ("androidmultimedia")
    D libGRIDNEToken_arm64-v8a.so: loaded library "/data/app/org.gridnetproject.GRIDNEToken-cbPgHvvnQyOXOLsGnsZrNw==/lib/arm64/libplugins_mediaservice_qtmedia_android_arm64-v8a.so"
    D libGRIDNEToken_arm64-v8a.so: QMediaPluginLoader: loaded plugins for key "org.qt-project.qt.mediaplayer" : ("androidmultimedia")
    D libGRIDNEToken_arm64-v8a.so: About to request permissions
    D libGRIDNEToken_arm64-v8a.so: Permissions granted
    


  • woooaww... hold on...

    Good thing: we got the sound to play.

    but we've still got to confirm what was breaking it... we'll be back



  • Turns out when file is declared in such a way within the resource file (note the voices directory):

     <qresource prefix="/new/prefix2">
            <file>voices/welcome.mp3</file>
        </qresource>
    

    the sound won't be played when referencing the file through

    QUrl("qrc:/new/prefix2/welcome.mp3")
    

    However

    when the mp3 file is not located within a directory and declared as

     <qresource prefix="/new/prefix2">
            <file>welcome.mp3</file>
        </qresource>
    

    the sound would be played.

    Is that a bug? Looks like one.

    Looks like the mp3 file doesn't make it into the binary resource file if located within a directory? is that the case? or for any other reason is not retrieved? should we file a bug-report?

    Note that in our project we've got images in nested directories and they are accessed fine. It's the case with QMediaPlayer being unable for some reason to access these.



  • @Vega4 said in Mp3 not being played on android:

    Turns out when file is declared in such a way within the resource file (note the voices directory):

    <qresource prefix="/new/prefix2">
         <file>voices/welcome.mp3</file>
     </qresource>
    

    the sound won't be played when referencing the file through

    When using sub-directories, you have to set alias or give the full path:

    Url("qrc:/new/prefix2/voices/welcome.mp3")
    

    or

        <qresource prefix="/new/prefix2">
             <file alias="welcome.mp3">voices/welcome.mp3</file>
         </qresource>
    

    and

    Url("qrc:/new/prefix2/welcome.mp3")
    


  • @KroMignon thank you so much! With full-path it indeed does work! bug... report.. what? had something like it even crossed our minds? Shame on us! Thank you for such an amazing development platform! Wizards keep on riding on!



  • @Vega4 said in Mp3 not being played on android:

    Thank you for such an amazing development platform!

    Your welcome, but I am only a Qt user, like you.



  • @KroMignon well then, I hope I can help you one day as well.



  • Just one more thing to note for all the other fellas. When if you choose to use an alias, the full-path wouldn't work anymore. This seems to hold true for any resource.



  • @KroMignon and other friends. Have you encountered such an issue?

    D mali_winsys: EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, EGLBoolean) returns 0x3000
    I HwViewRootImpl: removeInvalidNode all the node in jank list is out of time
    I MediaPlayer: [HSM] stayAwake false uid: 10275, pid: 14167
    D MediaPlayerNative: Action:stop, CurrentState:MEDIA_PLAYER_STOPPED
    D MediaPlayerNative: Message: Unknown MediaEventType(8), ext1=0, ext2=0x0
    D MediaPlayerNative: [notify] : [1170] callback app listenerNotNull=1, send=1
    V PlayerBase: baseStop() piid=13167
    I MediaPlayer: [HSM] stayAwake false uid: 10275, pid: 14167
    D MediaPlayerNative: Action:reset_l, CurrentState:MEDIA_PLAYER_IDLE
    V MediaPlayer: resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
    V MediaPlayer: cleanDrmObj: mDrmObj=null mDrmSessionId=null
    V PlayerBase: baseRelease() piid=13167 state=4
    I MediaPlayer: [HSM] stayAwake false uid: 10275, pid: 14167
    V MediaPlayer: resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
    V MediaPlayer: cleanDrmObj: mDrmObj=null mDrmSessionId=null
    I MediaPlayerNative: Pid:14167 MediaPlayer destructor MediaPlayer(0x70635cca40)
    D MediaPlayerNative: MediaPlayer::setVolume(1.000000, 1.000000)
    D MediaPlayerNative: Message: MEDIA_PREPARED(1), ext1=0, ext2=0x0
    D MediaPlayerNative: [notify] : [1170] callback app listenerNotNull=1, send=1
    

    happens all of the sudden on Android (pretty soon). From it, seemingly the underlying (android-native)media player gets stopped and destroyed.

    The QMediaPlayer object is allocated on heap (of course) access to it is synchronized through a mutex and audio-playback attempts attempted only when in an idle-state. Ideas?

    From what I can tell this causes the upper QMediaPlayer object ending up in an invalid state with playing status. Further references to it cause corruption.

    that's what happened a moment earlier:

    D MediaPlayerNative: Message: Unknown MediaEventType(8), ext1=0, ext2=0x0
    D MediaPlayerNative: [notify] : [1170] callback app listenerNotNull=1, send=1
    I MediaPlayer: [HSM] stayAwake false uid: 10275, pid: 14167
    D MediaPlayerNative: Action:reset_l, CurrentState:MEDIA_PLAYER_IDLE
    V MediaPlayer: resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
    V MediaPlayer: cleanDrmObj: mDrmObj=null mDrmSessionId=null
    V PlayerBase: baseRelease() piid=13159 state=4
    I MediaPlayer: [HSM] stayAwake false uid: 10275, pid: 14167
    V MediaPlayer: resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
    V MediaPlayer: cleanDrmObj: mDrmObj=null mDrmSessionId=null
    I MediaPlayerNative: Pid:14167 MediaPlayer destructor MediaPlayer(0x70635cca40)
    D MediaPlayerNative: MediaPlayer::setVolume(1.000000, 1.000000)
    D MediaPlayerNative: Message: MEDIA_PREPARED(1), ext1=0, ext2=0x0
    D MediaPlayerNative: [notify] : [1170] callback app listenerNotNull=1, send=1
    V PlayerBase: baseStart() piid=13167
    I MediaPlayer: [HSM] stayAwake true uid: 10275, pid: 14167
    D MediaPlayerNative: Action:start, CurrentState:MEDIA_PLAYER_STARTED
    D MediaPlayerNative: Message: Unknown MediaEventType(6), ext1=0, ext2=0x0
    D MediaPlayerNative: [notify] : [1170] callback app listenerNotNull=1, send=1
    D MediaPlayerNative: [notify] : [1170] callback app listenerNotNull=1, send=1
    D MediaPlayerNative: Message: MEDIA_PLAYBACK_COMPLETE(2), ext1=0, ext2=0x0
    D MediaPlayerNative: [notify] : [1170] callback app listenerNotNull=1, send=1
    V PlayerBase: baseStop() piid=13167
    D MediaPlayerNative: [notify] : [1170] callback app listenerNotNull=1, send=1
    I MediaPlayer: [HSM] stayAwake false uid: 10275, pid: 14167
    

    During normal operation it goes like this:

    D MediaPlayerNative: Action:reset_l, CurrentState:MEDIA_PLAYER_IDLE
    V MediaPlayer: resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
    V MediaPlayer: cleanDrmObj: mDrmObj=null mDrmSessionId=null
    V PlayerBase: baseRelease() piid=13583 state=4
    I MediaPlayer: [HSM] stayAwake false uid: 10275, pid: 20388
    V MediaPlayer: resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
    V MediaPlayer: cleanDrmObj: mDrmObj=null mDrmSessionId=null
    I MediaPlayerNative: Pid:20388 MediaPlayer destructor MediaPlayer(0x707d20ee00)
    D MediaPlayerNative: MediaPlayer::setVolume(1.000000, 1.000000)
    D MediaPlayerNative: Message: MEDIA_PREPARED(1), ext1=0, ext2=0x0
    D MediaPlayerNative: [notify] : [1170] callback app listenerNotNull=1, send=1
    V PlayerBase: baseStart() piid=13591
    I MediaPlayer: [HSM] stayAwake true uid: 10275, pid: 20388
    D MediaPlayerNative: Action:start, CurrentState:MEDIA_PLAYER_STARTED
    D MediaPlayerNative: Message: Unknown MediaEventType(6), ext1=0, ext2=0x0
    D MediaPlayerNative: [notify] : [1170] callback app listenerNotNull=1, send=1
    D MediaPlayerNative: [notify] : [1170] callback app listenerNotNull=1, send=1
    D MediaPlayerNative: Message: MEDIA_PLAYBACK_COMPLETE(2), ext1=0, ext2=0x0
    D MediaPlayerNative: [notify] : [1170] callback app listenerNotNull=1, send=1
    D MediaPlayerNative: [notify] : [1170] callback app listenerNotNull=1, send=1
    V PlayerBase: baseStop() piid=13591
    I MediaPlayer: [HSM] stayAwake false uid: 10275, pid: 20388
    


  • @Vega4 said in Mp3 not being played on android:

    happens all of the sudden on Android (pretty soon). From it, seemingly the underlying (android-native)media player gets stopped and destroyed.
    The QMediaPlayer object is allocated on heap (of course) access to it is synchronized through a mutex and audio-playback attempts attempted only when in an idle-state. Ideas?

    Sorry, I don't have so many experience with QMediaPlayer and Android.



  • @KroMignon

    No worries, seems like the legends were true. People place objects on stack since the support of state-management of underlying native objects is well... all it takes for it to become dead is for the window to get into the background.



  • after more investigation seems like the QMediaPlayer at least on Android is utterly broken.

    It's one thing to get it play an mp3 2-5 times it's entirely different thing for it to remain stable.

    We wanted to wrap around its problems by making a new instance every time it's used and use it's callbacks to manage state around these mechanics. No luck. Once one explicitly deletes an instance of QMediaPlayer no other instance would work.

    For instance the code below

    if(mPlayer!=nullptr)
        {//will be null only first time
            delete mPlayer;//we do this before rather than after as it might still be alive when receiving notificaiton about it stopping playing
            mPlayer=nullptr;
        }
    
        mPlayer = new QMediaPlayer();
       connect(mPlayer, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(playerStateChanged(QMediaPlayer::State)));
    

    Everything else held constant, were the player not delated and instantiated anew the sound would be played. BUT we delete it, create anew. no sound. We can't live with one global instance as it wouldn't survive.

    And were we to make an instance on stack as the legends advise we can't as we need to be using the on-change callback and the object would be destroyed thus slots not fire by the time the audio finishes playing.

    Abra kadabra.

    What seems to indicate that the QMediaPlayer is about to die is the following in log:

    MediaPlayerNative: Message: Unknown MediaEventType(8)
    

    QT relies on Android's player and Android devs call the player a 'State-Hell' so.... seems like QT devs need give it some love.
    link text



  • @Vega4 said in Mp3 not being played on android:

    resetDrmState

    Bug Report: here


Log in to reply