Quasar app using cordova-plugin-media to play sound files => error "code 1"
-
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 withstatics/
, 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 asMediaError.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 thehttp
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. IntogglePlayback
, I grabbed that element’ssrc
attribute value in the js and used that as the URL. It did pick up thesrc
attribute, which wasn’t changed from when I’d hardcoded it, and still code 1.I prefixed that
<audio>
tag’ssrc
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.
-
@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?
-
Got it working!
I unzipped the apk file and see that my mp3 is located inassets/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:
Actually, only after a build the files in
src/statics
are copied tosrc-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 tosrc-cordova/www/statics
-
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.
I think this webpack loader plugin would base64 encode your audio file and add the audio mime type as in the jsfiddle example
See https://quasar.dev/quasar-cli/handling-webpack for details on how to add webpack plugins to Quasar.