I have created a sound app for Android using Cordova. Everything was perfect, at least in the Android Studio's emulator, until I found something strange happening while testing on a real device.
My app contains more than 100 sounds one second each. You click to play sounds till you get 32 clicks that play audios without problems. But starting from thirty-third (33rd) click I get a message error:
code: -19 message: undefined
I must mention that you can reply the previous clicked sounds that still work. But other sounds get the error above.
If I close and reopen the app, sounds that gave error work again until I get to 33rd click and start getting the error message even for sounds that used to work.
Here is the code I use to play my sounds:
// Wait for device API libraries to load
//
document.addEventListener("deviceready", onDeviceReady, false);
// device APIs are available
//
function onDeviceReady() {
var my_media = new playAudio();
}
// Audio player
//
var my_media = null;
var mediaTimer = null;
// Play audio
//
my_media = {}; // init the play object
function playAudio(src, id) {
if (!my_media[id]) { // check if media already created
my_media[id] = new Media(src, onSuccess, onError);
}
my_media[id].play();
}
//playAudio('file:///android_asset/www/media/1.mp3');
// Pause audio
//
function pauseAudio() {
if (my_media) {
my_media.pause();
}
}
// Stop audio
//
function stopAudio() {
if (my_media) {
my_media.stop();
}
clearInterval(mediaTimer);
mediaTimer = null;
}
// onSuccess Callback
//
function onSuccess() {
console.log("playAudio():Audio Success");
}
// onError Callback
//
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
// Set audio position
//
function setAudioPosition(position) {
document.getElementById('audio_position').innerHTML = position;
}
Any IDEA?
thanks
Related
So, i have made an app with phonegap build, where the goal is to read a xml file that contains info about audio tracks, and includes the path for each audio track.
I proceed to input the data of xml file into html, and before it was working fine. After i imported my project into phonegap build, no more audio plays. The controls work, but the audio doesn't play.
Here is the code:
<script>
document.addEventListener('play', function(e){
var audios = document.getElementsByTagName('audio');
for(var i = 0, len = audios.length; i < len;i++){
if(audios[i] != e.target){
audios[i].pause();
}
}
}, true);
xmlhttp=new XMLHttpRequest();
xmlhttp.open("GET","teste.xml",false);
xmlhttp.send();
xmlDoc=xmlhttp.responseXML;
document.write("<table><tr><th>Track</th><th>Description</th<th>URL</th></tr>");
var x=xmlDoc.getElementsByTagName("CD");
for (i=0;i<x.length;i++){
document.write("<tr><td>");
document.write(x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue);
document.write("</td><td>");
document.write(x[i].getElementsByTagName("DESCRIPTION")[0].childNodes[0].nodeValue);
document.write("</td><td>");
var audio = x[i].getElementsByTagName("URL")[0].childNodes[0].nodeValue;
document.write('<audio controls><source src="'+audio +'" type="audio/mpeg"></audio>');
document.write("</td></tr>");
}
document.write("</table>");
</script>
The XML file is simply structured like this:
<CD>
<TITLE>Track one</TITLE>
<DESCRIPTION>Bob Dylan</DESCRIPTION>
<URL>files/test.mp3</URL>
</CD>
I have read some similar questions and find that most mistakes are in the PATH of the audio file. What should i do for the audio to play?
Thanks
EDIT: I have updated my code:
var path = '/android_asset/www/';
var audio = x[i].getElementsByTagName("URL")[0].childNodes[0].nodeValue;
var audioPath = path+audio;
alert(audioPath);
document.write('PLAY<br/>');
document.write('PAUSE<br/>');
document.write('STOP');
document.write('<p id="audio_position"></p>');
The alert(audioPath) returns the correct path and it works when I use this function:
function onDeviceReady() {
playAudio('/android_asset/www/files/test1.mp3');
}
The audioPath is the same as the path above.
But the app doesn't play the sound when i press Play...
Any ideas?
playAudio function:
function playAudio(src) {
// Create Media object from src
my_media = new Media(src, onSuccess, onError);
// Play audio
my_media.play();
// Update my_media position every second
if (mediaTimer == null) {
mediaTimer = setInterval(function() {
// get my_media position
my_media.getCurrentPosition(
// success callback
function(position) {
if (position > -1) {
setAudioPosition((position) + " sec");
}
},
// error callback
function(e) {
console.log("Error getting pos=" + e);
setAudioPosition("Error: " + e);
}
);
}, 1000);
}
}
FOUND my problem! It was the 'onclick'. I now import jQuery and built the following code:
$(".btPlay").on("click",function (e) {
// body...
console.log("Play");
playAudio(audioPath);
});
It now works!
Try to install the cordova Media plugin org.apache.cordova.media (http://docs.phonegap.com/en/edge/cordova_media_media.md.html)
And then, try this :
//src is your path to your file
var my_media = new Media(src, function(){
alert("Success");
}, function(){
alert("Fail");
});
my_media.play();
Try it with all the paths yuo already tried, but this plugin works for me with online files.
EDIT: You may need to add '/android_asset/www/' in front of your src
Hi I am developing one app in phonegap older version and now I have added RevMob ads to my app after that Media is not defined error is throwing in Logcat.
I have tried to add media plugin using this command in cli cordova plugin add org.apache.cordova.media then current working project directory is not cordova based project error getting in command prompt.
Other than Media plugin for sound is there anything to play sound in phonegap?
Media Code :
var my_media = null;
var mediaTimer = null;
// Play audio
//
function playAudio22(src) {
// Create Media object from src
my_media = new Media(src, onSuccess22, onError22);
// Play audio
my_media.play();
// Update my_media position every second
/* if (mediaTimer == null) {
mediaTimer = setInterval(function() {
// get my_media position
my_media.getCurrentPosition(
// success callback
function(position) {
if (position > -1) {
setAudioPosition((position) + " sec");
}
},
// error callback
function(e) {
console.log("Error getting pos=" + e);
setAudioPosition("Error: " + e);
}
);
}, 1000);
}*/
}
// Pause audio
//
function pauseAudio() {
if (my_media) {
my_media.pause();
}
}
// Stop audio
//
function stopAudio() {
if (my_media) {
my_media.stop();
}
clearInterval(mediaTimer);
mediaTimer = null;
}
// onSuccess Callback
//
function onSuccess22() {
console.log("playAudio():Audio Success");
}
// onError Callback
//
function onError22(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
// Set audio position
//
function setAudioPosition(position) {
document.getElementById('audio_position').innerHTML = position;
}
When clicked
$('#playId_1').bind('touchstart', function(e) {
playAudio22('/android_asset/www/MenuBtnclicksound.mp3');
revmob.showFullscreen(onSuccess, onError);
e.stopImmediatePropagation();
});
Logcat error
11-19 12:42:11.805: E/Web Console(9770): Uncaught ReferenceError: Media is not defined at file:///android_asset/www/js/sounds.js:8
Config.xml
<feature name="Media" >
<param
name="android-package"
value="org.apache.cordova.AudioHandler" />
</feature>
ANd also I tried to create cordova project with higher version 3.6+ in eclipse its not taking any modification also, whenever I change index.html file under www directory its not affecting in device.
I am running project in eclipse.
im trying to record an audio file using Media object in phonegap and then play it. i have no problem recording, but then when i try to play it my app shuts down, both on my emulator and my device. on the logcat it says: "null pointer exception at org.apache.cordova.readyPlayer (AudioPlayer.java)". many thanks to anyone who is willing to help me, it took me a while to realize im completely lost here.
here is the code which i copied from http://docs.phonegap.com/en/2.4.0/cordova_media_media.md.html#media.stopRecord and added .play() after the .stopRecord(). i can add the manifest and activity if needed, i doubt that the problem is there but i could be wrong.
index.html:
<script type="text/javascript" charset="utf-8" src="cordova-2.4.0.js"></script>
<script type="text/javascript" charset="utf-8">
// Wait for Cordova to load
//
document.addEventListener("deviceready", onDeviceReady, false);
// Record audio
//
function recordAudio() {
var src = "myrecording.amr";
var mediaRec = new Media(src, onSuccess, onError);
// Record audio
mediaRec.startRecord();
// Stop recording after 10 sec
var recTime = 0;
var recInterval = setInterval(function() {
recTime = recTime + 1;
setAudioPosition(recTime + " sec");
if (recTime >= 10) {
clearInterval(recInterval);
mediaRec.stopRecord();
document.getElementById('audio_position').innerHTML = "finished";
**mediaRec.play();**
}
}, 1000);
}
// Cordova is ready
//
function onDeviceReady() {
recordAudio();
}
// onSuccess Callback
//
function onSuccess() {
console.log("recordAudio():Audio Success");
}
// onError Callback
//
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
// Set audio position
//
function setAudioPosition(position) {
document.getElementById('audio_position').innerHTML = position;
}
</script>
<p id="media">Recording audio...</p>
<p id="audio_position"></p>
yuval
I found the same issue with Cordova 3.5 (with Media plugin 0.2.11) and Android 4.4. The solution is as described above. Basically something like this should do the trick:
mediaRec.stopRecord();
src = mediaRec.src; // if you don't have src defined anymore
mediaRec.release();
mediaPlay = new Media(src, onSuccess, onError);
mediaPlay.play();
There is no need to create an other Media object to play the previously recorded file. Just do the following - you have to release the media object after recording is stopped:
// variable in global scope
var mediaRec = 0;
// function to record an audio
function recordAudio() {
// create media object for your recording
mediaRec = new Media("phonegap_rec.amr", onMediaRecordSuccess, onMediaRecordError);
// start recording
mediaRec.startRecord();
// recording for 5 seconds
var recTime = 0;
var recInterval = setInterval(function() {
recTime = recTime + 1;
if (recTime >= 5) {
clearInterval(recInterval);
// stop recording after 5 seconds
mediaRec.stopRecord();
// release the media object (THIS IS THE KEY SOLUTION HERE)
mediaRec.release();
}
}, 1000);
}
// function to playback recorded audio
function playRecord() {
// check if the object exists
if (mediaRec) {
// now you can playback the recording
mediaRec.play();
}
}
I need to play the "correct" sound if user answer the question correctly and "wrong" if incorrect. The sound is playing at first but after at the fifth time I answer correctly which output the fourth time "correct" sound already the fifth time, no sound can be heard. It seems the music can only played at most 4th times.
What is the possible reason that cause this?
updated*
I added media.release in my stopAudio() but so far the sound can be heard for 6th (improved) but it is still not suits my case. (Many questions that need the same sound effect)
Js.file
// Audio player
var my_media = null;
var mediaTimer = null;
// Play audio
function playAudio(src) {
// Create Media object from src
my_media = new Media(src, null, soundCB);
my_media.play();
}
function soundCB(err){
console.log("playAudio():Audio Error: "+err);
}
// Stop audio
//
function stopAudio() {
if (my_media) {
alert("AQA");
my_media.stop();
my_media.release();
}
clearInterval(mediaTimer);
mediaTimer = null;
}
/////question part//////
$("#answer").live('tap', function(event){
if(buttonAns==true) {
$this= $(this);
buttonAns = false;
var choice = $this.attr("class");
if((correctAnsNo == 0 && choice =="answer0")||(correctAnsNo == 1 && choice =="answer1")||(correctAnsNo == 2 && choice =="answer2")){
playAudio('/android_asset/www/audio/fall.mp3'); //falling sound
correct = parseInt(correct)+2;
playAudio('/android_asset/www/audio/correct.mp3'); //dingdong
}else{
playAudio('/android_asset/www/audio/wrong1.wav');
}
if(quesNo < wordsNo ){
setTimeout(function() {
buttonAns = true;
db.transaction(queryQuesDB, errorCB);
},1800);
}else{
endLevel();
}
} else {
event.preventDefault();
}
});
Android has a finite amount of resources in order to play sounds. You keep creating a new Media object each time you want to play a file. You need to release the sounds you are not using. If you need to play those sounds multiple times each then consider creating separate media objects to hold a reference to those sounds.
Read up on media.release.
I had the same problem.
The solution I did.:
if(media){
media.stop();
media.release();
}
media = new Media(...);
Here's my trick: I released it upon it finished playing or an error occurred.
function playAudio(url) {
try {
var my_media = new Media(url,
// success callback
function () {
**my_media.release();**
},
// error callback
function (err) {
**my_media.release();**
});
// Play audio
my_media.play();
} catch (e) {
alert(e.message);
}
}
first time when i play a mp3 file using phonegap media it works fine. but wen i stop and again play for 2nd time it does not and 3rd time when i play it shows error code 0
below is code
var my_media = null;
var mediaTimer = null;
var pausePos = 0;
var counter=0;
var playing=false;
function playAudio(src) {
// Create Media object from src
if(my_media==null){
my_media = new Media(src, onSuccess, onError);
}
if(!playing){
// get audio duration
var duration = my_media.getDuration();
// set slider data
if( duration > 0 ){
$('#slider').attr( 'max', Math.round(duration) );
$('#slider').slider('refresh');
}
// Play audio
my_media.play();
playing=true;
$("#play_pause_img").attr("src","img/pause.png")
// Update my_media position every second
if (mediaTimer == null) {
mediaTimer = setInterval(function() {
// get my_media position
my_media.getCurrentPosition(
// success callback
function(position) {
if (position > -1) {
setAudioPosition(position);
}
},
// error callback
function(e) {
console.log("Error getting pos=" + e);
setAudioPosition("Error: " + e);
}
);
}, 1000);
}
}
else{
pauseAudio();
playing=false;
$("#play_pause_img").attr("src","img/play.png");
}
}
function pauseAudio() {
if (my_media) {
my_media.pause();
}
}
function resumeAudio()
{
my_media.play();
}
function stopAudio() {
if (my_media) {
my_media.stop();
my_media.release();
playing=false;
$("#play_pause_img").attr("src","img/play.png");
}
clearInterval(mediaTimer);
mediaTimer = null;
pausePos = 0;
$('#slider').val(pausePos);
$('#slider').slider('refresh');
}
function onSuccess() {
console.log("playAudio():Audio Success");
}
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
what could be the reason and what is error code 0.
In 3.5.0 I'm experiencing the error function firing with an error code of 0.
From older docs, 0 appears to mean none, and appears to be no indication of a problem.
I seems under these circumstances this can be ignored, and is not really an error
it has to do with audio-ressources which are finite and therefore must get released. This is explained there: http://docs.phonegap.com/en/3.3.0/cordova_media_media.md.html
In my case it did the trick to call release() for my media object at that moment I don't use it anymore - I do it directly after calling stop()
this.stopAudio = function() {
if (my_media) {
my_media.stop();
my_media.release();
}
}
I have the same problem. I'm searching for the solution, but I didn't find anything.
My code:
$('#button').click(function{
media = new Media('/android_asset/www/sonidos/trans/sound.m4a', play, error);
});
function play(){
media.play();
}
function error(err){
alert(err.code);
}
If i do in that way, the sound does not play and I get always the alert with 0. That not match with any error code from mediaError.
Testing and testing I make code works with next code:
$('#button').click(function{
media = new Media('/android_asset/www/sonidos/trans/sound.m4a', play, error);
media.play();
});
function play(){
;
}
function error(err){
;
}
I know is not the correct way but I can't find other solution.
P.D. Sorry for my bad English.
Add the release method in the onSuccess method in addition to the stop method you created.
function onSuccess() {
my_media.release();
console.log("playAudio():Audio Success");
}