Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Audio files don't play in QML app on iPhone
Forum Updated to NodeBB v4.3 + New Features

Audio files don't play in QML app on iPhone

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
15 Posts 3 Posters 2.5k Views 2 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.
  • tomyT tomy

    @J.Hilk

    Thanks so much.
    I added a test.mp3 file to the project as below, just to check the work out:

    0_1555082786034_1.png

    And added the lines below to the .pro file:

    ios {
        APP_Sounds.files = $$PWD/sounds/test.mp3
    
        APP_Sounds.files = sounds
        QMAKE_BUNDLE_DATA += APP_Sounds
    }
    

    And here is the Application Output window errors, when ran by the Deskto (Clang) kit:

    QML debugging is enabled. Only use this in a safe environment. default openal device = Built-in Output device list: Built-in Output add QDeclarativeAudioSample[ "test" ] add QDeclarativeSound[ "explosion" ] SoundCone: engine not changeable after initialization. Unknown child type for AudioEngine! AudioEngine begin initialization creating default category init samples 1 creating new StaticSoundBufferOpenAL init sounds 1 AudioEngine ready. QDeclarativeAudioEngine::dtor active = 0 pool = 0 for pool QAudioEngine::dtor QAudioEnginePrivate::dtor QAudioEnginePrivate::dtor: all done

    J.HilkJ Offline
    J.HilkJ Offline
    J.Hilk
    Moderators
    wrote on last edited by
    #6

    @tomy well
    in your pro file the iostag means this is only executed if your target is the iOS platform.

    When you compile it for MacOS, which you said you tried, than you need

    macx {
    ....
    }
    

    just to make sure on the point

    $$PWD/sounds/test.mp3

    asumes, that your test.mp3 file is inside the sounds folder, and the sound folder is on the same hierarchy level as your pro file.

    otherwise the files won't be found and therefore won't be put into your app bundle


    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


    Q: What's that?
    A: It's blue light.
    Q: What does it do?
    A: It turns blue.

    tomyT 1 Reply Last reply
    1
    • J.HilkJ J.Hilk

      @tomy well
      in your pro file the iostag means this is only executed if your target is the iOS platform.

      When you compile it for MacOS, which you said you tried, than you need

      macx {
      ....
      }
      

      just to make sure on the point

      $$PWD/sounds/test.mp3

      asumes, that your test.mp3 file is inside the sounds folder, and the sound folder is on the same hierarchy level as your pro file.

      otherwise the files won't be found and therefore won't be put into your app bundle

      tomyT Offline
      tomyT Offline
      tomy
      wrote on last edited by
      #7

      @J.Hilk
      Thank you.
      Well, the sounds folder, as it's shown on the screenshot above, is on a lower hierarchy level than the .pro file.
      Shouldn't I add the audio file on the qml.qrc file (which makes the sounds folder under it)? If not, so on what file/directory of Project's menu should I add the file, please?

      J.HilkJ 1 Reply Last reply
      0
      • tomyT tomy

        @J.Hilk
        Thank you.
        Well, the sounds folder, as it's shown on the screenshot above, is on a lower hierarchy level than the .pro file.
        Shouldn't I add the audio file on the qml.qrc file (which makes the sounds folder under it)? If not, so on what file/directory of Project's menu should I add the file, please?

        J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote on last edited by
        #8

        @tomy
        the links @raven-worx posted post state that you can't use its resource system (qrc-files) for that. So you have to pack them with the app bundle itself.

        your folder should look like this:
        0_1555089283158_79d87e40-98dd-458b-afb4-4ed7d49225d5-image.png


        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


        Q: What's that?
        A: It's blue light.
        Q: What does it do?
        A: It turns blue.

        tomyT 1 Reply Last reply
        1
        • J.HilkJ J.Hilk

          @tomy
          the links @raven-worx posted post state that you can't use its resource system (qrc-files) for that. So you have to pack them with the app bundle itself.

          your folder should look like this:
          0_1555089283158_79d87e40-98dd-458b-afb4-4ed7d49225d5-image.png

          tomyT Offline
          tomyT Offline
          tomy
          wrote on last edited by tomy
          #9

          @J.Hilk
          That folder, sounds, beforehand appeared that way. But this time I removed it from the qml.qrc file. Still the error messages exist, unfortunately. The screenshot below includes all windows and results:

          0_1555100328240_Screen Shot 2019-04-12 at 1.16.25 PM.png

          J.HilkJ 1 Reply Last reply
          0
          • tomyT tomy

            @J.Hilk
            That folder, sounds, beforehand appeared that way. But this time I removed it from the qml.qrc file. Still the error messages exist, unfortunately. The screenshot below includes all windows and results:

            0_1555100328240_Screen Shot 2019-04-12 at 1.16.25 PM.png

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by J.Hilk
            #10

            @tomy
            ok, a couple of errors on my side. One should test before post actual code.

            the path in the profile should be a bit different to be relative to the executable.

            macx {
                APP_Sounds.files = $$PWD/sounds/Explosion_1.MP3 
            
                APP_Sounds.path = Contents/MacOS/sounds
            
                QMAKE_BUNDLE_DATA += APP_Sounds
            }
            

            you also need to add file:/// to tell Qt to use actual local files and not to search in the resource system.

            3rd I was unable to load a mp3 file from out of the appBundle, no matter what I tried. Maybe I'm missing something.
            So I hacked my way around it, by copying to the AppDataLocation in c++ .....

            It works, but I would encourage you to look for other/better solutions. Maybe someone else has more experience here.

            //pro
            QT += quick multimedia
            CONFIG += c++11
            
            SOURCES += \
                    main.cpp
            
            RESOURCES += qml.qrc
            
            macx {
                APP_Sounds.files = $$PWD/sounds/Explosion_1.MP3 
                APP_Sounds.path = Contents/MacOS/sounds
                QMAKE_BUNDLE_DATA += APP_Sounds
            }
            # Default rules for deployment.
            qnx: target.path = /tmp/$${TARGET}/bin
            else: unix:!android: target.path = /opt/$${TARGET}/bin
            !isEmpty(target.path): INSTALLS += target
            
            
            //main
            #include <QGuiApplication>
            #include <QQmlApplicationEngine>
            #include <QQmlContext>
            
            #include <QStandardPaths>
            #include <QFile>
            #include <QDir>
            
            int main(int argc, char *argv[])
            {
                QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
            
                QGuiApplication app(argc, argv);
            
                QQmlApplicationEngine engine;
            
                QString AppDataLocaltion = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
            
                if(!QFile::exists(AppDataLocaltion)){
                    QDir d; d.mkdir(AppDataLocaltion);
                }
            
                QFile f("/sounds/Explosion_1.mp3");
                f.copy(AppDataLocaltion + "/Explosion_1.mp3");
            
                engine.rootContext()->setContextProperty("AppDataLocaltion", AppDataLocaltion);
                engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                if (engine.rootObjects().isEmpty())
                    return -1;
            
                return app.exec();
            }
            
            //main.qml
            import QtQuick 2.12
            import QtQuick.Window 2.12
            import QtMultimedia 5.12
            
            Window {
                visible: true
                width: 640
                height: 480
                title: qsTr("Hello World")
            
                Text {
                    anchors.fill: parent
                    text: qsTr("Click me for sound")
            
                    MouseArea {
                        anchors.fill: parent
                        onClicked: playExplosion.play()
                    }
                }
            
                Audio{
                    id: playExplosion
                    source: "file://"+ AppDataLocaltion + "/Explosion_1.mp3"
                    onErrorStringChanged: console.log("errorString",errorString, source.toString())
                    onError: console.log(error)
                }
            }
            

            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            tomyT 1 Reply Last reply
            2
            • J.HilkJ J.Hilk

              @tomy
              ok, a couple of errors on my side. One should test before post actual code.

              the path in the profile should be a bit different to be relative to the executable.

              macx {
                  APP_Sounds.files = $$PWD/sounds/Explosion_1.MP3 
              
                  APP_Sounds.path = Contents/MacOS/sounds
              
                  QMAKE_BUNDLE_DATA += APP_Sounds
              }
              

              you also need to add file:/// to tell Qt to use actual local files and not to search in the resource system.

              3rd I was unable to load a mp3 file from out of the appBundle, no matter what I tried. Maybe I'm missing something.
              So I hacked my way around it, by copying to the AppDataLocation in c++ .....

              It works, but I would encourage you to look for other/better solutions. Maybe someone else has more experience here.

              //pro
              QT += quick multimedia
              CONFIG += c++11
              
              SOURCES += \
                      main.cpp
              
              RESOURCES += qml.qrc
              
              macx {
                  APP_Sounds.files = $$PWD/sounds/Explosion_1.MP3 
                  APP_Sounds.path = Contents/MacOS/sounds
                  QMAKE_BUNDLE_DATA += APP_Sounds
              }
              # Default rules for deployment.
              qnx: target.path = /tmp/$${TARGET}/bin
              else: unix:!android: target.path = /opt/$${TARGET}/bin
              !isEmpty(target.path): INSTALLS += target
              
              
              //main
              #include <QGuiApplication>
              #include <QQmlApplicationEngine>
              #include <QQmlContext>
              
              #include <QStandardPaths>
              #include <QFile>
              #include <QDir>
              
              int main(int argc, char *argv[])
              {
                  QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
              
                  QGuiApplication app(argc, argv);
              
                  QQmlApplicationEngine engine;
              
                  QString AppDataLocaltion = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
              
                  if(!QFile::exists(AppDataLocaltion)){
                      QDir d; d.mkdir(AppDataLocaltion);
                  }
              
                  QFile f("/sounds/Explosion_1.mp3");
                  f.copy(AppDataLocaltion + "/Explosion_1.mp3");
              
                  engine.rootContext()->setContextProperty("AppDataLocaltion", AppDataLocaltion);
                  engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                  if (engine.rootObjects().isEmpty())
                      return -1;
              
                  return app.exec();
              }
              
              //main.qml
              import QtQuick 2.12
              import QtQuick.Window 2.12
              import QtMultimedia 5.12
              
              Window {
                  visible: true
                  width: 640
                  height: 480
                  title: qsTr("Hello World")
              
                  Text {
                      anchors.fill: parent
                      text: qsTr("Click me for sound")
              
                      MouseArea {
                          anchors.fill: parent
                          onClicked: playExplosion.play()
                      }
                  }
              
                  Audio{
                      id: playExplosion
                      source: "file://"+ AppDataLocaltion + "/Explosion_1.mp3"
                      onErrorStringChanged: console.log("errorString",errorString, source.toString())
                      onError: console.log(error)
                  }
              }
              
              tomyT Offline
              tomyT Offline
              tomy
              wrote on last edited by tomy
              #11

              @J.Hilk

              Thanks so much. It worked.
              Didn't change the main.cpp whatsoever, but just replaced "... + AppDataLocaltion + ..." with the actual address to the file:
              "file:///Users/ ... /Explosion_1.mp3", in main.qml.
              It's simpler, now. :)

              Next, if we want to use the process on iOS, is substituting the macx { ... } in the .pro file for the following version all we need, please?

              ios {
                  APP_Sounds.files = $$PWD/sounds/Explosion_1.mp3
              
                  APP_Sounds.path = Contents/iOS/sounds
                  QMAKE_BUNDLE_DATA += APP_Sounds
              }
              
              J.HilkJ 1 Reply Last reply
              0
              • tomyT tomy

                @J.Hilk

                Thanks so much. It worked.
                Didn't change the main.cpp whatsoever, but just replaced "... + AppDataLocaltion + ..." with the actual address to the file:
                "file:///Users/ ... /Explosion_1.mp3", in main.qml.
                It's simpler, now. :)

                Next, if we want to use the process on iOS, is substituting the macx { ... } in the .pro file for the following version all we need, please?

                ios {
                    APP_Sounds.files = $$PWD/sounds/Explosion_1.mp3
                
                    APP_Sounds.path = Contents/iOS/sounds
                    QMAKE_BUNDLE_DATA += APP_Sounds
                }
                
                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by J.Hilk
                #12

                @tomy

                Didn't change the main.cpp whatsoever, but just replaced "... + AppDataLocaltion + ..." with the actual address to the file:
                "file:///Users/ ... /Explosion_1.mp3", in main.qml.
                It's simpler, now. :)

                it's simpler yes, but my point was it to make it viable for all platforms

                QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) exists for all platforms, but on some you have to create the folder first ->

                if(!QFile::exists(AppDataLocaltion)){
                        QDir d; d.mkdir(AppDataLocaltion);
                    }
                

                With a fixed local file path it will only work for your particular pc.

                Next, if we want to use the process on iOS, is substituting the macx { ... } in the .pro file for the following version all we need

                I'm actually not entirely sure.
                You may have to test the case :)


                that said, you could with the copy to appdata just place the mp3 in your qt resource system und copy them from there to local data.
                A workaround.


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                tomyT 1 Reply Last reply
                0
                • J.HilkJ J.Hilk

                  @tomy

                  Didn't change the main.cpp whatsoever, but just replaced "... + AppDataLocaltion + ..." with the actual address to the file:
                  "file:///Users/ ... /Explosion_1.mp3", in main.qml.
                  It's simpler, now. :)

                  it's simpler yes, but my point was it to make it viable for all platforms

                  QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) exists for all platforms, but on some you have to create the folder first ->

                  if(!QFile::exists(AppDataLocaltion)){
                          QDir d; d.mkdir(AppDataLocaltion);
                      }
                  

                  With a fixed local file path it will only work for your particular pc.

                  Next, if we want to use the process on iOS, is substituting the macx { ... } in the .pro file for the following version all we need

                  I'm actually not entirely sure.
                  You may have to test the case :)


                  that said, you could with the copy to appdata just place the mp3 in your qt resource system und copy them from there to local data.
                  A workaround.

                  tomyT Offline
                  tomyT Offline
                  tomy
                  wrote on last edited by tomy
                  #13

                  @J.Hilk

                  Before the prior post I tested your (for all platforms) version. It showed some errors. But if we want to make it work for Windows, Mac and Android, the method is very easy and viable.

                  For Windows and Android we use the qrc file, as you know. For Mac I use this way and it works too:

                  1- Leave both main.cpp and .pro files intact (without any changes).
                  2- Add the audio file in a folder and put it inside the project's directory.
                  3- Add the line below to main.qml:

                  Audio {
                          id: playExplosion
                          source: "file:///Users/ ... /soundTest/sounds/Explosion_1.mp3"
                      }
                  

                  Up to now, we have covered three different platforms. Then we go for iOS.
                  I made three different attempts as below:

                  1- At the first attempt, I made no changes and just changed the kit to iOS on Qt Creator and ran the project. Result: Qt Creator installed the app on the iPhone successfully. "But" when pressing the rectangle, the sound won't play!

                  2- At the second attempt I went for the .pro file and made only this change:
                  QT += quick to QT += quick multimedia. Result: Just as the prior stage.

                  3- At the third attempt, I made more changes to the .pro file, as follows:

                  • QT += quick to QT += quick multimedia.
                  • And adding this part at the end:
                  ios {
                      APP_Sounds.files = $$PWD/sounds/Explosion_1.mp3
                  
                      APP_Sounds.path = Contents/iOS/sounds
                      QMAKE_BUNDLE_DATA += APP_Sounds
                  }
                  

                  Result on iOS: two errors:
                  unsealed contents present in the bundle root
                  Xcodebuild failed.

                  Result on the Mac: Works properly.

                  Now, do you have any idea why it doesn't work on iOS, please?

                  J.HilkJ 1 Reply Last reply
                  0
                  • tomyT tomy

                    @J.Hilk

                    Before the prior post I tested your (for all platforms) version. It showed some errors. But if we want to make it work for Windows, Mac and Android, the method is very easy and viable.

                    For Windows and Android we use the qrc file, as you know. For Mac I use this way and it works too:

                    1- Leave both main.cpp and .pro files intact (without any changes).
                    2- Add the audio file in a folder and put it inside the project's directory.
                    3- Add the line below to main.qml:

                    Audio {
                            id: playExplosion
                            source: "file:///Users/ ... /soundTest/sounds/Explosion_1.mp3"
                        }
                    

                    Up to now, we have covered three different platforms. Then we go for iOS.
                    I made three different attempts as below:

                    1- At the first attempt, I made no changes and just changed the kit to iOS on Qt Creator and ran the project. Result: Qt Creator installed the app on the iPhone successfully. "But" when pressing the rectangle, the sound won't play!

                    2- At the second attempt I went for the .pro file and made only this change:
                    QT += quick to QT += quick multimedia. Result: Just as the prior stage.

                    3- At the third attempt, I made more changes to the .pro file, as follows:

                    • QT += quick to QT += quick multimedia.
                    • And adding this part at the end:
                    ios {
                        APP_Sounds.files = $$PWD/sounds/Explosion_1.mp3
                    
                        APP_Sounds.path = Contents/iOS/sounds
                        QMAKE_BUNDLE_DATA += APP_Sounds
                    }
                    

                    Result on iOS: two errors:
                    unsealed contents present in the bundle root
                    Xcodebuild failed.

                    Result on the Mac: Works properly.

                    Now, do you have any idea why it doesn't work on iOS, please?

                    J.HilkJ Offline
                    J.HilkJ Offline
                    J.Hilk
                    Moderators
                    wrote on last edited by
                    #14

                    @tomy
                    so I checked. On iOS, there is no Content .... stuff

                    In my last app I shipped the translations via app bundle:

                    iOS {
                        APP_Language.files = $$PWD/translations/myApp_de.qm \
                                                                   $$PWD/translations/myApp_en.qm
                    
                        APP_Language.path = translations
                        QMAKE_BUNDLE_DATA += APP_Languages
                    }
                    

                    I than load it directly via:

                    ...
                    QString translationPath = QCoreApplication::applicationDirPath();
                                   translationPath("/translations");
                    
                     m_translator->load("myApp_en.qm", translationPath);
                    qApp->installTranslator(m_translator);
                    

                    works fine. If I adapt this to your situation:

                    APP_Sounds.files = $$PWD/sounds/Explosion_1.MP3 
                        APP_Sounds.path = sounds
                        QMAKE_BUNDLE_DATA += APP_Sounds
                    

                    The file is shipped correctly and I can open it via QFile:

                    QString soundPath = QCoreApplication::applicationDirPath() + QString("/sounds/Explosion_1.mp3");
                    QFile f(soundPath);
                    qDebug() << f.open(QIODevice::readOnly); // returns true
                    f.close;
                    
                    QSound sound(soundPath);
                    sound.play(); // returns QSoundEffect(qaudio): Error decoding source
                    

                    I can't get it to work,
                    sry


                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                    Q: What's that?
                    A: It's blue light.
                    Q: What does it do?
                    A: It turns blue.

                    1 Reply Last reply
                    1
                    • tomyT Offline
                      tomyT Offline
                      tomy
                      wrote on last edited by
                      #15

                      @J.Hilk

                      Modifying the ios{ ... } block in the .pro file removed the prior errors.
                      I also added those lines into the code of main.cpp, and installed the project via Qt Creator on the phone, but no voice yet!
                      That is, neither sound.play(); nor onClicked: playExplosion.play() plays the audio file on the phone. :(

                      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