The example will be a basic Media player with play/pause and stop functionality. Here's a quick screen shot:
On Android you can create a Media object using one of three ways. The first way is referencing a file in your "android_asset" directory. For instance if you have a file called "test.mp3" in your projects "assets/www" directory you would create a new media object by doing:
myMedia = new Media("/android_asset/www/test.mp3");The second way to create a media object is by referencing a file on your devices file system. Say for instance, you have a file at "/sdcard/test.mp3" of your device you would create the media object by doing:
myMedia = new Media("test.mp3");You'll notice the "/sdcard/" portion of the file name is omitted. This is because on Android the Media object makes an assumption that the file is stored on your "/sdcard". Note: I may change this behaviour in an upcoming version of PhoneGap but I'll strive to retain backward compatibility.
The third and final way to create a media object is by URL:
myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3");Now that we've got our media object we want to be able to do the sensible thing and be able to play the audio. For that we'll create a play button:
<a href="#" onclick="playAudio()"><img id="play" src="images/play.png" /></a>and corresponding function:
function playAudio() {
myMedia.play();
}
Now the stop button is just as simple:<a href="#" onclick="stopAudio()"><img id="stop" src="images/stop.png" /></a>
function stopAudio() {
myMedia.stop();
}
However, that's pretty lame as it would be great to be able to pause the audio playback so let's enhance out play and stop functions:function playAudio() { if (!playing) { myMedia.play(); document.getElementById('play').src = "images/pause.png"; playing = true; } else { myMedia.pause(); document.getElementById('play').src = "images/play.png"; playing = false; } } function stopAudio() { myMedia.stop(); playing = false; document.getElementById('play').src = "images/play.png"; }Now when the user is playing some audio the play button image is changed to a pause button and hitting the pause button again will, well, pause the playing of the audio. I'm cheating a little bit by using a global variable called playing as it could easily be changed to check what the currently set image is and doing the correct action.
Of course it is always nice to know where we are at in a given audio clip so we can add some functionality to get the current position of where we are at in the file. So let's create a function that will run every second and update our HTML with the current position of the audio file.
<p id="audio_position">0.000 sec</p> var mediaTimer = setInterval(function() { myMedia.getCurrentPosition( function(position) { if (position > -1) { document.getElementById('audio_position').innerHTML = (position/1000) + " sec"; } }, function(e) { console.log("Error getting pos=" + e); } ); }, 1000);
That's all well and good but there is one thing that's slipped by our notice so far. When an audio clip finishes playing the pause button should become a play button in case the user wants to play the clip again. That can be accomplished by adding a success call back to our Media object constructor. The success call back is executed when the clip has finished playing. So we'll now instantiate our media like this:
myMedia = new Media("/android_asset/www/test.mp3", stopAudio);So what we have here are the beginnings of a audio player application for Android. In part two of this article I'll enhance the app with the File System and Directory API showing you how to scan your device for audio files.
The HTML and images can be found here and below is a listing of the HTML code uses in this article. I added a select box so that users could switch between the different ways of creating a Media object. You'll have to supply your own MP3 file as I don't want the RIAA coming after me.
Hi Simon,
ReplyDeleteSo there seems to be a fourth way to create a Media object and that is with src=null. For iOS, this seems to create something like "documents://1203044830072" where the numbered part is unique with each creation.
What is it creating?
Thanks for your help,
Jo
If I'm not mistaken if you pass src=null to the Media class on iOS it will make it's own file name using the current date. This file name will be used if you call the startAudioRecord() method.
ReplyDeletemedia.getCurrentPosition and media.getDuration currently do not seem to work in ios , is this support coming in a future release?
ReplyDeleteCorrect, those methods don't work on iOS yet but we are looking into including them for 1.0 due end of July early August.
ReplyDeleteI've just started developing a media application with PhoneGap, and I noticed that when loading an audio file from a URL, the app becomes unresponsive until it is ready to play. Could this be mitigated by using Web Workers to load them in a different thread?
ReplyDeletein simulator it works
ReplyDeletebut in real device its not work
i want to stream shoutcast
@Rob Archer
ReplyDeleteI think it has to do with the OpenCore instance being allocated by the Android OS.
@Ibnu Maksum
I'll help you over on the google group.
Hi Simon, i have one cuestion... I made all what u said.. but allways, no matter what i do and what function use i allways get a prompt with this:
ReplyDeletegap:["Media","startPlayingAudio","Media0",true]
????... U have any idea what is this... i found the code in phonegap-1.0.0.0.js this code:
var r = prompt(PhoneGap.stringify(args), "gap:"+PhoneGap.stringify([service, action, callbackId, true]));
and this is the prompt what i getting... Plis help!
PS: sorry for my inglish, i just starting with it
thanks for the code!
ReplyDeleteHi again Simon.. a few seconds I realized that in the BROWSER allways going to get the prompt, in the divice it s Work Amazin! Both codes, your and mine.
ReplyDeleteThanks again.
Best regards
In the example above - with the file page "/android_asset/www/test.mp3" ... will this work "out of the box" on an iPhone is the test.mp3 file is in the same place (www/test.mp3)?
ReplyDelete@Dr Senior
ReplyDeleteNo, it won't work out of the box on iOS as it has no concept of the android_asset directory. You'll need to do a conditional for now to determine if you are on iOS or Android and pass the appropriate path.
I'm advocating we spend some time in 1.1 to make Media sane across all platforms.
Hello, does media.getDuration work yet on iOS?
ReplyDelete@anh
ReplyDeleteIt should but if it doesn't open an issue on github and we'll get it fixed.
https://github.com/phonegap/phonegap-iphone/issues
hi, can you explain, how to use a playlist (play several files sequentially)?
ReplyDelete@Lars
ReplyDeleteI've been meaning to write some code to do exactly that. I would keep and array of file names or urls then in my onSuccess method of the Media constructor, which is stopAudio in the example, I would add one to my array index create the new Media object and start playing.
To make things faster I'd probably keep a buffer of 3 to 5 Media objects so that people could skip or go back in the play list.
Hi Simon,
ReplyDeletei wanna add the ID3 in the player,
i used from this library :
http://web.ist.utl.pt/antonio.afonso/www.aadsm.net//libraries/id3/
http://github.com/aadsm/JavaScript-ID3-Reader
this is my code:
var file="/sdcard/music.mp3";
function callback() {
var pic = ID3.getTag(file, "picture");
var artist = ID3.getTag(file, "artist");
var title = ID3.getTag(file, "title");
document.getElementById('judul').innerHTML = artist+ "\r\n";
document.getElementById('judul').innerHTML += title+ "\r\n";
document.getElementById('urlartis').src = "data:" + pic.format + ";base64," + Base64.encodeBytes(pic.data);
}
myMedia.play();
ID3.loadTags(file, callback, ["picture", "artist", "title"]);
playing = true;
it took 40 second to show the artist & title. but the picture not showed at all.
is there a way to speed up this, and also why the image does'nt show.
thanks before for your help.
Ali
@Arkan
ReplyDeleteSorry, I can't help you here as I've never used that library but it looks like a cool one. If I had to guess what it is slow is that they are using JavaScript to read a binary file which it doesn't support out of the box. I number of tricks have to be done for the library to read the binary data.
Hi simon....
ReplyDeleteThanks for the tutorial...
I tried it, it working fine in emulator, but it is not working in my device sony erricsson xperia... what is the problem....
@Jithin
ReplyDeleteThe first thing that jumps out at me is that your Sony may not have to proper codec for playing the file. Run "adb logcat" to see what is going on.
Hi simon, thanks for the quick response.
ReplyDeleteCan i add volume controller for this app. ?
Regard
Jithin
@Jithin yes, you can. There is a setVolume() method on the Android PhoneGap Media class. It is coming to other platforms.
ReplyDeleteHi simon,
ReplyDeleteCan u explay how to run "adb log cat", because a m very new to android.
thanks
jithin
@jithin
ReplyDeleteadb logcat docs.
thanks simon
ReplyDeleteHi simon,
ReplyDeleteyour demo url http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3 is working fine in both emulator and device. But i applied another url http://live.ardanradio.com:8228/;audio.mp3. but it is working only in emulator, not working in device. i run adb logcat, it showing D/dalvikvm( 2335): GC freed 7225 objects / 344040 bytes in 100ms
W/MediaPlayer( 2335): info/warning (1, 32)
I/MediaPlayer( 2335): Info (1,32)
D/dalvikvm( 2335): GC freed 20579 objects / 799192 bytes in 118ms
D/dalvikvm( 2335): GC freed 17355 objects / 657824 bytes in 115ms.
and also i checked with this shoutcast url:http://62.75.216.8:8008/;audio.mp3. but same problem
@Jithin
ReplyDeleteCan't test right now as I am at a conference but try removing the /;audio.mp3 from the end of the URL.
hi simon
ReplyDeletethanks for the quick response,
i tried with http://62.75.216.8:8008 this url. But working only in emulator but not in emulator.
hello sir me new to phonegap n android development i have audio in binary i.e base 64 format however it does not play on android audio tag.....please help me...
ReplyDelete@Unknown the "audio" tag does not work in the WebView for some strange reason. Use the Media class instead.
ReplyDelete@Jithin that URL plays fine in the emulator and my Samsung Galaxy S phone. What version of Android is your phone using?
ReplyDeleteHai simon,
ReplyDeletei am using samsung galaxy s5570(android 2.3)...
Sorry @Jithin I can't reproduce your problem. I wonder if it is a missing codec problem on your phone as, as you say, it works in the emulator.
ReplyDeleteHi simon,
ReplyDeleteI don't know what wrong thing i did. i checked with these two url 1. http://62.75.216.8:8008
2. http://stream.lexandterry.com:8000
But first one working only in emulator and second one working in both device(samsung galaxy s) and emulator. After that i checked with sony Ericsson experia. But same problem happening.
Sorry @Jithin, I don't know what to tell you. Some devices may not support streaming audio. I know you need Android 2.2 or better for this to work though.
ReplyDeletehello Simon Sir,
ReplyDeletemy application requires me to play mp3 BASE64 audio..
phonegap my media doesn't play bas64 audio source...
kindly help Thanks in advance...
@Unknown you'd have to write a plugin to convert your base64 encoded mp3 to a binary file and then pass that the the Media class to be played.
ReplyDeleteDear Simon,
ReplyDeleteThanks for writing this awesome tutorial. I'm having trouble getting the full filepath of the new recorded Media object and uploading it to the server. I wonder if you could suggest how to do it? I've already tried just saving it to android_asset but file upload doesn't work with /android_asset/www/myrecording.mp3 - I know the problem isn't with my file upload methods because I can already upload other files. I just can't get the fullpath of this recording I've made using your recorder/player code.
@Andrea Levinge
ReplyDeleteThat's because the Media class isn't following any know spec. The file name you pass in is assumed to be under /sdcard. So if you pass in temp/data/record.mp3 the file will end up at /sdcard/temp/data/record.mp3.
You cannot save files to the android_assets directory as that is a "virtual" directory that is part of your .apk.
Hi Simon,
ReplyDeleteThank you so much for replying!
I created a new Media file:
mediaRec = new Media('myrecording.amr', onSuccess, onError);
mediaRec.startRecord();
I want to get that mediaRec's fullPath.
I check where the file is actually located on my sdcard and it's located at /mnt/sdcard/external_sd/
I've tried the following filepaths for uploading:
/mnt/sdcard/external_sd/myrecording.amr
/sdcard/myrecording.amr
myrecording.amr
but the upload always fails as if the file does not exist.
I've successfully uploaded photos and videos already but those were captured using the example code from the API. This recording uses a new Media object. I suspect it is saving it at content://media/external but I don't know how to get the URI of the new Media object I've created. All I know is that photos are getting temporarily saved to content://media/external/images/media/ but I'm sure that's different for audio recordings. I've tried grabbing it from the onSuccess method, but it seems to pass nothing to the onSuccess method when creating a new Media file.
Let us know when your book comes out, I will be ordering it for sure.
Kukulako from Puerto Rico...
ReplyDeleteCan I put seek bar or progres bar?
@kukulako
ReplyDeleteSure, but you'd have to implement it yourself using getDuration and getCurrentPosition.
Simon,
ReplyDeleteHow does this work with PhoneGap Build and PhoneGap 1.2? Where are the media files that are packaged with the application placed and how would I access them cleanly from any platform?
@John
ReplyDeleteI'm not sure how it would work on the build service as I don't use it. For regular PhoneGap you'd have to do an OS detection and pass the correct prefix along with your file name to the Media constructor.
This has the potential to be great, but can I have a looping background track with an independent volume, while playing a foreground track, or playlist?
ReplyDelete@John A
ReplyDeleteThese are some great ideas and we should make the Media class better for people making games. You should raise a ticket at:
https://issues.apache.org/jira/browse/CB
Hi Simon,
ReplyDeletePlease help me out in displaying the All Songs and playlists of android device and how to access android device media table to display the list using phone gap.
Thanks in advance.
Hi Uday, I haven't written the code yet but what you'd need to do is query the content provider for the available music.
ReplyDeletehttp://developer.android.com/guide/topics/providers/content-providers.html
Thanks Simon for reply,
ReplyDeleteIs there any way in phonegap to get the data using content provider and display using phonegap javascript and html5. Do i need to write any phone gag plug in to read data using content provider.
@Uday
ReplyDeleteYes, you'd need to write a plugin for that type of functionality.
@Andrea
ReplyDeleteSorry I missed your comment. After you call stopRecord() the file should be moved to /sdcard. So you should be able to use:
/sdcard/myrecording.amr
of
file:///sdcard/myrecording.amr
In my app, setVolume() possible values are 0.0 - 1.0. It's looking for a float value.
ReplyDeleteHi Devgeeks,
ReplyDeleteI'm testing your demo with a shoutcast streaming url and it does'nt work :(
I tested with the streaming url somebody said in this google group.
The debug window in Xcode stucks on this line:
2012-02-08 15:02:21.274 altafullaradio[3219:13403] Will use resource 'http://live.ardanradio.com:8228/;audio.mp3' from the Internet.
I'm using the latest version of phonegap, and iOS 5.0.1
With a normal mp3 url it works good. But with a streaming url it does'nt
What I should try?
Thank you.
Kind regards,
@MrReview
ReplyDeleteSounds like a bug in iOS. I'll let Becky or Shaz address this on the google group where you also asked your question.
Very useful tutorial on Media Player.
ReplyDeleteMaybe you have an hint for a apparently blocking problem: is there a way to pass the mediaplayer between different html pages (not dynamically injected)? If I create the mediaplayer in page one.html, how could I use it in page two.html (loaded as "external")? I know the object is still alive, I can still hear audio (if I don't release it), however, I've no reference to the mediaplayer to control it.
Thank you for any hint!
Kind regards
Paolo
@pcasa.net
ReplyDeleteOnce you go to two.html all the JS from one.html is unloaded. You'll want to register a "pause" listener to release your Media object. Then create a new Media object in page two.html.
Hi Simon,
ReplyDeleteHow is it decide where the media file is when I am developing an android phonegap application?
assets/www or sdcard
@ArulMurugan
ReplyDeleteIt's up to you. Files that are deployed with the application end up in assets. Files downloaded generally end up on the sd card.
Hi Simon ,
ReplyDeleteWhen the phone is sleeping or active other app ,how can i keep the audio play in the background? would u give me some solution suggestion? and does this be feasible ?
@juxiang peng
ReplyDeleteAs long as you use the home button to put your app in the background it should continue to play.
Thank u for the reply!
ReplyDeleteIn android it play good ; but ios is not ok, i maked the audio play as
//code start
new Media(src ,onSuccess, onError,onStatus).play() ;
//code end
Any suggestion for the ios ?
@juxiang peng
ReplyDeleteI would split out the play onto the next line. iOS might need some time to prepare the Media object.
Thank u for your relay ;
ReplyDeleteI solve the background play problem from this link :http://mobile.tutsplus.com/tutorials/iphone/ios-sdk_background-audio/
and *-info.plist a configure :
"
Once the project has been created go to NoiseMaker-Info.plist and add UIBackgroundModes as a new row. It should then create the array. "
Thanks Simon, i was buid Android apps with this plugin and tested with Android Ice Cream Sandwich.
ReplyDeleteIts works, but the buffering is to much wasting time.
I was succesfully tested it on Android Ice Cream Sandwich, but how about the Blackberry? It also works too?
ReplyDeleteHi..
ReplyDeleteI'm beginner on phonegap.
I make some page that play some music on each page.
Page1.html, play page1.mp3
Page2.html, play page2.mp3
but, when I'm on page2.html and go back to page1.html, the page1.mp3 becomes echo..
when I go to the page2.html and go back again to the page1.html, the page1.mp3 becomes double echo -_-
what should I do ???
very need help.
thank you
I have download music file in phone memory. Location is : file://data/data/com.luontoportti/files/2/audio/Accnis.mp3
ReplyDeleteHow can I play these files. It works if i download file in sd card. But not for this. Please help me.
Regards
Reezo
Thanks for the great post....
ReplyDeleteI include my app resources in the html application manifest cache.
What I want to do is cache the mp3 file in my manifest as well so it can be play when my app is offline. it doesn't seems to work (it works fine if I am online). can this be done using phonegap media type while offline?
thanks,
@profilcaleg
ReplyDeleteYeah, if you want to get around the buffering you will probably need to download the file to the sdcard to make playback faster. Yes, I believe Drew just added support for Media for BB,
@ikkimassu
ReplyDeleteRegister an event listener for the "pause" event and stop playing your file when you leave the page and then wait for the "resume" event to start playing the file again.
@reezo ahmad
ReplyDeleteOnly the application that is "com.luontoportti" will be able to play those files. No other application will have access to your internal app storage directory. That's why it works when they are on the sd card as that has not file protection.
@wilson
ReplyDeleteThe Media class will not look at the app cache. You'll need to download the audio to the sd card in order to cache it manually.
HI Simon and thanks for your great works
ReplyDeleteI use you plugin for playing audio in an app on my Galaxy tab (android 3.2, Cordova-1.8.1) and its works perfectly
If i try this app on an LG (Android 2.3.3) or a samsung (Android 2.3.3) its does'nt works
What could you suggest ?
Thanks
@Patrick
ReplyDeleteAre you trying to play a local file, a file in assets or a remote file? Run "adb logcat" to see what is going on.
Thanks for your answer.
ReplyDeleteI am sorry but i make a mistake, i was calling phone gap 1.8.1 as i was running on phone gap 1.9.
All is ok now
@Doubts
ReplyDeleteThat is odd the getDuration should return the proper duration of any local media file. As for building the slider you won't be able to seek in a file that is not playing as the file is not prepared yet. We've made some changes in 2.0.0 and we are going to get it right in 2.1.0 to make Media work much better. Get ready for another blog post later this month.
Hi Simon,
ReplyDeleteI wanted to have a toolbar kind of interface for my media player while the phone is in lock mode. Do you have any suggestions as to how to implement it?
I am using phonegap, jquery on android.
@Doubts
ReplyDeleteIt isn't very easy to add stuff to the lock screen. You would need to write a plugin for sure. Check out this SO answer for some possible solutions:
http://stackoverflow.com/questions/4116001/android-lock-screen-widget
Hi Simon,
ReplyDeleteThank you for your great article.
It seems that something is not working correctly in my setup. If I call play() only once, the player does not start. Only if I call it twice the playback starts. What am I doing wrong?
Here is the environment; Samsung Galaxy with android 2.3.3, cordova 2.0.0.
var m = null;
function myTest1(){
if(m != null){
m.stop();
m.release();
m = null;
}
m = new Media(media_src, onSuccess, onError);
m.play();
m.play();
}
Thank you,
-igor
@igor
ReplyDeleteYou are running into a bug in 2.0.0. 2.1.0 with a bunch of fixes to Media will take care of it.
hi simon
ReplyDeletei have added your given code and images to asset/www
but it doesn't work
any other changes to made?
i am new to phonegap
waiting for your response
@umairqureshi_6 et al
ReplyDeleteI'm going to stop answering comments that are along the lines of "it just doesn't work". Obviously it does work or I wouldn't have posted this information up in the first place. I'm sorry but you probably didn't follow the instructions correctly or at least that's what I'll have to assume if you don't give me enough information like:
1) Android version
2) PhoneGap version
3) error logs (learn "adb logcat" folks)
Sorry to be an ass but I don't have time to debug everyones problems or chase them for information they aren't providing.
Hi simon :
ReplyDeleteIt's ok for playing files under /android_asset/sample.mp3. but it will failed when using url as remote http (ex :http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3). Log as below . Can media object support playing mp3 via http ?
emulator : android 2.2
cordova : 1.8
Error : E/MediaPlayer(685): Error (1,-2147483648)
@吳志忠
ReplyDeleteYes, it supports playing files over http.
Hi Simon, thanks for this great example, im trying to stream this url: http://streaming507.com:9996 is shoutcast aac+ but when i click play i just hear strange noices not the music itself can u help me please.
ReplyDeletethanks very much.
@Alexis Gaitan
ReplyDeleteRight now it says that server is down so I can't tell you for sure if that url would even work. I can tell you that streaming audio only works on Android 2.3 or later, if I remember correctly. Maybe it is Android 2.2.
Simon, thank you for the wonderful article, but could you please help me figure out the correct directory structure to play my audio files in PhoneGap on Android. Currently my audio is stored in the directory: assets/www in a folder audio.
ReplyDeleteThatis the index.html file in assets/www has path names referred as: audio/publisher104_book311_view3.mp3
@Ozzy Shahzaib
ReplyDeleteYou should use:
myMedia = new Media("/android_asset/www/audio/publisher104_book311_view3.mp3");
myMedia.play();
Hi Simon,
ReplyDeleteI have been following your posts all over the web (here, stackoverflow, ect), and I have been trying to resolve this issue that I have with Cordova 2.1 for Android...
Basically I want to create an array of Media objects in javascript upon recording the file. At the top of the js file an array - mediaFiles = []; - is initialized, and, upon each "onRecord" event that is triggered, I do this:
-
mediaFiles[counter]= new Media (path, success, error, status) ;
-
and then i do:
mediaFiles[counter].startRecord and mediaFiles[counter].stopRecord respectively.
--------
I know that the media files are created successfully, because when I open them with a file manager I can play them back. However here is where my confusion occurs.
On the "playFile()" event that is triggered, I attempt to simply determine which file the user wants to play, and then call:
-
mediaFiles[item].play();
-
Now, this is the ONLY place that it does not work! I know I am referencing the correct array index, i've checked it over and over again, and I cannot seem to find out what is wrong... Furthermore, there is nothing in the LogCat either. I have tried to do an "alert(mediaFile[item].play)" and all I get is the function definition of the play function for the media File.
Do you think you would be able to reproduce the same issue?
Thank you very much for your help!
-Mike
@Mike Alireza
ReplyDeleteThere may be a bug in the Media API. You should try creating a new Media object to play the file you've recorded.
@Simon
ReplyDeleteThank you for your reply.
Interestingly enough there was a phonegap update on Nov 1st (which you posted as well I believe). I reverted back to my initial version with 2 objects only, each being created when needed and released when not needed (the correct way).
Surprisingly, it works perfectly fine now...Guess there was a bug!
Thanks!
-Mike
@Mike Alireza
ReplyDeleteGreat, glad we fixed it.
getCurrentPosition can be terribly inaccurate at times. Why is it implemented as an asynchronous callback?
ReplyDeleteI have detailed description of the issue posted here:
http://stackoverflow.com/questions/12633726/phonegap-media-getcurrentposition-is-inaccurate-and-slow
@Dave Lowerre
ReplyDeleteI feel your pain. No one is more disappointed in the Media API than I am. I've been after the guys to do a review of this API for ages. I really want to replace it with and implementation of the W3C Audio tag API in JavaScript instead.
Have you looked at the Low Latency Audio Plugin? It may not do 100% what you want but it is probably more performant and could be modified to return a current position.
https://github.com/phonegap/phonegap-plugins/tree/master/Android/LowLatencyAudio
@Mishbah Razzaque
ReplyDeleteRegister an event listener for the "pause" event. When you get a pause event call media.stop().
Hi Simon
ReplyDeleteCan we analyse audio intensity of the recorded sound using phonegap.
@rahulmendonca
ReplyDeleteNo, you'd need to write a plugin to do this.
any thought on how to continue playing audio in the background?
ReplyDeletethx
@scottii
ReplyDeleteWhat behaviour are you getting as I can do that just fine on Android? Make sure keep running is set to true in onCreate:
super.setBooleanProperty("keepRunning", true);
Hi Simon,
ReplyDeleteHow can we add a loading image while the audio file is streaming. My files are bit larger so the loading of file taking some time, how can I solve it.
@joseph
ReplyDeleteThe Media API is actually pretty lame. There is no event fired when the file is loaded. Without making some additions to the native code I don't know of a way to do this.
@Simon
ReplyDeleteThanks for this great tutorial, it really opend my eyes!! But since 3 days im really disfrustated, i only can play the mp3 from the Url. I tried the whole tutorial with Phonegap Build, so that i add the test.mp3 simply in the same package with the index.html. But somehow it wont play! And how do i save the mp3 file on the sdcard, to load it how you described with ("test.mp3")? Greetings from Germany! Hope you understand my englisch! Sorry!
@gammler
ReplyDeleteYou should have any trouble playing the file if you use the path I specified in the tutorial if the mp3 is in the same folder as your index.html.
If you want to put a file on the sdcard use adb push.
Hi Simon, I am using your exact code and when i run the App;icationin Browser Mozilla just to test if this triggers the File or not, I am getting the following error:
ReplyDeleteTypeError: myMedia is null
[Break On This Error]
myMedia.play();
ReferenceError: Media is not defined
[Break On This Error]
...dia = new Media(yourSelect.options[yourSelect.selectedIndex].value, stopAudio, n...
@randhawaz.com
ReplyDeleteThe Media object doesn't exist in Firefox.
Hi Simon,
ReplyDeleteHere i tested on Chrome:
Uncaught TypeError: Cannot call method 'play' of null
playAudio
onclick
Uncaught ReferenceError: Media is not defined
updateMedia
onchange
@gavyrandhawa
ReplyDeleteIt's not in Chrome, Firefox, Opera, etc. you have to run it as a PhoneGap application in the emulator or on the device.
Hi Simon
ReplyDeletethanks for the excellent article.
I'm experiencing a strange problem that I can't find any leads on:
In a simple PhoneGap Android project, I can play sound just fine through the Media object.
However, within a larger framework I'm using on a current project at work, the sound does not play at all. No errors thrown - just no sound at all.
The framework links in many other javascript libraries for various purposes, but none related to audio.
Are there any know issues/conflicts between PhoneGap and other libraries?
(note - iOS works fine)
Thanks
Greg
@gmayer
ReplyDeleteNone that I know of. You may want to try grepping the other libs for instances of "Media" to see if there is a conflict.
Hi Simon I am trying to play an audio using different url. The audio is playing using http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3 url but when I try a different url, there's no response. Please help.
ReplyDelete@Nidhi Dagar
ReplyDeleteWhat URL are you using? Did you make sure it was whitelisted? Do you know if the codec is compatible on your OS?
Hi Simon, I am trying record and play on the same file. Record is working but play from /sdcard/ is not working on the device. I even tried creating a new Media object.
ReplyDeleteCode: http://pastebin.com/GUG0jTUh
What might be the problem?
@Gautam Kishore
ReplyDeleteLooking at your code in pastebin you use "/voiceit/myrecording.mp3" as the location of your file. That means it is trying to store it in the root file system in a directory called "voiceit". First thing I would do is to try your code with just "myrecording.mp3" which should just drop it in the sdcard. Then if that works and you have a directory called "/sdcard/voiceit" then try using the path "voiceit/myrecording.mp3" instead.
Thanks Simon. But, I've tried only myrecording.mp3 too. Also, the extra slash I noticed and removed after I pasted it to you in pastebin and its creating the file in /sdcard/voiceit/ but my problem is, its not playing from sd card.
ReplyDelete@Gautam Kishore
ReplyDeleteTry using the paths "voiceit/myrecording.mp3" and "/sdcard/voiceit/myrecording.mp3" either one of those should work. If they don't what are you seeing in "adb logcat" when you try to play the file?
Hi Simon,
ReplyDeleteI wanted to play an Url streamed thru shoutcast server in windows phone 7 in cordova. I tried it many times without any luck. Can u pls suggest a wau to do it. Thanks in advance.
@Sunil
ReplyDeleteSorry, I don't know if Windows Phone can play a shoutcast stream. Try asked Jesse MacFadyen @purplecabbage
Great post Simon. My media player works great on android but on ios it seems to freeze for a bit before finally playing. Any idea why?
ReplyDeleteMy code is thus
var path = "http:// ....";
var player = new media (path, onsucess, onfailure)
player.play()
The log file just says "will use resource 'http://....' from the internet."
Thanks
@Kingsley
ReplyDeleteIt probably takes a bit to buffer the file before it can start playing. Typically http delay.
Hi, Simon. The file format on Android is not 'mp3'. The codec is 'AMR' and the container is '.3gp'. What's more, on iOS it changes to '.wav'. Why does no one change the document till now? It mislead lots of people.
ReplyDelete@My computer science learning log
ReplyDeleteSorry, we're not perfect. Sometimes we make mistakes.
Hi Simon,
ReplyDeleteI have been facing an issue with Media object while playing live streaming (shoutcast). It looks like Media object's error function does not get called if the URL fails to return valid stream (bytes) but does return status code 200 (OK). The LOG CAT clearly shows that there is an error and Media cannot be played but this error message does not get forwarded to the media error function and Media object dies silently. The error function only gets called when I try to call Media.Stop() function.
I tested the same URL on Chrome, that implicitly uses HTML5 Audio object, and it seems like in case they do not get valid stream but 200 (OK), the Audio object keeps on trying and stops until it gets audio stream back. I used fiddler and can see Audio object calls the same URL again and again until it gets response with stream.
So my question here are,
1) Can we make Media object works the same way HTML5 Audio control works?
2) Can we force Media object to call error function in case there is any error (just after play).
I am hoping that you can help me on this.
URL
*******
http://radio.sgpc.net:8020/live16?1.mp3
LogCat logs
********************
08-12 11:09:32.348: E/HTTPStream(21328): HTTPStream::receive(): recv failed, server is gone, total received: 0 bytes
08-12 11:09:32.348: E/NuHTTPDataSource(21328): NuHTTPDataSource::readAt(offset 0, size 65536) err(-1005) = internalRead()
08-12 11:09:32.348: E/NuCachedSource2(21328): source returned error -1005
08-12 11:09:32.548: E/MediaPlayer(31929): error (1, -2147483648)
08-12 11:09:32.548: E/MediaPlayer(31929): Error (1,-2147483648)
08-12 11:09:42.988: E/CordovaWebView(31929): CordovaWebView: TIMEOUT ERROR!
Many Thanks,
Khushwant
@Khushwant Singh
ReplyDeleteYeah, I'd have liked to have fixed the Media object a long time ago but we never seemed to have had the time. You have a good case and description here, you should open a bug on JIRA:
https://issues.apache.org/jira/browse/CB
Hi Simon
ReplyDeleteI have query, when i'm try to convert website to android apps using phonegap its work fine but audio backgroud not functioning. can u please guide me step by step.
Thanks
Pradeep
itspradeepit@gmail.com
@PradeepIT
ReplyDeleteAre you using an audio tag or the Media class from PhoneGap? The audio tag doesn't work too well in a WebView.
Hey Simon,
ReplyDeletereally hoping you can shed some light on this, as I've spent a bunch of time trying to get things working with the Media class.
Here's the deal, I'm first using fileTransfer to download the MP3 and putting it into a sub directory called "cornish-mining" on the sdcard. But when I use the exact same URI in the media statement it does not play the file when on an Android device (iOS is just fine)
The file ends up in file://mnt/sdcard/cornish-mining/track_1.mp3
So after reading all the other comments and your instructions I tried moving the MP3 to the root of the SD card, and changed the path accordingly, no joy.
I've had no joy with
/mnt/sdcard/track_1.mp3
/mnt/sdcard/cornish-mining/track_1.mp3
/sdcard/track_1.mp3
/sdcard/cornish-mining/track_1.mp3
track_1.mp3
cornish-mining/track_1.mp3
(not forgetting that I have the same MP3 in the root and in the cornish-mining directory.
I'm really at a loss as to where to go next, so strange that it works on iOS and not on Android.
To add to the plot, I use window.appRootDir.fullPath to get the fully qualified location of the app directory (file://........../cornish-mining/) on the SD card as I know on my old galaxy-y the file path is vastly different to the S-4, neither of which are able to play the audio.
Please tell me I am just being silly and making a noob mistake.
Many thanks for your help in advance, if you want to see the code do let me know
@phatreaction
ReplyDeleteOkay that should work but one thing I notice is you are using the path "file://mnt/sdcard/cornish-mining/track_1.mp3" with 2 / but you should double check to make sure it has 3 / as in "file:///" as the first to are for the protocol and the last indicates the root of the file system.
The Media class is a bit of PITA and I wish we'd refactor it. What are you seeing in "adb logcat" when you try to play the file? If you can post a snipped of the code up somewhere like gist.github.com it would probably help.
Thanks for your effort
ReplyDeleteIts really helped lot of us...
Thanks, this helped a lot.
ReplyDelete