- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am trying to use Cordova Media plugin (1.0.1 version) to play a sound sprite.
I am using Intel XDK which includes an emulator. For debugging, the device I am using is a Sony Xperia Z3 with Android 5.1.1.
The code works well when I want to play the sound from one point to another which is far from the end of the audio file (its duration). Lets say the file duration is 13000 ms: there is no problem when I play from 0 to 12000 or even 12500, etc. but there are problems when I want to play until 12700, 12800 or 13000, for example.
When I try to play a sound until a place near its real duration, it works well in the emulator but it does not work well in the real device (Sony Xperia Z3 phone). In the real device, the first loop (the play method which is called inside) is ignored until the third loop. So some loops are silent until the next one.
I cannot trust the onStatusChanged function because some times it is not getting executed (specially in the emulator). This is an already well known Cordova Media plugin issue. This is the reason why we cannot use this method to loop.
This is the code I have (simplified to be easily understood. Note that the point now is not performance or others but just make it work):
var onSuccess =
function()
{
mediaObject.play(null, null, true); //Null parameters for startAt and stopAt to play whole file.
};
var onError =
function(error)
{
//Whatever.
};
var onStatusChanged =
function(error) //Sometimes this method is not executed. Don't trust it.
{
if (status === Media.MEDIA_STOPPED)
{
console.log("Status changed to stop.");
}
};
var mediaObject = new Media("path/to/file.wav", onSuccess, onError, onStatusChanged);//Fires the events by calling play method and stopping immediately:
mediaObject.play();
mediaObject.stop();
var onStopTimeout;
function play(startAt, stopAt, loop)
{
if (startAt === null) { startAt = 0; }
if (stopAt === null) { stopAt = mediaObject.getDuration() * 1000; }console.log("Playing...");
mediaObject.play();
mediaObject.seekTo(startAt); //Performed after play (otherwise ).clearTimeout(onStopTimeout);
var onStopFunction =
function()
{
mediaObject.seekTo(0);
mediaObject.stop(); //also tried with mediaObject.pause();
if (loop)
{
console.log("Looping again!");
play(startAt, stopAt, true);
}
};
onStopTimeout = setTimeout(onStopFunction, stopAt - startAt);
}
As I said, that code above works well in the emulator. But it does not work well in the real device.
This is the console output in the emulator (where all works fine):
Status changed to stop.
Playing...
Status changed to stop.
Looping again!
Playing...
Status changed to stop.
Looping again!
Playing...
Status changed to stop.
...
This is the console output in the device (where the first loop and some others are silent):
Status changed to stop.
Playing...
Looping again!
Playing... //<--- Now the loop is silent. No sound can be heard.
Status changed to stop.
Status changed to stop.
Looping again!
Playing... //<--- Now the sound can be heard again.
Looping again!
Playing...
Status changed to stop.
Status changed to stop.
...
You can observe that "Status changed to stop." is either printed twice (and then no sound is heard) or not printed at all (and the soundn can be heard). First loop is printed twice, third loop none, four loop twice... and so on. So only even loops are heard and not the odd ones.
A first solution would be to make onStopFunction to wait until onStatusChanged is called to execute the loop again. But as I said before, I cannot trust that onStatusChanged is called because sometimes is not.
A second solution would be to prevent playing whole file with a margin of about 500ms to fix the problem and then it works everywhere. I just need to do this inside my play method (before calling the setTimeout):
//Don't let play the whole file:
var margin = 500;
var duration = mediaObject.getDuration() * 1000;
if (stopAt + margin > duration) { stopAt = duration - margin; }
But I do not like this solution. It forces to stop before the file ends. And it should work with all kind of audio files (some will have sound until its very end).
Is there anyone who has faced the same issue or similar? I would like to find a solution since I am developing a game engine that includes different APIs to play a sound and one of them is the Cordova Media plugin.
Thank you very much in advance. I would really appreciate any help.
- Tags:
- HTML5
- Intel® XDK
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are some low-latency audio plugins out there that might serve you better than the standard Cordova Media plugin. I recommend you search for those and try one of them. There are several that people have used with good luck.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Joan. Like Paul said, it looks like what you need is a low latency plugin instead. Try this one: https://github.com/floatinghotpot/cordova-plugin-nativeaudio. It is also used to in the audio player sample the XDK ships with.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you very much for your replies.
@Armita C., I tried that example and it works well in the emulator but not in the real phone (using debug option from Intel XDK). When I click to the button that represents the audio that supposedly has been recorded I cannot hear anything. But I do not see the relationship between that and my problem.
My code works and plays the sound nicely. There is no problem when I play a file from one point to another which is not too close to the end of the audio (because that way, I guess, the playing is never stopped). And it loops without problem. But when I try to play and loop playing whole file (or a part of the audio which stops very close to the end of the file), then some loops are silent.
I know there are other plugins with low latency. But my problem is not related to latency. I would like to find out a solution for the problem I have because I am interested in making my engine compatible with the Apache Cordova Media plugin.
Now my engine, which should work everywhere without modifying the code (desktop, mobile...), can use Web Audio API, Audio API, SoundManager 2 (with Flash fallback) and Apache Cordova Media plugin. Next ones will be Intel XDK Player plugin and maybe some others with low latency (maybe https://github.com/floatinghotpot/cordova-plugin-nativeaudio but I cannot see which platforms it is compatible with). But for now, I am working with Apache Cordova Media plugin and it just has that problem.
If someone know a solution or can reproduce the problem and can find a way to solve it, I will be very grateful.
Thanks,
Joan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If anyone is interested, so far the unique momentary solution I have been able to find is just using two sounds and alternate them when I have to loop. It is not a good solution because it has to use the double of Media objects but it works at least.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page