10 Replies Latest reply on Aug 17, 2016 3:23 AM by erikb18269666

    No audio from Media plugin using Phonegap Build on Android

    dans8649804

      I am trying to build an app that includes reliable audio playback across our target platforms, and have been directed to use the Media plugin for this task.  I was previously using the Javascript Audio native object, which seemed to work well on some Android devices, but did not work at all on others.  I have implemented the Media plugin into my project but so far have yet to have it successfully play back any audio on any of my test devices and am trying to identify what I am doing wrong. 

       

      My app should hopefully also work on a desktop browser, so I have a 'phonegap sniffer' in my javascript.  From there, we either launch the app on deviceready events on mobile devices or document.ready on desktop devices, which seems to be working well.

       

      var is_phonegap = navigator.userAgent.match( /(iPhone|iPod|iPad|Android|BlackBerry|IEMobile)/ ); // USE USERAGENT DATA TO GUESS AT WHETHER THIS IS A PHONEGAP APP OR A DESKTOP BROWSER

      // SET UP CALLERS TO THE DEVICE_READY FUNCTION: ADD EVENT LISTENER FOR PHONEGAP AND ADD DOCUMENT.READY FOR DESKTOP

      if ( is_phonegap) document.addEventListener( 'deviceready', device_ready, false );

      else $( document ).ready( device_ready );

      function device_ready() {

        console.log( 'is phonegap? ' + ( is_phonegap )? 'true' : 'false' );

        ...

      }

       

      All audio within the app is being called by a play_sound function:

       

      function play_sound( audio_file ){

        var path = 'audio/' + audio_file;

        if( is_phonegap ) var audio = new Media( path, null, media_error ); // IF THIS IS AN APP, USE THE MEDIA OBJECT PROVIDED BY THE PHONEGAP PLUGIN

        else var audio = new Audio( 'audio/' + audio_file ); // IF THIS IS ON THE DESKTOP, USE THE AUDIO OBJECT PROVIDED BY CORE JAVASCRIPT

        console.log( 'audio: ' + JSON.stringify( audio ) ); // INSPECT THE AUDIO OBJECT TO SEE WHAT IT LOOKS LIKE

        audio.play(); // PLAY THE SOUND

      }

       

      Since the Media constructor allows for an onError callback, I have set that up as well:

       

      function media_error( e ){

        console.log( 'media error: ' + JSON.stringify( e ) );// INSPECT THE ERROR TO SEE WHAT IT LOOKS LIKE

      }

       

      I am testing by running Phonegap Dev on an android device hooked up to Phonegap Desktop so I can make use of the console.log debugging messages.  When I run the app and attempt to play a sound I get the following output:

       

      is phonegap? true

      attempting to play audio file: audio/shuffle.mp3 // THIS FILE IS LOCATED IN THE PROJECT AT /WWW/AUDIO/SHUFFLE.MP3

      media error: {"code":1} // THIS IS THE OUTPUT OF THE MEDIA ERROR HANDLER

       

      I have ready several discussions about extra pathing requirements needed by the Media plugin on Android, and believe I have implemented the recommended solution (per Audio Not Working for Android Build), but this does not seem to help things.  I modified the above to:


      function play_sound( audio_file ){

        var path = platform_specific_audio_path( 'audio/' + audio_file ); // RUN PATH THROUGH PLATFORM FUNCTION

        if( is_phonegap ) var audio = new Media( path, null, media_error );

        else var audio = new Audio( 'audio/' + audio_file );

        console.log( 'audio: ' + JSON.stringify( audio ) );

        audio.play();

      }

      function platform_specific_audio_path( file ){

        if( typeof device == 'undefined' ) return file;

        return ( device.platform.toLowerCase() == "android" ) ?"/android_asset/www/" + file : file;

      }

       

      Running this version of the code outputs the following:

       

      attempting to play audio file: /android_asset/www/audio/shuffle.mp3

      media error: {"code":1}

       

      It appears that I am getting the same error result from either of these paths.  I assume this is a pathing issue but have yet to confirm this in any way.  I am just not familiar with how file paths are being built within the app.  Is there a solution for this or can anyone identify what I am doing wrong?  Thanks very much for any assistance.

        • 1. Re: No audio from Media plugin using Phonegap Build on Android
          kerrishotts Adobe Community Professional

          I am testing by running Phonegap Dev on an android device hooked up to Phonegap Desktop so I can make use of the console.log debugging messages.  When I run the app and attempt to play a sound I get the following output:

           

          You can't use the Media plugin to play audio files from your application assets in conjunction with the PG Developer/Desktop app. You'll have to build your app using the CLI (phonegap build android) or use PG Build.

          • 2. Re: No audio from Media plugin using Phonegap Build on Android
            dans8649804 Level 1

            Hi, I am not using PG Developer to build this project, and am only using PG Desktop so I can view the console output from the app as it runs on my phone. I believe that the IDE I am using for this project (JBoss with the Hybrid Mobile (Cordova) application plugin) handles CLI operations for me so I think that this plugin is installed within my project as you state it needs to be.  I understand that Phonegap Build plugins can't be used from the CLI, but it appears that I have plugin files in my project that appeared when I added the Media plugin to the project.  In my project file structure, I see the following:

             

            /plugins/cordova-plugin-media

             

            This folder appears to be full of plugin files so my presumption is that the plugin is locally installed.  My best guess is that I have the 'CLI version' of the plugin installed, and my hope is that this gets swapped out for the Phonegap Build version of the plugin when I upload the project to Phonegap Build and it gets compiled there.  In testing, I am able to confirm that the Media object exists and has properties, so my assumption is that this means that the plugin is installed and working to some extent, otherwise I would not expect a Media object to exist in my javascript.

             

            Is any of this correct?  If the plugin were not installed or working as expected, I would expect that console.log( Media ) statment would throw a ReferenceError if the plugin were not working, as Media. Also, after creating a media object, I am able to inspect that and see properties that look media-related to me:

             

            The following code:

             

            var audio = new Media( path );

            console.log( JSON.stringify( audio ) );

             

            Outputs:

             

            {"id":"3e507aa3-2ad2-7286-5e22-9afe222933f9","src":"/android_asset/www/audio/shuffle.mp3", "successCallback":null,"_duration":-1,"_position":-1}

             

            As a Media object exists and can be instantiated, my assumption is that the plugin is installed.

             

            I have not used the CLI much (maybe it is time to get up to speed), but I can launch my app from the command line with 'phonegap serve', which allows me to use the Phonegap Dev app on my phone to load the app and use it.  When I do this, I get the same results (console messages) as what I am seeing when serving the app from the Phonegap Desktop app.  So from this prespective it does not appear that serving the app from the CLI or the Phonegap Desktop app makes any difference.  From the CLI, if I run the command 'phonegap plugin list': I get the following:

             

            cordova-plugin-file 4.1.1 "File"

            cordova-plugin-media 2.2.0 "Media"

            cordova-plugin-whitelist 1.2.0 "Whitelist"

             

            Any further ideas regarding this? Am I doing something horribly wrong with these plugins?  All I want to do is reliably play a sound ... does not seem like it would be rocket science.  Thanks for any additional help.

            • 3. Re: No audio from Media plugin using Phonegap Build on Android
              kerrishotts Adobe Community Professional

              Based upon your comment, you are using the PhoneGap Developer app in your workflow. This is the root of the problem you are experiencing. Using the PG Desktop App or "phonegap serve" doesn't change anything (and it should be noted that neither of these apps actually build your app. They just serve files using a web server.)

               

              The PhoneGap Developer App is the app you launch on your mobile device to connect to either the PhoneGap Desktop App or "phonegap serve". It comes prebuilt with a selection of plugins, including the Media plugin. Hence why you can instantiate the Media class and see properties and methods. Checking for the existence of these properties and methods only serves to verify if the plugin is installed, not if the plugin will function correctly.

               

              Based upon your code and associated error messages, you are trying to play a file from the app's bundled assets. When your app is being run in the PhoneGap Developer App, however, no mechanism exists to physically push the assets being served into the PG Developer App's bundled assets. As such, the play request fails because the file can't be found.

               

              A temporary workaround to simply verify that you can, indeed, play a media file would be to change the path to something like this:

               

                  http://dev-machine-ip-address:pg-serve-port/www/shuffle.mp3

               

              However, that's not what you'll want to have long-term in production code. Instead, you need to build a version of your app that you can run directly (without using the PG Developer App or PhoneGap Serve).

               

              To do this, you can run (with your Android device attached, and assuming you've got the Android SDK installed properly):

               

                  $ phonegap run android

               

              This should build a version of your app including your media files in the bundle, and then launch it on your device. You should then be able to play media files as you are attempting now.

               

              Or, you can use PhoneGap Build's cloud service to build a version of the app:

               

                  $ phonegap remote build android

               

              You can download the resulting app onto your phone and it should work as well.

               

              Long-story-short: the PhoneGap Developer App is not a perfect representation of the environment your built apps will receive. Don't rely upon the PG Dev App to simulate the environment perfectly; at some point the only true test is to build your app and install it on a device.

               

              Hope that helps.

              • 4. Re: No audio from Media plugin using Phonegap Build on Android
                dans8649804 Level 1

                Thanks for this very detailed and helpful explanation of how Phonegap Build works and its limitations regarding plugins.  I am exploring your two suggestions of building it using the the CLI/local SDK and using Phonegap Build from the CLI with the 'remote' commands.  I have run into a problem with the CLI/local SDK build and have posted a separate question regarding this, and my attempt to use the phonegap remote build command resulted in the message "Private app limit reached".  Looking into this, it appeared that the best solution may be to delete my current project within Phonegap Build and try building it using the CLI.  This seemed to work in that I was able to successfully run "phonegap remote build android" and was then able to view a newly created app at build.phonegap.com.  Installing this on my phone results in the app loading but not proceeding past the splash screen.  My assumption is that there is a javascript error that I will need to view to debug.  I have looked into using adb to view the console.log output from the app running on the phone, and got this to work a bit ago.  Now, when I run my app and play an audio clip, I see the following:

                 

                I/chromium(23968): [INFO:CONSOLE(137)] "attempting to play audio file: audio/shuffle.mp3", source: file:///android_asset/www/js/gold-digger.js (137)

                I/chromium(23968): [INFO:CONSOLE(142)] "audio: ", source: file:///android_asset/www/js/gold-digger.js (142)

                I/chromium(23968): [INFO:CONSOLE(142)] "{"id":"8157f767-9494-ca41-60c6-be34421170ec","src":"audio/shuffle.mp3","successCallback" :null,"_duration":-1,"_position":-1}", source: file:///android_asset/www/js/gold-digger.js (142)

                I/chromium(23968): [INFO:CONSOLE(150)] "media error:", source: file:///android_asset/www/js/gold-digger.js (150)

                I/chromium(23968): [INFO:CONSOLE(151)] "{"code":1}", source: file:///android_asset/www/js/gold-digger.js (151)

                 

                The output appears to be about the same that I have been getting since trying to implement the Media plugin.  I have tried 3 different pathing approaches, the relative path as shown above, appending '/android_asset/www' prefix to the path as recommended by some, and using a reference to a file on a public web server to rule out possible pathing issues.  The 3rd of these worked properly, so it appears that the Media plugin is installed and working with an audio file from an external URL.  All I need to do is get this to work with audio files bundled in the project.

                 

                The following is now working:

                 

                var path = 'http://dev.dansteeby.com/dan/shuffle.mp3'; // A KNOWN, WORKING AUDIO FILE HOSTED ON A WEB SERVER

                var audio = new Media( path, null, media_error );

                audio.play();

                 

                The console.log outputs do not look much different other than the media error handler does not get called (I was hoping that the duration property would be set to something other than -1):

                 

                I/chromium(25882): [INFO:CONSOLE(138)] "attempting to play audio file: http://dev.dansteeby.com/dan/shuffle.mp3", source: file:///android_asset/www/js/gold-digger.js (138)

                I/chromium(25882): [INFO:CONSOLE(143)] "audio: ", source: file:///android_asset/www/js/gold-digger.js (143)

                I/chromium(25882): [INFO:CONSOLE(143)] "{"id":"5b00d955-9445-9927-6fd7-c6fd59b941f4","src":"http://dev.dansteeby.com/dan/shuffle.mp3","successCallback":null,"_duration":-1,"_position":-1}", source: file:///android_asset/www/js/gold-digger.js (143)

                 

                This leads me back to my suspicion that it is a pathing issue of some sort or something similar.  If this sounds correct, can anyone provide any insight on what I may be doing wrong regarding referencing the audio files?   The functions for this are in my original post.

                • 5. Re: No audio from Media plugin using Phonegap Build on Android
                  dans8649804 Level 1

                  I have the media plugin working now, turns out that the method described here (Audio Not Working for Android Build) is correct.  I was not getting the expected results as I had not realized that the 'device' object that was being referred to in the solution was provided by the Device plugin, and I had not added this plugin to my project.  After adding this plugin, the device inspection returned the results described in the solution and my audio began working on my Android phone.  This gitlab repo (Cordova-Examples/mp3 at master · cfjedimaster/Cordova-Examples · GitHub) has a great example of this, which is what helped me to identify the root of the issue I was having.

                   

                  Big thanks to kerrishotts for getting me this far!

                  • 6. Re: No audio from Media plugin using Phonegap Build on Android
                    erikb18269666

                    I spent 2 days on getting my mp3-files to work using the media plugin. I constantly got a 'file not found'.

                    Then I tried to insert an IMG-tag - and the image did not show up until I placed the image in the root of the app (the www-folder).

                    So I did the same with the MP3-file. And voila it worked.

                    Conclusion: there is a problem in PhoneGap Build.

                    • 7. Re: No audio from Media plugin using Phonegap Build on Android
                      kerrishotts Adobe Community Professional

                      It would be helpful to see your code. Chances are it's not a PGB problem, but an incorrect URI.

                      • 8. Re: No audio from Media plugin using Phonegap Build on Android
                        erikb18269666 Level 1

                        This is my javascript:

                         

                        function playMP3(fil) {

                            var mp3URL = getMediaURL(fil);

                          try {

                          var media = new Media(mp3URL, null, mediaError);

                          media.play();

                          }

                          catch(e)  {}

                        }

                         

                         

                        function getMediaURL(s) {

                          try  {

                          var dev=device.platform+'';

                          if(dev.toLowerCase() === "android") return "/android_asset/www/" + s;

                          return s;

                          }

                          catch(e)  {

                          // only when tested under phoneGap app

                          document.getElementById('lydstart').src=s

                          document.getElementById('lydstart').play()

                          }

                          }

                         

                         

                         

                         

                        function mediaError(e) {

                            alert('Fejl ved afspilling af lyd');

                          alert(JSON.stringify(e))

                        }

                         

                        if I store the MP3 like this www/res/test.mp3

                         

                        and does playMP3('res/test.mp3)

                         

                        it does not work. mediaError gets executed with error code=1

                         

                        Then I moved 'test.mp3' directly under the www-folder

                         

                        and does play('test.mp3')

                         

                        and then it works.

                        • 9. Re: No audio from Media plugin using Phonegap Build on Android
                          kerrishotts Adobe Community Professional

                          When you're using "www/res/test.mp3", which of these most closely matches your project structure when uploading to PGB?

                           

                          archive.zip/

                             config.xml

                             index.html

                             www/

                                 res/

                                     test.mp3

                           

                          or like this?

                           

                          archive.zip/

                             config.xml

                             index.html

                             res/

                                 test.mp3

                          • 10. Re: No audio from Media plugin using Phonegap Build on Android
                            erikb18269666 Level 1

                            This is the structure of the zip-file:

                             

                            www/

                              css/

                              img/

                              js/

                              res/

                              config.xml

                              index.html

                              start.mp3