Cordova Media won't play mp3 from www - android

I have found lots of potential resolutions to this issue on StackOverflow but nothing seems to be resolving it for me. I am trying to play an mp3 file within my Cordova (3.5) app using org.apache.cordova.media#0.2.10
var sound = new Media('audio/el/hello.mp3');
sound.play()
But it just won't play and I get the following error in LogCat
MediaPlayer error (1, -2147483648)
I have tried serving the folder locally and the following works pointing at the same file
var sound = new Media('http://10.0.2.2:9999/www/audio/el/hello.mp3');
sound.play()
Which suggests that it isn't because the file has an encoding problem.
I wasn't able to use the latest version of the media plugin because the deviceready event never fires.
Update: I've just tried unzipping the files to persistent storage and playing them from there and I get the same error.
Update: Stepping through the AudioPlayer.java source it seems that the www directory is not part of the assets because the following call throws a FileNotFoundException where f == "www/el/hello.mp3"
fd = this.handler.cordova.getActivity().getAssets().openFd(f);
However If I place the files directly in the assets folder then it works.

Path of media file incorrect. You must get path correctly:
var getPathMedia = function () {
var path = window.location.pathname;
var phoneGapPath = path.substring(0, path.lastIndexOf('/') + 1);
// Return path at www folder
return 'file://' + phoneGapPath;
};
var media = new Media(getPathMedia() + 'media/message.mp3');
media.play();

On android, you only need to have the correct path for the www folder.
Android:
var media = new Media("/android_asset/www/audio/el/hello.mp3",
successFunction,
errorFunction
);
If your app is going to run on iOS as well, you need to add the /android_asset/www/ dynamically as iOS does not need it.
iOS:
var media = new Media("audio/el/hello.mp3",
successFunction,
errorFunction
);

I finally figured this out for myself, but I figured I'd share.
What I needed to do is not get the location, but the current url to the page I was on. From that I could construct a url to the asset I wanted to play.
var path = window.location.href;
var phoneGapPath = path.substring(0, path.lastIndexOf('/') + 1);
var media = new Media(phoneGapPath + 'media/message.mp3');
media.play();
hope this helps

I am using this plugin with ionic capacitor. I had to use a different filepath, when playing audiofiles that are located in assets folder. Additionally I had to call the release function after the
onSuccess-event fired. When I called it after file.play(), the playback didn't work.
var audioPath = "/android_asset/public/assets/" + "audio.mp3"
const file: MediaObject = this.media.create(audioPath)
file.onSuccess.subscribe(() => {
console.log('Action is successful')
file.release()
});
file.play();
If the audio file is not found, make sure to check that it is copied to the android project assets folder. If it is not there run "npx cap sync" and "npx cap copy".

Related

Sound plays in PhoneGap when testing with phonegap app, but not when built with PhoneGap Build

I am working on my first android app where you hit a button and it plays a .wav sound, it works great when I run the phonegap server app to test it but then when I package it as an .APK with phonegap build and install it on my phone, it does not play the .wav sounds.
$('.sound1').on('touchstart', function () {
var thissound = new Audio();
thissound.src = $(this).attr('key');
thissound.play();
});
The changes I made were instead of new audio(); I did new Media(); and after reading Playing Local Sound In Phonegap I found out it may have had something to do with the path needing to be an absolute local path, it works in the real packaged app now. I also discovered you need too use media.release(); because of the finite number of times you can play a sound.
$('.sound1').on('touchstart', function () {
var path = window.location.pathname;
path = path.substr( path, path.length - 10 );
var finalpath = 'file://' + path;
var key = $(this).attr('key');
var thissound = new Media( finalpath + key, function onSuccess() {
// release the media resource once finished playing
thissound.release();
} );
thissound.play();
});

Phonegap app playing mp3 using Media plugin does not work

