No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    Quasar app using cordova-plugin-media to play sound files => error "code 1"

    Help
    3
    4
    1436
    Loading More Posts
    • 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.
    • J
      jakemiles last edited by jakemiles

      Hello. I’m looking for a solution to using cordova-plugin-media with quasar, playing an audio file packaged with the cordova app, running on android. It works fine in a straight cordova app, just not as a quasar app. It also works fine if instead of a path beginning with statics/, the URL I provide is to the same path via a local http server address.

      Does anyone have a working example of playing a sound file on android using this plugin in a quasar app?

      More detail:

      I’ve added the cordova-plugin-media plugin, put my media file in <project root>/src/statics/audio/songs/BlueJayCall.mp3. This is my single-file vue component, index.vue:

      <template>
        <q-page class="flex flex-center">
          <img alt="Blue Jay" src="statics/image/birds/BlueJay.png" v-on:click="togglePlayback"/>
        </q-page>
      </template>
      
      <style>
      </style>
      
      <script>
      export default {
        name: 'player',
        data () {
          return {
            playing: false
          }
        },
        methods: {
          togglePlayback () {
      
            let newState = !this.$data.playing
            console.log(`Changing playing status to ${newState}`)
      
            if (newState) {
      
              let url = 'statics/audio/songs/BlueJayCall.mp3'
              console.log(`url:  ${url}`)
      
              // eslint-disable-next-line no-undef
              this.media = new Media(url,
                                     () => {
                                       console.log('media finished')
                                     },
                                     (e) => {
                                       console.error('Media produced an error: ' + JSON.stringify(e))
                                     },
                                     (status) => {
                                       console.log(`media status changed to ${status}`)
                                     })
              this.media.play()
            } else {
              this.media.pause()
            }
      
            this.$data.playing = newState
          }
        }
      }
      </script>
      

      The image shows up fine. When I tap the image, it tries to play the mp3 and produces this rather opaque error information (using adb logcat | grep CONSOLE):

      06-04 21:08:11.915  1558  1558 I chromium: [INFO:CONSOLE(12)] "Changing playing status to true", source: webpack-internal:///./node_modules/babel-loader/lib/index.js??ref--1-0!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/pages/index.vue?vue&type=script&lang=js (12)
      06-04 21:08:11.916  1558  1558 I chromium: [INFO:CONSOLE(16)] "url:  statics/audio/songs/BlueJayCall.mp3", source: webpack-internal:///./node_modules/babel-loader/lib/index.js??ref--1-0!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/pages/index.vue?vue&type=script&lang=js (16)
      06-04 21:08:11.936  1558  1558 I chromium: [INFO:CONSOLE(20)] "Media produced an error: {"code":1}", source: webpack-internal:///./node_modules/babel-loader/lib/index.js??ref--1-0!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/pages/index.vue?vue&type=script&lang=js (20)
      

      So Media provides {"code": 1} in response, and no further information. Their docs only define code 1 as MediaError.MEDIA_ERR_ABORTED = 1 (https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-media/#mediaerror)

      However, since it plays the mp3 just fine if I use a URL on a local web server, my guess is that code 1 either means the file doesn’t exist at the path specified, or there is some setting preventing it from playing a local file.

      If I change the path to /android_asset/www/statics/audio/songs/BlueJayCall.mp3 per the many responses on the internet about this problem, for example
      https://stackoverflow.com/questions/46816599/cordova-plugin-media-not-playing-from-local-uri,
      it produces the same error (prints the new path correctly, then code 1).

      Per that link, I also changed the android section of config.xml to:

          <platform name="android">
              <allow-intent href="market:*" />
              <config-file parent="/*" target="AndroidManifest.xml">
                  <uses-permission android:name="android.permission.INTERNET" />
                  <uses-permission android:name="android.permission.WAKE_LOCK" />
              </config-file>
          </platform>
      

      I restarted quasar dev -m cordova -T android, tapped the image, still get code 1. Also, I don’t need these permissions set to play it via the http URL, so I suspect that’s a red herring.

      Per this very clever user’s idea, https://stackoverflow.com/questions/46816599/cordova-plugin-media-not-playing-from-local-uri, I tried adding this to the template:

              <audio id="blueJay" src="statics/audio/songs/BlueJayCall.mp3" type="audio/mpeg"></audio>
      

      thinking that perhaps quasar would turn it into the correct path. Its documentation mentions a magic algorithm that ensures that statics/ always works out. In togglePlayback, I grabbed that element’s src attribute value in the js and used that as the URL. It did pick up the src attribute, which wasn’t changed from when I’d hardcoded it, and still code 1.

      I prefixed that <audio> tag’s src attribute with /android_asset/www/. Still code 1.

      Has anyone done this successfully? Does anyone know what I’m doing wrong? What is the magic missing piece? I was able to get this working as a plain cordova app (had to prefix the url with /android_asset/www for that version to work, so I imagine that’s true here too, but it doesn’t solve the issue). It’s only when using quasar and including the audio file packaged with the cordova app that it doesn’t work.

      Thanks for any help.

      gvorster 1 Reply Last reply Reply Quote 1
      • gvorster
        gvorster @jakemiles last edited by

        @jakemiles said in [Quasar app using cordova-plugin-media to play sound

        I saw this in the docs

        You can force serving static assets by binding src to a value with Vue. Instead of src="statics/path/to/image" use :src=" 'statics/path/to/image' " or :src="imageSrc". Please note the usage of single quotes within double quotes on the second code example (spaces have been added to see this visually on the documentation website - normally you would not have the spaces).
        

        I tried this example and it works both in dev and prod (cordova/android).

        <audio controls>
              <source :src="'statics/sounds/click.mp3'" type="audio/mpeg"/>
        </audio>
        

        But I want to use sound files in the statics folder with the cordova-media-plugin.

        So, the mp3 file is there and it plays via the html audio tag. What url to use in the media plugin?

        gvorster 1 Reply Last reply Reply Quote 0
        • gvorster
          gvorster @gvorster last edited by gvorster

          Got it working!
          I unzipped the apk file and see that my mp3 is located in

          assets/www/statics/sounds/click.mp3

          I used this code to get the url to this file:

            window.resolveLocalFileSystemURL(
              cordova.file.applicationDirectory + "www/statics/sounds/click.mp3",
              fileEntry => {
                console.log("file", fileEntry);
          
                let o = new Media(fileEntry.nativeURL,
                  () => console.log("yes!"),
                  err => console.log(err)
                );
                o.play();
              },
              err => console.log("err", err)
            );
          

          FileEntry in console.log:

          Selection_003.png

          Actually, only after a build the files in src/statics are copied to src-cordova/www/statics and that is where the cordova media plugin is looking in when given a URL. Because in dev some sound files were not playing until I either did a build or copied the files to src-cordova/www/statics

          1 Reply Last reply Reply Quote 0
          • T
            tohagan last edited by tohagan

            Another option might be to embed the sounds as base64 encoded data URI’s. This solution may not be what you need for large audio files or many audio file but ok for short audio like click / alarm sounds.

            • See https://jsfiddle.net/zw7qnrgm/53/

            I think this webpack loader plugin would base64 encode your audio file and add the audio mime type as in the jsfiddle example

            • https://webpack.js.org/loaders/url-loader/

            See https://quasar.dev/quasar-cli/handling-webpack for details on how to add webpack plugins to Quasar.

            1 Reply Last reply Reply Quote 0
            • First post
              Last post