I've developed file reader in phonegap with following path:
var defaultPath = 'file:///storage/sdcard0/';
So i'm able to list all file on sdcard and select one folder with audio files to load. So my list of audio files looks like:
i[1] = 'file:///storage/sdcard0/Download/audio/file.mp3';
i[2] = 'file:///storage/sdcard0/Download/audio/file1.mp3';
Then I try to init song using Media plugin ( installed ) with following piece of code:
var media = new Media(i[1]);
media.play();
But audio does not play or do nothing. But when I'm trying to test it using PhoneGap APP all works fine this just isn't work when I make build and try to test app from build.
I found the issue by myself.
Android does not let read files on local storage or on sdcard via path starting from root /storage/sdcard0 /storage/sdcard1. So when we would like to access local storage or sdcard we must access it via file:///mnt/sdcard/ for sdcard and file:///mnt/storage/sdcard1/ for phone storage.
Small example how to read entries from sdcard or phone storage:
var path = 'file:///mnt/storage/sdcard1/';
window.resolveLocalFileSystemURL(path, function(entry){
var reader = entry.createReader();
reader.readEntries(showEntries);
});
function showEntries(entries){
var entries = [];
for(var i =0; i < entries.length; i++){
var entry = entries[i];
var data = {
name: entry.name,
path: entry.fullPath,
};
entries[i] = data;
}
console.log(JSON.stringify(entries));
}
Hope that this will help with same issue as I had because this is not documented in phonegap.

MediaPlayer: Error (1,-2147483648) in Cordova 6.1.1 with Phaser 2.4.6

I am trying to play audio files on an Android game built with Cordova 6.1.1 and Phaser.io 2.4.6. The media will not play on Android versions less than API 21 or so, and gives the error
04-21 21:48:57.546 9659-9671/com.jtronlabs.birdu E/MediaPlayer: error (1, -2147483648)
04-21 21:48:57.546 9659-9672/com.jtronlabs.birdu E/MediaPlayer: Error (1,-2147483648)
I have read some SO answers, and nothing has helped. I load in audio using Phaser's Loader class:
this.load.audio('background-music', this.arrayOfCompatibleMusicFileNames('the_plucked_bird') );
...
//Phaser has support to load in multiple types of audio formats if the first supplied in the array is not compatible with the browser.
arrayOfCompatibleMusicFileNames: function(key){
//old versions of android don't play music, they require an absolute pathname (instead of relative). This is a generic solution
//https://stackoverflow.com/questions/4438822/playing-local-sound-in-phonegap?lq=1
var path = window.location.pathname;
path = path.substr( 0, path.lastIndexOf("/")+1 ); //need to remove 'index.html' from the end of pathname
var aud = path+'assets/audio/';
//aud = '/android_res/raw/'
var wav = aud + 'wav/';
var ogg = aud + 'ogg/';
var mp3 = aud + 'mp3/';
console.log(mp3+key+".mp3");
return [mp3+key+".mp3",ogg+key+".ogg",wav+key+".wav"];
},
This works in the browser, and on newer versions of Android. On older versions I have attempted to add multiple formats, the absolute path, external write permissions to $PROJECT_ROOT/platforms/android/AndroidManifest.xml, and moving the files from /www to $PROJECT_ROOT/platforms/android/res/raw.
All for naught. Any ideas on what could be going wrong?
Edit: When the audio files are in the 'res' folder, I reference them as such:
arrayOfCompatibleMusicFileNames: function(key){
return ['/android_res/raw/'+key+".ogg"];
}
Which works on API 21 but not 19 or below (just like the first function).
I have gotten the Audio working by using the cordova-plugin-media.
var path = window.location.pathname;
path = path.substr( 0, path.lastIndexOf("/")+1 ); //need to remove 'index.html' from the end of pathname
var aud = path+'assets/audio/';
var ogg = aud + 'ogg/' + key + ".ogg";
//works!
var snd = new Media(ogg);
snd.play();
However, I discovered the 'normal' way of doing this is what causes the bad behaviour.
//does not work... Phaser uses this internally
var snd = new Audio(ogg);
snd.play();
It seems I will have to write code to test if it is browser or cordova, and use 'Media' or 'Audio' respectively.
Update: I wrote that code and it makes things messy, but works. Nowadays I use Crosswalk, and WebAudio works on all devices. No need for the media plugin and extra case-checking in my code.

Audio will not play on Android using phonegap, but works fine on iOS

It works fine on iOS.
I have looked many answers including these 2:
Play sound on Phonegap app for Android
HTML5 audio not playing in PhoneGap App (Possible to use Media?)
I have tried all of the solutions:
Changing the path to /android_asset/www/ for Android
Using .ogg files
Pre load the audio with a play() / pause().
Using the Media plugin provided by Cordova/Phonegap
Here is my current code:
if(device.platform === "Android") //DIFFERENT PATH FOR ANDROID
{
url = "/android_asset/www/sound.ogg";
}else{
url = "sound.mp3";
}
alert(url);
sound = new Media(url);
sound.play();
Anyone have an ideas?? It feels like I have been going round in circles
I had similar and this solution worked for me
Get complete path of your application using window.location.pathname, this way you dont need to worry about device type, it will give you the complete path including index.html and by using the below function simply strip off index.html from the string and append your media file.
function getPhoneGapPath() {
var path = window.location.pathname;
path = path.substr( path, path.length - 10 ); //strip off index.html
return 'file://' + path;
};
And then
url = getPhoneGapPath()+'sound.ogg'; //OR MP3
alert(url);
sound = new Media(url);
sound.play();
Hope this helps
I finally managed to get it working!!
I first initialising the audio file by finding the full Android path using #Sarim Sidd help above and then preloading the audio file:
//INITIALISE SOUND
if(device.platform === "Android") //DIFFERENT PATH FOR ANDROID
{
//navigator.notification.beep(1);
var path = window.location.pathname;
path = path.substr( path, path.length - 10 ); //strip off index.html
url = 'file://'+path+"sound.ogg";
}else{
url = "sound.mp3";
}
//sound = new Media(url);
sound = new Media(url);
sound.play();
sound.pause();
Then when to play the audio I forced the volume to full (1.0) before calling the play method. For some reason I noticed the audio kept reseting to mute each time I started the app:
//PLAY BELL SOUND THROUGH APP
sound.setVolume(1.0);
sound.play();

Cordova 3.4 Android Local Video files not playing

I have tried for days now to play a local video file on my galaxy tab 4.2 through a cordova 3.4 app.
When i use an absolute http url the video plays just fine.
Here is what i have tried:
I put the video file in the assets/res/raw folder as suggested here: Loading video failed on html5 phonegap
RESULT: After i click on play -> spinning loading icon no video
Video in the www folder:
Result: Same as #1
<video id="myvideo" controls="controls" width="400">
<source src="file:///android_asset/www/gruppenruf.mp4" />
</video>
Result: Same as #1
I set all the permissions of the folders to 777
Then i tried with the https://github.com/jaeger25/Html5Video plugin
After installing the plugin all i get is:
03-06 18:27:06.953: E/Web Console(22530): Uncaught TypeError: Cannot read property 'html5Video' of undefined:37
All i am trying to do is play a local video file on android. Is this really that complicated?
any help would be appreciated.
Take a look at this post.
The File plugin (at least <=v1.3.1) has a bug for android devices. Also, I am not sure if jaeger25/Html5Video plugin is still working with cordova 3.6.x.
A working approach is to programmatically copy your video files from www/gruppenruf.mp4 to a place accessible for playback by the app during runtime. You may use file:///data/data/com.example.MyPackage/files/gruppenruf.mp4 for that. The FileTransfer cordova plugin will take care of this.
var myFilename = "gruppenruf.mp4";
var myUrl = cordova.file.applicationDirectory + "www/" + myFilename;
var fileTransfer = new FileTransfer();
var filePath = cordova.file.dataDirectory + myFilename;
fileTransfer.download(encodeURI(myUrl), filePath, (function(entry) {
/*
res = "download complete:\n"
res += "fullPath: " + entry.fullPath + "\n"
res += "localURL: " + entry.localURL + "\n"
alert(res += "nativeURL: " + entry.nativeURL + "\n")
*/
var vid = document.getElementById("myvideo");
vid.src = entry.nativeURL;
//vid.loop = true;
}), (function(error) {
alert("Video download error: source " + error.source);
alert("Video download error: target " + error.target);
}), true, {
headers: {
Authorization: "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
}
});
If it does not play you may want to link a click event listener to it or start the video with vid.play();.
If the mentioned options are not working try:
src="android.resource://com.example.hello/raw/Videofile" (leave the extension ".mp4" what so ever)
place your video files in "..\platforms\android\res\raw"
note that you don't use the extension of the video file in the src.
I've struggled a lot with this issue, but this worked for me =]
As I spend some time with a similar issue, I feel its worth sharing:
If you want to display video fullscreen: dont use html tag as there is a media plugin for that. If you dont need to play offline: the video src pointing to a web server will work just fine.
If you need to play offline and the video is part of your app package, have a look to https://github.com/jaeger25/Html5Video (it help to automatically copy the video files in a public location)
If you need to play offline videos dynamically downloaded: (my case)
Use fileTransfer plugin
Save file in cordova.file.externalDataDirectory as its public
In some case you may need to force the file to be public
you can do that by adding 'file.setReadable(true, false);' to FileTransfer.java line 820
Cheers
Your code stopped working in Cordova 3.4.0 because they changed the file path structure. Instead of 'file:///' you have to use 'cdvfile://'.
Remember to update the File Plugin as well.

Categories

Resources