NOTE: This tutorial was written for Android v1.0. I have just updated the code to v1.5 (Cupcake) and written a quick addendum to that streaming media post with some additional information on the updated code. You should read that post as well as this one.
This is a long tutorial, but for those of you that have been struggling with streaming of .mp3 audio to Google’s Android’s MediaPlayer, then I hope this tutorial proves useful as you finalize your entries into Google’s Android Challenge
This tutorial will show how to roll your own streaming audio utility for Android’s MediaPlayer. We will buffer 10 seconds of audio and start playing that audio while the rest of the audio loads in the background. We store the streamed audio locally so you could cache it on device for later use or simply let it be garbage collected.
Here’s the source code for those that just want to jump in. You’ll also notice code for the other tutorials as I didn’t have time to strip them out.
Here are a few screenshots of what we’ll be creating:

Basic Layout
The tutorial consists of just two classes:
Tutorial3: Contains the UI layout and process button clicks
StreamingMediaPlayer: Connects to the server, downloads audio into the buffer, and controls the functionality to ensure the audio continues to play seamlessly.
We’ll assume you know about UI layout using Android’s XML resource files and will instead jump right into the audio streaming code.
Start Your Streaming
Upon clicking the “Start Streaming” button, Tutorial3 creates an instance of StreamingMediaPlayer.
new StreamingMediaPlayer(textStreamed, playButton, streamButton,progressBar);
All UI elements are passed to StreamingMediaPlayer so it can perform UI update itself. In a more robust implementation, StreamingMediaPlayer would fire relevant update events and Tutorial3 would handle the UI updates. For simplicity & cleaner code in this tutorial however, StreamingMediaPlayer will be directly updating the UI.
Tutorial3 then calls StreamingMediaPlayer.startStreaming():
audioStreamer.startStreaming(“http://www.pocketjourney.com/audio.mp3″,1444, 180);
Three variables are passed to startStreaming(): a url for the media to stream (link to an .mp3 file in this tutorial), the length in kilobytes of the media file, and the lenght in seconds of the media file. These last two values will be used when updating the progress bar.
AudioStreamer.startStreaming() creates a new thread for streaming the content so we can immediately return control back to the user interface.
public void startStreaming(final String mediaUrl, long mediaLengthInKb, long mediaLengthInSeconds) throws IOException {
this.mediaLengthInKb = mediaLengthInKb;
this.mediaLengthInSeconds = mediaLengthInSeconds;
Runnable r = new Runnable() {
public void run() {
try {
downloadAudioIncrement(mediaUrl);
} catch (IOException e) {
Log.e(getClass().getName(), “Initialization error for fileUrl=” + mediaUrl, e);
return;
}
}
};
new Thread(r).start();
}
Incremental Media Download
This is where the magic happens as we download media content from the the url stream until we have enough content buffered to start the MediaPlayer. We then let the MediaPlayer play in the background while we download the remaining audio. If the MediaPlayer reaches the end of the buffered audio, then we transfer any newly downloaded audio to the MediaPlayer and let it start playing again.
Things get a little tricky here because:
(a) The MediaPlayer seems to lock the file so we can’t simply append our content to the existing file.
(b) Pausing the MediaPlayer to load the new content takes awhile so we only want to interrupt it when absolutely necessary.
(c) Accessing the MediaPlayer from a separate thread causes it to crash.
So with those caveats in mind, here’s the method that bufferes the media content to a temporary file:
public void downloadAudioIncrement(String mediaUrl) throws IOException {
// First establish connection to the media provider
URLConnection cn = new URL(mediaUrl).openConnection();
cn.connect();
InputStream stream = cn.getInputStream();
if (stream == null) {
Log.e(getClass().getName(), “Unable to create InputStream for mediaUrl:” + mediaUrl);
}
// Create the temporary file for buffering data into
downloadingMediaFile = File.createTempFile(“downloadingMedia”, “.dat”);
FileOutputStream out = new FileOutputStream(downloadingMediaFile);
// Start reading data from the URL stream
byte buf[] = new byte[16384];
int totalBytesRead = 0, incrementalBytesRead = 0;
do {
int numread = stream.read(buf);
if (numread <= 0) {
// Nothing left to read so quit
break;
} else {
out.write(buf, 0, numread);
totalBytesRead += numread;
incrementalBytesRead += numread;
totalKbRead = totalBytesRead/1000;
// Test whether we need to transfer buffered data to the MediaPlayer
testMediaBuffer();
// Update the status for ProgressBar and TextFields
fireDataLoadUpdate();
}
} while (true);
// Lastly transfer fully loaded audio to the MediaPlayer and close the InputStream
fireDataFullyLoaded();
stream.close();
}
What’s up with testMediaBuffer()?
So if you were paying attention, an important piece of functionality must reside in the testMediaBuffer() method. You’re right. That’s the method where we determine whether we need to transfer buffered data to the MediaPlayer because we have enough to start the MediaPlayer or because the MediaPlayer has already played out its previous buffer content.
Before we jump into that, please take note that interacting with a MediaPlayer on non-main UI thread can cause crashes so we always ensure we are interacting with the UI on the main-UI Thread by using a Handler when necessary. For example, we must do so in the following method because it is being called by the media streaming Thread.
private void testMediaBuffer() {
// We’ll place our following code into a Runnable so the Handler can call it for running
// on the main UI thread
Runnable updater = new Runnable() {
public void run() {
if (mediaPlayer == null) {
// The MediaPlayer has not yet been created so see if we have
// the minimum buffered data yet.
// For our purposes, we take the minimum buffered requirement to be:
// INTIAL_KB_BUFFER = 96*10/8;//assume 96kbps*10secs/8bits per byte
if ( totalKbRead >= INTIAL_KB_BUFFER) {
try {
// We have enough buffered content so start the MediaPlayer
startMediaPlayer(bufferedFile);
} catch (Exception e) {
Log.e(getClass().getName(), “Error copying buffered conent.”, e);
}
}
} else if ( mediaPlayer.getDuration() – mediaPlayer.getCurrentPosition() <= 1000 ){
// The MediaPlayer has been started and has reached the end of its buffered
// content. We test for < 1second of data (i.e. 1000ms) because the media
// player will often stop when there are still a few milliseconds of data left to play
transferBufferToMediaPlayer();
}
}
};
handler.post(updater);
}
Starting the MediaPlayer with Initial Content Buffer
Starting the MediaPlayer is very straightforward now. We simply copy all the currently buffered content
into a new Ffile and start the MediaPlayer with it.
private void startMediaPlayer(File bufferedFile) {
try {
File bufferedFile = File.createTempFile(“playingMedia”, “.dat”);
FileUtils.copyFile(downloadingMediaFile,bufferedFile);} catch (IOException e) {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(bufferedFile.getAbsolutePath());
mediaPlayer.prepare();
fireDataPreloadComplete();
Log.e(getClass().getName(), “Error initializing the MediaPlaer.”, e);
return;
}
}
Transferring Buffered Content to a MediaPlayer That is Already Playing
This is a little trickier but not much. We simply pause the MediaPlayer if it was playing (i.e. the user had not pressed pause), copy over the currently downloaded media content (which may be all of it by now) and then restart the MediaPlayer if it was previously running or had hit the end of its buffer due to a slow network.
private void transferBufferToMediaPlayer() {
try {
// Determine if we need to restart the player after transferring data (e.g. perhaps the user
// pressed pause) & also store the current audio position so we can reset it later.
boolean wasPlaying = mediaPlayer.isPlaying();
int curPosition = mediaPlayer.getCurrentPosition();
mediaPlayer.pause();
// Copy the current buffer file as we can’t download content into the same file that
// the MediaPlayer is reading from.
File bufferedFile = File.createTempFile(“playingMedia”, “.dat”);
FileUtils.copyFile(downloadingMediaFile,bufferedFile);
// Create a new MediaPlayer. We’ve tried reusing them but that seems to result in
// more system crashes than simply creating new ones.
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(bufferedFile.getAbsolutePath());
mediaPlayer.prepare();
mediaPlayer.seekTo(curPosition);
// Restart if at end of prior beuffered content or mediaPlayer was previously playing.
// NOTE: We test for < 1second of data because the media player can stop when there is still
// a few milliseconds of data left to play
boolean atEndOfFile = mediaPlayer.getDuration() – mediaPlayer.getCurrentPosition() <= 1000;
if (wasPlaying || atEndOfFile){
mediaPlayer.start();
}
}catch (Exception e) {
Log.e(getClass().getName(), “Error updating to newly loaded content.”, e);
}
}
Conclusion
To get the real feel for how your audio will download, make sure to set it to a slower network speed. I recommend setting to AT&T’s EDGE network setting as it should give a lower limit on expected performance. You can make these setting’s easy in Eclipse by setting going into your Run or Debug setting’s dialog and making these selections.

Well that’s it. I’ve inluded additional code for handling the ProgressBar and TextField updates but that should all be sufficiently easy to understand once you understand the rest of the code. Good luck during the next week as you finish your Android Challenge submissions.
And of course, here’s the source code. Please post a comment below if I need to explain anything in more detail. You’ll also notice code for the other tutorials as I didn’t have time to strip them out.
Other Tutorials
Tutorial 1: Transparent Panel (Linear Layout) On MapView (Google Map)
Tutorial 2: “Hit” testing on a View (MapView)
Tutorial 4.1: Image and Text-Only Buttons
too useful and very good
Hi, great tutorial!. I’m working on a media player and i used it as a guide. I’m traying to add a funtionality, when i press a button i would like to change to the next song. It start play the music ok but after listening a few songs or after a while the emulator crash, it restart by itself, i don’t know whath i going on. I really appreciate your help. Thanks
Hello, unfortunately I have the same problem as Marielisa, after launching several songs the emulator crashes, any suggests?
Hi Michal,
We’ve been discussing this issue on another thread at AndDev.org. Here’s the link: http://www.anddev.org/viewtopic.php?p=6658#6658
Since this tutorial was posted, I’ve further developed my streaming player to support caching of files and have been able to play unlimited numbers of files without crashing. So…I at minimum know it’s possible and not a limitation of the Android SDK. That said, it took me a week of coding and debugging to resolve various quirks of reimplementing this tutorial as a Service.
Part of the Service challenge was dealing with multi-threaded conflicts and the caching though.
Are you using the StreamingMediaPlayer exactly as I had released it but with ability to play more files or have you re-implemented it as a Service?
Biosopher
Actually here’s a link to the exact starting post: http://www.anddev.org/viewtopic.php?p=8255#8255
Hi All,
I am new in Android.
Wants to develop one streaming media player application.
This tutorial is really nice to read and implement.
I have downloaded this source code. but not able to run it .
Can u all please help me .
Just show me the process how i should open this project in android to run this application!
Thanks in advance.
thanks.
Souvik
Hi Souvik,
Here’s how to import an .apk file into Android.
1) Start a new Emulator.exe or quit out of any apps running in a current Emulator by clicking the home button.
2) Run: adb install myproject/bin/.apk
e.g. adb install D:\personal\Work\Code\Eclipse\MobileJourney\bin\MobileJourney.apk
3) Note: Installation of new applications may require restarting the Emulator.exe as the Android app manager may only reads manifests on start.
Cheers,
Anthony
Hi Anthony,
Thanks for your quick reply.
But where and how to run “Run: adb install myproject/bin/.apk”
Where should i write this command.
And Even if I able to run this application in emulator, can i add it as a project and
do some modification into this? if yes, then how?
Waiting for your reply.
Thanks,
Souvik
Hi Anthony,
I forget to mention that I am using windows XP.
souvik
Hi Anthony,
Thanks a lot for your help.
Actually I was using windows pc. And there is no need to run
Run: adb install myproject/bin/.apk
we can directly load the project in eclips with the same folder name .and we have to run this application. Its working properly
Its really great.
Thanks,
Souvik
you guys ROCK! thanks for sharing!!!
Hi ,
I have done some basic application with android.And all are independent application.
Now I want to do something different …..
For example, I have two separate application like tutorials & Browser/Game
Now, what i have to do, If I wants to Launch game or Browser application by clicking Tutorial1 button which is a separate application???
Need help..(Its like calling one application from another application)
Thanks in advance.
Thanks,
Souvik
Hi Souvik,
Applications are simply groups of Activity & Service classes. To launch one application from another, all you’ll need do is have an Activity in one Application launch an Activity from the other application.
public class Application1 extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
Button launchApp2Button = (Button) findViewById(R.id.button_view_launch_app_2);
launchApp2Button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
startActivity(new Intent(this, Application2.class));
}});
}
}
Hi,
I’m not able to write blogs, after clicking submit buuton it’s displaying “discard” message.
What i have to do for this? Please let me know.
Thanks,
Souvik
Hi Biosopher,
Thanks for the response…
But my scenario is little different.
I have not done any main.xml changes for UI. like:
public class PikuTest extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
TextView tv = new TextView(this);
tv.setText(“test ===\n”);
setContentView(tv);
}
continued in next blog ….
I have created one menu iten with submenu like:
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
SubMenu subITEM = menu.addSubMenu(0,0,”TEST”);
subITEM .add(0, 1, “CM1″);
subITEM .add(0, 2, “CM2″);
subITEM .add(0, 3, “CM3″);
return true;
}
continued in next blog …
and i am handling these menu item in the function onOptionsItemSelected as switch statement where it displays through showAlert(“Menu Item Clicked”,0, “CM1″, “ok”, null, false, null);
continued in next blog ….
Now my question is when I am clicking CM1, How should i launch browser application.
Can u please modify the code to make me understand!!
Thanks,
Souvik
Hello souvik,
In the case of launching a browser window, you should pass a URI to startActivity() with an ACTION_VIEW intent. Android will then determine what the default browser is and hand your URI to it for display.
Activity parentActivity;
public HelpMenuHandler(Activity parentActivity) {
this.parentActivity = parentActivity;
}
Then when requested, simply call the following method with your desired URL:
parentActivity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(“http://www.pocketjourney.com/mobileHelp.do”)));
Cheers,
Biosopher
Hi Biosopher,
Thanks for the response…Its working with some small changes.
However we are calling Uri API, and its launching browser with the mentioned link.
But what happen if, I want to launch one of my own application by clicking the menu item?
suppose I want to launch “app1″ by clicking one menu item from “app2″. Then what activity I have to start?
Thanks,
Souvik
Hi Souvik,
Simply call: startActivity(new Intent(this, YourActivity.class));
Hello Biosopher,
But I am not able to call like this:
“Tutorials” is one different application for me. but this stsrtActivity I am calling from “TestApp”.
Where Tutorial and TestApp both have different package name. then how should I call ?
startActivity(new Intent(this, Tutorials.class));
For me if i call like this , its giving me error: Tutorials cannot be resolved to a type
Thanks,
Souvik
Hi,
How to refresh R.java file if its not updating automatically when I am adding one file in resource?
Thanks,
Souvik
Hi Souvik,
Make sure you are reading all the error messages in detail.
You are not allowed to have capital letters in your resources files so ‘HALUDPAKHI’ is an invalid file name. Change it to lower case.
The R.java should refresh itself but you can always right click on your project in Eclipse & select “Refresh” if necessary.
Anthony
Thanks,
I solved the problem.
Actually R.java file is not updated automatically because there is one “Thub.db” file inside “res”.
When i remove this file form that folder is updated automatically.
Now I can able to play mp3 file from resource.
But need help in case of playing from URl.
Have tried this steps, but not working:
try
{
MediaPlayer mp1 = new MediaPlayer();
mp1.setDataSource(“http://ip address /Jingle_Bell-Dog.mp3″);
mp1.start();
}
catch ( IOException e )
{
Log.e( “ioexception”, “”, e);
}
But its not playing .
Any suggestion??
Thanks,
Souvik
Hi,
I was wondering if you could provide a sample code of how u created the media player as a service?
thanks!
anu
Hi,
FileUtils were supported in the earlier version .but not in 1.0
how to solve this problem?
thanks
Hello Ele,
It seems we now need to write the code ourselves in order to copy files. Here’s the code for doing so. Hopefully I’ll get the time to rewrite and update this blog posting soon.
Anthony
public static void moveFile(File oldLocation, File newLocation)
throws IOException {
if ( oldLocation.exists( )) {
makeDirectories(newLocation, false);
//BufferedReader reader = new BufferedReader( new FileReader( oldLocation ) );
//BufferedWriter newFWriter = new BufferedWriter( new FileWriter( newLocation, false ) );
BufferedInputStream reader = new BufferedInputStream( new FileInputStream(oldLocation) );
BufferedOutputStream writer = new BufferedOutputStream( new FileOutputStream(newLocation, false));
try {
byte[] buff = new byte[8192];
int numChars;
while ( (numChars = reader.read( buff, 0, buff.length ) ) != -1) {
writer.write( buff, 0, numChars );
}
} catch( IOException ex ) {
throw new IOException(“IOException when transferring ” + oldLocation.getPath() + ” to ” + newLocation.getPath());
} finally {
try {
if ( reader != null ){
writer.close();
reader.close();
}
} catch( IOException ex ){
Log.e(“FileUtils”,”Error closing files when transferring ” + oldLocation.getPath() + ” to ” + newLocation.getPath() );
}
}
} else {
throw new IOException(“Old location does not exist when transferring ” + oldLocation.getPath() + ” to ” + newLocation.getPath() );
}
}
When the streaming is happening , at one of the cursor position the Media players gets paused with throwing this error.
11-19 16:00:06.659: ERROR/MediaPlayer(536): Error (-38,0)
Whats the reason for this error??
oh let me correct the error that i get when i run tutorial 3
11-19 20:09:41.339: ERROR/Player(247): 124584
11-19 20:09:41.350: ERROR/Player(247): /data/data/com.pocketjourney.tutorials/cache/playingMedia1.dat
11-19 20:09:41.430: ERROR/com.pocketjourney.media.StreamingMediaPlayer(247): Error initializing the MediaPlaer.
11-19 20:09:41.430: ERROR/com.pocketjourney.media.StreamingMediaPlayer(247): java.io.IOException: Prepare failed.: status=0xFFFFFFFC
11-19 20:09:41.430: ERROR/com.pocketjourney.media.StreamingMediaPlayer(247): at android.media.MediaPlayer.prepare(Native Method)
11-19 20:09:41.430: ERROR/com.pocketjourney.media.StreamingMediaPlayer(247): at com.pocketjourney.media.StreamingMediaPlayer.startMediaPlayer(StreamingMediaPlayer.java:170)
11-19 20:09:41.430: ERROR/com.pocketjourney.media.StreamingMediaPlayer(247): at com.pocketjourney.media.StreamingMediaPlayer.access$2(StreamingMediaPlayer.java:159)
11-19 20:09:41.430: ERROR/com.pocketjourney.media.StreamingMediaPlayer(247): at com.pocketjourney.media.StreamingMediaPlayer$2.run(StreamingMediaPlayer.java:143)
11-19 20:09:41.430: ERROR/com.pocketjourney.media.StreamingMediaPlayer(247): at android.os.Handler.handleCallback(Handler.java:542)
11-19 20:09:41.430: ERROR/com.pocketjourney.media.StreamingMediaPlayer(247): at android.os.Handler.dispatchMessage(Handler.java:86)
11-19 20:09:41.430: ERROR/com.pocketjourney.media.StreamingMediaPlayer(247): at android.os.Looper.loop(Looper.java:123)
11-19 20:09:41.430: ERROR/com.pocketjourney.media.StreamingMediaPlayer(247): at android.app.ActivityThread.main(ActivityThread.java:3742)
11-19 20:09:41.430: ERROR/com.pocketjourney.media.StreamingMediaPlayer(247): at java.lang.reflect.Method.invokeNative(Native Method)
11-19 20:09:41.430: ERROR/com.pocketjourney.media.StreamingMediaPlayer(247): at java.lang.reflect.Method.invoke(Method.java:515)
11-19 20:09:41.430: ERROR/com.pocketjourney.media.StreamingMediaPlayer(247): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
11-19 20:09:41.430: ERROR/com.pocketjourney.media.StreamingMediaPlayer(247): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:497)
11-19 20:09:41.430: ERROR/com.pocketjourney.media.StreamingMediaPlayer(247): at dalvik.system.NativeStart.main(Native Method)
Guru, I had the same issue then tried to play wrong content via Media Player. Since you cannot(as I see in SDK) specify content-type for sound file Media Player try to open and play .dat file and looks like cannot do so. Currently android supports olsy MPEG-4, MP3, AAC, AMR, JPG, PNG and h.264 formats.
p.s
I could be wrong of course but it is my observarions
i missed to say the rest of error: at java.net.Socket.connect(Socket.java:928)
Gyru:
player cannot read user’s files.
use:
FileInputStream ins = new FileInputStream(bufferedFile.getAbsolutePath());
mediaPlayer.setDataSource(ins.getFD());
instead
Hi guys, that is a nice tutorial.
I don’t think it’s clever if each one of us started their own program to use this.
So, has anyone written a working program that can stream audio?
If not, do we have a common project? Should we start one?
Thanks,
Chris
Hi,
First of all, nice tutorials you have here.
I’ve been trying to play your file. I configured the app, loaded it with Eclipse, and installed it. When I try the Tutorial 3 application, however, I can stream whatever file I want, but I don’t have any sound at all..
Still, there’s no problem with it, or so says Eclipse.
ty,
r0ckf3l3r
Hi r0ckf3l3r did you ever got the sound working, I have the same problem.
cmavr8
if you are intrested in common app – android platform has build in streaming activity in Media.apk
just use corresponding intent to invoke it:
this activity uses MediaPlaybackService to play the file. You can also use it.
MusicUtils.bindToService(this, new ServiceConnection() {
public void onServiceConnected(ComponentName classname, IBinder obj) {
try {
IntentFilter f = new IntentFilter();
f.addAction(MediaPlaybackService.ASYNC_OPEN_COMPLETE);
registerReceiver(mStatusListener, new IntentFilter(f));
MusicUtils.sService.openfileAsync(getIntent().getData().toString());
} catch (RemoteException ex) {
}
}
public void onServiceDisconnected(ComponentName classname) {
}
});
cannot post xml:-) sry
activity android:name=”StreamStarter” android:theme=”@android:style/Theme.Dialog”
intent-filter
action android:name=”android.intent.action.VIEW” />
category android:name=”android.intent.category.DEFAULT” />
category android:name=”android.intent.category.BROWSABLE” />
data android:scheme=”http” />
data android:mimeType=”audio/mp3″/>
data android:mimeType=”audio/x-mp3″/>
data android:mimeType=”audio/mpeg”/>
data android:mimeType=”audio/mp4″/>
/intent-filter>
/activity
Hi,
I noticed that getDuration() is returning the total duration of the file (probably retrieved from the file’s header), instead of returning the total duration of the buffered file. This is causing the method transferBufferToMediaPlayer() not to be called (it is called only when the whole file is downloaded). Does anybody knows a workaround for this issue?
Thanks
Thanks for the tutorial.
I found that you don’t actually have to copy the file over to a second one. You can just point the media player back to the same file. The only issue is that it looks at the file length when you give it the file, and then it will stop when it hits the end. So, you do have to reset it and point it back at the file again, but it can be the same one. There’s no “locking” that prevents you from appending to it.
I get java.io.IOException : prepare failed in startMediaPlayer() until the entire file is downloaded, at which point, prepare() works.
I am doing this to setDataSource:
FileInputStream ins = new FileInputStream(bufferedFile.getAbsolutePath());
mediaPlayer.setDataSource(ins.getFD());
Any ideas?
-amit
Hi Amit,
I tried to send this directly but the email you provided was inaccurate.
Could you post more of your code? It’s hard to tell with just that short snippet. Please show me the full set of calls from new MediaPlayer() through to mediaPlayer.prepare().
Thanks,
Anthony
What is your email Biosopher? I will email you all my code. I am using my correct email..
Thanks.
After some tinkering, I was able to make the app work with the mp3 file. But my real goal is to be able to stream videos. The same logic does not seem to work with mp4 or 3gp files. Anybody have any input? Whats this MediaPlaybackService class? Anybody know of any code that plays streaming video off the net?
amit
For simple streaming video, just follow the code for Android’s video demo in APIDemos. We use that code for streaming video without a problem.
Anthony
Anthony, by the APIDemo, I’m guessing you’re referring to the MediaPlayerDemo_Video class.
Since you are using this code for streaming video without a problem, can you share the URL’s of some of the videos you are able to play? The more variety the better. And if you can tell me exactly what kind of streamable content MediaPlayer can handle, that would be great too. Thanks a lot!
Hi Amit,
We settled on .3gp as getting other formats to stream properly was not working in the earlier versions. Other formats might work now but we’re happy with .3gp as it’s smaller than other formats and is an open format.
I’ll send the files to you to work with.
Anthony
Anthony, thanks for your response. I have been able to play 3gp and mp4 files locally too. IE, if I download these files onto the device then MediaPlayer can play them. But what I want to do is to be able to play streaming/progressive download videos straight off the web, with a minimum buffer. It seems MediaPlayer cannot do this (Prepare failed error), which is why I started looking into your StreamingVideoPlayer since downloading smaller chunks at a time and playing is faster than downloading the whole file and playing.
Are you aware of anything that can help me play streaming or progressive download video content, without downloading the whole file first?
The files I provided you are ones we stream from a server and play via Android’s MediaPlayer (i.e. we don’t download them first and then play them locally).
Without seeing your code, it’s hard to say what’s wrong. The main bug people typically introduce when playing video’s is to not setup their SurfaceView properly. Make sure your method call chain looks something like this else you’ll get a prepare error:
public Your MediaController()
{
…
// Add the video callback listener
videoSurface.getHolder().addCallback(MediaController.this);
…
}
// Implementation of SurfaceHolder.Callback
@Override
public void surfaceCreated(SurfaceHolder videoHolder)
{
// Don’t create and prepare your MediaPlayer until this method has been called
createMediaPlayer();
}
private void createMediaPlayer() {
try {
foregroundMediaPlayer = new MediaPlayer();
foregroundMediaPlayer.setDataSource(mediaUri);
foregroundMediaPlayer.setDisplay(videoSurface.getHolder());
foregroundMediaPlayer.setOnCompletionListener(this);
foregroundMediaPlayer.setOnErrorListener(this);
foregroundMediaPlayer.setOnBufferingUpdateListener(this);
foregroundMediaPlayer.setOnPreparedListener(this);
// If prepare() is called before the SurfaceView is ready, you’ll get a
// ‘preprare failed error’ when MediaPlayer accesses the invalid SurfaceView
foregroundMediaPlayer.prepare();
foregroundMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}catch (Exception e) {
Log.e(getClass().getName(), “Error while preparing MediaPlayer path: ” + mediaUri, e);
}
}
Anthony, I am creating the MediaPlayer only after surfaceCreated() has been called. I am still getting prepared failed error. Here is the code (I’ve removed the empty listener methods).
public class TestMediaPlayer2 extends Activity implements
OnBufferingUpdateListener, OnCompletionListener,
MediaPlayer.OnPreparedListener, SurfaceHolder.Callback {
private static final String TAG = “MediaPlayerDemo”;
private int mVideoWidth;
private int mVideoHeight;
private MediaPlayer mMediaPlayer;
private SurfaceView mPreview;
private SurfaceHolder holder;
private String videoStreamUrl;
/**
*
* Called when the activity is first created.
*/
public void onCreate(Bundle icicle) {
Log.d(TAG, “hello”);
super.onCreate(icicle);
setContentView(R.layout.main);
Toast.makeText(this, “hi”, Toast.LENGTH_SHORT);
mPreview = (SurfaceView) findViewById(R.id.surface);
holder = mPreview.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
//extras = getIntent().getExtras();
videoStreamUrl = /*url to a 3gp file. pocketjourney is complaining..*/
Log.d(TAG, videoStreamUrl);
}
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
Log.d(TAG, “surfaceCreated called”);
playVideo();
}
private void playVideo() {
Log.d(TAG, “in playVideo()”);
try {
// Create a new media player and set the listeners
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(videoStreamUrl);
mMediaPlayer.setDisplay(holder);
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.prepare();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
} catch (Exception e) {
Log.e(TAG, “error: ” + e.getMessage(), e);
}
}
public void onPrepared(MediaPlayer mediaplayer) {
Log.d(TAG, “onPrepared called”);
mVideoWidth = mMediaPlayer.getVideoWidth();
mVideoHeight = mMediaPlayer.getVideoHeight();
if (mVideoWidth != 0 && mVideoHeight != 0) {
holder.setFixedSize(mVideoWidth, mVideoHeight);
mMediaPlayer.start();
}
}
}
HI Biosopher,
i am also interested in this 3gp links ., may you forward me them also.
In this days i am also starting to develop me first tests for streaming and will also try your scripts.
till now i am experimenting with the api demo, but all he 3gp i tested are not opening.
greets
chris
Hi together,
i was able now to create a 3gp that plays nice from local, but not over the net
does anyone have a complete source example just simple streaming 3gp over the net
with http protocol?
thanks
chris
The MediaPlayer streaming example in Android’s ApiDemos provides easy streaming of 3gp. I’ve used the same code by simply pointing to my .3gp file at my server.
hi Biosopher,
thanks, I got now also a “small” 3gp File running with the API DEMO, and also with 2 other option.
But in the moment this 3gp or .mp4 comes bigger, lets say over 2mb, it is not working.
I have now two option working for smaller files.
// Version 1
mVideoView.setVideoURI(Uri.parse(urlpath));
mVideoView.setMediaController(new MediaController(this));
mVideoView.requestFocus();
// Version 2
Intent i = new Intent(Intent.ACTION_VIEW);
Uri u = Uri.parse(urlpath);
i.setDataAndType(u, “video/*”);
startActivity(i);
//for all other beginners: use setDataAndType! I search hours till i found out
But as mentioned, if its bigger, lets say like my testfile: on http://www.guruk.com/3gp/2.mp4
it stops working.
Thats the Reason I tried to work with this Streaming Demo on this Page here.
For now I can get mp3 downloaden and he even starts playing but stops after around 8sec. (i guess in the moment he refresh the buffer its gone)
If you have any idea, let me know. If you send me your email, I also will provide you with all sources I have.
The goal is a streaming functionality, like mentioned on this page for music.. to realize for videos.. also with big files.
(second small question)
When I understand right, the demo above loads piece by piece and appends to the pieces bevore. But so i guess a big file with lets 700 MB (video), will never work with this demo (just because internal memory of the g1)??
Greets
Chris
We have streamed file up to 5MB that were 5 mins long. Check the format of your files. The Android MediaPlayer is very finicky still.
We create our .3gp using Quicktime Pro and have had no problems. However we did have numerous issues creating .3gp files with other audio tools.
Biosopher
Chris,
As you say, this streaming media player is for small files (1-10MB) as anything larger should probably be downloaded via a sync cable.
As a side note, we wrote this tool when Android’s sreaming media functionality was not working well. Now, we simply use Android’s built-in streaming ability.
Anthony
Hii Biosopher,
I am also trying to stream videos from a vlc server using the mediaplayerdemo_video in Apidemos.The file i have been trying to stream is of .3gp format(600 kb). But the problem is that i am not able to stream this file consistently. i mean to say that i can stream the file successfully once or twice but most of the times i get error
as
error: Prepare failed.: status=0xFFFFFFFF
java.io.IOException: Prepare failed.: status=0xFFFFFFFF
I tried to find out the error and solve but all my efforts went in vain.So could u please help me in this matter?
Anyone have working mp3 streaming? use pastebin(google it) and link your code for us.
Thanks
It is giving me exception while calling prepare() method of MediaPlayer. I am using SDK 1.1 is there problem in it. Please mail me what could be wrong in it.
Hi Biosopher,
I was trying MediaPlayerDemo_Video example from API Demos.
Used the URL for different mp4 and 3gp files but the same issue:
I got the following exception-
error: Prepare failed.: status=0xFFFFFFFF
java.io.IOException: Prepare failed.: status=0xFFFFFFFF
If API demos don’t have any issue, Please send me the URLs of some 3gp/mp4 files so that I can enable myself to test the same.
Thanks,
Amit
anthony, hope you don’t mind. i’m going to share this link.
http://www.pocketjourney.com/downloads/pj/video/famous.3gp
Hi Amit,
As amit suggests, this works in API Demo’s MediaPlayerDemo_Video class:
http://www.pocketjourney.com/downloads/pj/video/famous.3gp
Cheers,
Anthony
Hi: I liked your Tutorial3 demo. Thanks. However, I am getting an error after the music starts playing – it seems to come due to the “counter” being wrong, or not set properly, between the downloadingmedia and playing media. In particular, the error shown is:
java.io.FileNotFoundException: / data/data/com.pocketjourney.tutorials/cache/playingMedia2.dat
and seems to come from:
transferBufferToMediaPlayer – line 199 (in my version of your code), where the code is as follows:
——–
File bufferedFile = new File(context.getCacheDir(),”playingMedia” + (counter++) + “.dat”);
//FileUtils.copyFile(downloadingMediaFile,bufferedFile);
mediaPlayer = new MediaPlayer();
//mediaPlayer.setDataSource(bufferedFile.getAbsolutePath());
FileInputStream ins = new FileInputStream(bufferedFile.getAbsolutePath());
mediaPlayer.setDataSource(ins.getFD());
——–
Seems like counter has become 2, when playingMedia2.dat does not exist / is not created. only playingMedia1.dat exists.
No wonder there is a fileNotFound exception.
Any ideas, your help will be appreciated.
Thanks
Bindu Rama Rao
binduramarao@yahoo.com
Hi,
I have tried video streaming using API demo sample. it s working only for the url which is suggested by amit..
for all other url i am getting the following error.
error: Prepare failed.: status=0xFFFFFFFF
java.io.IOException: Prepare failed.: status=0xFFFFFFFF
can anyone provide me some other url of 3gp video format..?
thanks,
Senthil.M
Hi,
Can anyone tell me how to resolve the follwing error while implementing video streaming.
error: Prepare failed.: status=0xFFFFFFFF
java.io.IOException: Prepare failed.: status=0xFFFFFFFF
i am getting this error when mediaplayer.prepare(); is called.
thanks,
Senthil.M
Hi msenthil,
Your files are most likely not compatible with Android.
Android has issues with most file formats. I’ve only been able to get .3gp to work successfully. Even then, only files created using Quicktime Pro have worked for me.
E.g. this file was created using Quicktime Pro:
http://www.pocketjourney.com/downloads/pj/video/famous.3gp
If the file above works but your other ones don’t, then you need to fix the format of your file.
Anthony
Hi Anthony,
Thanks for your reply. I understood that the problem is with the URL which i tried. When i try to play that url, i got a message “Sorry ,this video is not valid for streaming to this device”
thanks,
Senthil.M
Hi friends,
Can anyone temme how to change the colour of the stars in rating bar in android.
I am getting the stars in green colour when we rate them.
But i need to change them as some other colour when we rate.
Is it possible..?
thanks ,
Senthil
Hi Senthil,
I’m not doing Android dev at the moment so my info may be slightly out of date, but here’s what I know:
A RatingBar is an extension of SeekBar and ProgressBar that shows a rating in stars.
The XML format for updating the ProgressBar was a combination of this:
Where ’shape_media_segment_rating_bar’ was defined as such:
More info here:
http://developer.android.com/reference/android/widget/RatingBar.html
These pages offer info on changing the ProgressBar style though not the RatingBar stars (hope it helps):
http://groups.google.com/group/android-developers/browse_thread/thread/147e60581e7626b3
http://www.anddev.org/seekbar_progressbar_customizing-t6083.html
Cheers,
Anthony
hi.. i’ve been studying your code and the tutorial and i found some inconsistencies between the two.. plus when i run the emulator using either from the downloaded code and the code from the tutorial, adb logcat gives me an error about media player prepare failed.. can you help me?
Hi,
Can anyone tell me how to stream live videos on android emulator?
Kindly help as this is very urgent!!!
REgards,
Aahan
Hi,
Can anyone tell me how to stream live videos on android emulator?
Kindly help as this is very urgent!!! Mail me available info or your knowledge on this requirement on chiragpayal@gmail.com
REgards,
Aahna
Hi Aahna,
Use the MediaPlayerDemo_Video example in Android’s APIDemo. Simply set the example’s ‘path’ argument to the url of your video file. I highly recommend getting your file to load from the local directory first so you can ensure your media file is in a valid format.
Cheers,
Anthony
Hi Anthony,
Thanks for your reply. However I am able to play only only pocketjourney link given on this webpage by Amit which ofcourse is not live link.
I tried to put some http links from some live news channel weblinks but all the times emulator shows error message, “Sorry, this video can not be played”.
I am using windows Vista system and android 1.5 with ADT 0.9 version and testing on APIDemo, MediaPlayerDemo_Video example only.
If possible, can you send me some live video weblinks which plays successfully on emulator by streaming online video?
REgards,
Aahna
Android does not handle media files very well. They MUST be in one of the few supported formats. E.g. this URL points to a media file that was encoded properly for the .3gp format using QuickTime:
http://www.pocketjourney.com/downloads/pj/video/famous.3gp
I highly recommend using QuickTime to format your media files. Ensure you test any media format by playing through Android off the local drive before trying to play those files off the net.
I don’t know of any specific ‘live’ URLs that play well through Android.
Anthony
Dear Anthony,
Thanks for your quick response. However, I am not able to find any online .3GP links. All 3gp/mp4 videos are found on .html URL link only
It would be great if you can elaborate more on encoding part. As far as I know we can use quicktime or VLC player and stream/encode to any other format. However, I am not able to choose particular .3GP or .MP4 video links for this job.
Can you or anyone else help me?
Regards,
Aahna
Hi Aahna,
If you are streaming other people’s media files (i.e. you can’t encode them to .3gp/.mp4 yourself), then you’ll need to parse through that sites .html to find the media file links to pass to Android.
What website’s media files are you trying to stream to Android?
Anthony
Dear Anthony – Thanks for all!
I am developing an app requiring “streaming” (PD…) and this post is the only place on the web I found the solution.
I am using QuickTimePro for images I have downloaded from YouTube (With the uploader permission…) and it’s working great!
Thanks!!!
Hi Anthony,
Can you explain me your reply with easy to understand steps to meet my requirement?
” Anthony — If you are streaming other people’s media files (i.e. you can’t encode them to .3gp/.mp4 yourself), then you’ll need to parse through that sites .html to find the media file links to pass to Android.”
I am interested in streaming and getting played some live videos on android emulator 1.5 for example,
http://www.ndtv.com/news/videos/video_live.php?id=LIVE_BG24×7
So, how should I achieve this successfully? Your procedural response would help many developers like me as there is no clear response to this question on any forum.
Let me know wihtout RTSP support on emulator 1.5, would this be possible to stream live news/sport videos?
Regards,
Aahna
Hi YuvalKesten,
You have mentioned that you are using quickTimePro for images downloaded from youTube. Can you tell me what are the exact steps you are performing to get streamed videos?
I tried using VLC network stream to get some URL link as an input and putting encoded streamed out HTTP/UDP packets on my own system and then redirecting packets from desktop to emulator’s IP. But it failed
Because of this, I am not able to play any other .3gp video link except that pocketjourney link.
Your or anybody’s reply on this would be great help.
Thanks,
Aahna
Hi Aahna,
I’m streaming my own videos accessible from my own server. Streaming other people’s videos is typically against their usage agreement. If you have authorization though, then someone on their IT team can help you access the videos.
If you want to stream videos from another site though, you would need to parse through their HTML & Javascript to find their video file links. Nowadays though, most companies encode their video links so you wouldn’t be able to access them even if you tried.
I don’t know the answer to your RTSP question.
Anthony
Hi Anthony,
Thanks for the explanation. I would have to find such sites for getting live streaming. Kindly keep me updated if you find any such site who can authorize us to get their live videos streamed.
Can you answer me the above question I have put to YuvalKesten?
Putting it othe way, would like to ask how you are achieving formatting the video through quick time and getting it played on emulator? Is the procedue I have mentioned above is correct?
Because with my encoded packets I am able to playback on another instance of VLC (in your case might be quicktime) but those are not getting redirected to emulator.
How to achieve that?
Regards,
Aahna
Hi Anthony,
I just have a question about your tutorial3. I tried to play an online radio (with this URL for example http://scfire-ntc-aa03.stream.aol.com:80/stream/1003) and it’s not working. Is your tutorial working only for mp3s ? In that case, isn’t it possible to listen streaming music coming from an streaming radio ?
Thanks.
Nicolas
Hi Nicolas,
The answer to your question has been discussed many times in other posts for this tutorial.
In short, Android does not handle media files very well. They MUST be in one of the few supported formats. E.g. this URL points to a media file that was encoded properly for the .3gp format using QuickTime:
http://www.pocketjourney.com/downloads/pj/video/famous.3gp
I highly recommend using QuickTime to format your media files. Ensure you test any media format by playing through Android off the local drive (using the API Demo example) before trying to play those files off the net.
In your case, download the file from AOL and ensure that Android can play their specific format.
Anthony
Hi Anthony,
I’m sorry if I haven’t been really clear but I was talking about audio and not video. I tried MP3 and OGG web radios but not working. Android can handle these both formats for one file right ? So it shouldn’t be impossible to read the same formats from a stream ?
Thanks again for your time
Nicolas
Hi Nicolas,
Why aren’t you just streaming using Android’s built-in streaming capability? All you need do is put a URL as the path for the MediaPlayer example in ApiDemo.
Doesn’t that work for you?
Anthony
Hi Aahna,
Two answers:
1) Go here for video files you can stream. They have numerous files you can download:
http://mediaplayer.group.cam.ac.uk/component/option,com_mediadb/itemid,26
2) It’s very easy to create a streamable .3gp file using QuickTime Pro. Simply open your video in QuickTime Pro and then choose ‘Export’ and select .3gp.
Anthony
Hi Anthony,
Thank you very much for your support so far. I hardly seen anyone helping developers like this!!! You are really great having lot of patience and clarity on your inputs.
Adding another requirement to my application, I need to let user enter some URL video link to play the streamable video. If this URL lists the available video items then how to decide at run time whether android can play selected video on emulator
Also I am not using Linux. I am using windows vista, android 1.5, ADT 0.9.
Regards,
Aahna
Hi,
I am working on an Android project as part of a university project. I am working with some film-makers from the Arts faculty.
What we are doing is – they are uploading their movies to youtube, I am downloading them, convert them using QucikTimePro (Export to IPhone(Cell)) and then I upload the converted videos to a file server.
Hope I helped…
Hi Nicolas,
Yes…this tutorial only works with MP3 files. Radio and other audio streaming sites are not typically streaming mp3 files as their feeds are continuous while mp3 files are discreet chunks (with headers and footers in the file describing start and end information).
Anthony
Hi. I’m developing an application that can stream from internet radio stations. Can you help me out? THanks
Hi Ivy,
Sadly my code doesn’t work for internet radio stations as they don’t typically use streams compatible with Android’s media player (that I know of).
Cheers,
Anthony
Hi Anthony,
Can we able to encode the video file url through code to make it to support streaming in android…?
thanks,
Senthil
Hi Senthil,
You definitely couldn’t convert streaming video in the wrong format to the correct format. You’d have to download the entire file and then convert it. Of course, you would then need access to Java code that could convert whatever format the server is providing into a format that Android accepts (e.g. .3gp). Most likely it would be impossible or a LOT of work though.
Anthony
Hi,
is this player also able to play aac streams ?
Hi Anthony,
Thanks for the reply. Can we have any other way of converting the video file to streaming format other than QuicktimePro..?
thanks ,
Senthil.M
Hi Tiger,
This tutorial uses Android’s MediaPlayer so it would work with any format supported by Android.
Anthony
Hi Senthil,
I’m sure there are but I found that Quicktime Pro worked and stooped looking after that.
Anthony
Hi Anthony,
Actually for my application, i am getting the video urls dynamically from the server.. and those video files are not supported for streaming in android device. I need to convert those urls to proper format so that it supports streaming in android. currently i am downloading the entire video in SD card and playing it. but i don want the user to wait until the entire video is getting downloaded. I don think that quicktimepro is helpful for my case. Also i am searching for any java code available for video streaming. if i get any information, it ll be very helpful.
thanks,
Senthil.M
Hi Anthony,
Can you please tell me whether quicktimepro will help for the above scenario i mentioned or any other way if you found for streaming, please post here.
thanks,
Senthil.M
Converting video ‘on the fly’ is not possible from what I know…or at least too difficult to attempt unless you’re a media format guru. Your current approach is the only solution…though not very usable as you say.
Anthony
Hi,
I have been looking osmewhat in the code and I noticed that the call to startStreaming actually needs a file length and the duration… Let’s say that I’d like to stream an infinite file, a real stream… Has that been implemented, so could I pass like for example a -1 as argument for both ?
Hi Tiger,
You could easily implement that update. The file length is only really used for displaying the playback progress. E.g. 1:01 mins played of 5:00 total mins.
Thanks for your reply Anthony..
Senthil.M
why dont you use audiotrack??? there you can easily write data to it, while its playing…
Thanks for pointing us to AudioTrack, theluk. That class wasn’t available when I wrote this tutorial. It won’t help Senthil’s audio format translation but might provide a useful extension to this tutorial’s solution.
Sadly as with most of Android’s code, there’s very little in the way of documentation. Here’s a brief from a post by Ed Burnette:
AudioTrack and AudioRecord are interesting to low level audio developers:
* Expose raw PCM audio streams to applications
* AudioTrack: Write PCM audio directly to mixer engine
* AudioRecord: Read PCM audio directly from mic
* Callback mechanism for threaded application
* Static buffer for playing sound effects
Full post: http://blogs.zdnet.com/Burnette/?p=1133
Anthony
hi friends
i have been working on a problem called out of memory exception.
i am getting this exception in my application when i spawn more number of threads.
i am using
System.gc();
runtime.gc();
in onDestroy method. Still i am getting this exception..
Can anyone knows the solution for this problem…?
thanks,
Uma Maheswara Rao
Anthony,
Thanks for your blog post and code. I came across it only after writing something very similar. Glad to see I (mostly) had it right!
Jason
Hi Anthony,
I have one more question regarding the videos. Actually i am calling an intent after the video is getting played completely by using setoncompletionlistener method. When i try to play video in media player of android, for some videos it is not calling the setoncompletionlistener method when the video is finished. Simply video playing time (displayed on the left side of media player)is getting increased infinitely even after the whole playing time (displayed on the right side of media player) of video. I dont know the reason why it is happening like that.. This scenario is occurring especially when we drag the video fully.
regards,
Senthil.M
Hi Senthil,
Sounds like a possible bug. I’d try posting in the Android dev group to see if a Google/Android lead knows a solution or if it’s a bug.
Anthony
Hi Anthony,
Thanks for the reply. If you found any solution for this problem, please post the information here so that it will be helpful for everyone.
thanks,
Senthil.M
Hi Biosopher,
thanks for the tutorial!
I try the code to run on the HTC G1, but ist seemed something wrong.
private void fireDataPreloadComplete() {
Runnable updater = new Runnable() {
public void run() {
mediaPlayer.start();//never be called
startPlayProgressUpdater();
playButton.setEnabled(true);
// streamButton.setEnabled(false);
}
};
handler.post(updater);
}
the line “mediaPlayer.start()” is apparently never be called, so i can hear nothing.
Do u have some ideas?
thanks
T.B
Hi alwaystry,
Sadly I’m not developing on Android at the moment. Probably a threading issue or your not preparing the MediaPlayer properly.
The code worked in prior versions so perhaps the newest release broke the code.
Anthony
Hi Anthony,
First of all, Thanks a ton for the tutorial.
I downloaded the tutorial and created a new project with the same files.
I compiled the project and was able to run it without any errors. I used the URL provided in the example.
Also, in the emulator I could see the buffering taking place. However, No sound is coming .
I am using Windows vista and Android SDK 1.5 with Eclipse.
I think, when i call mediaplayer.prepare () , it throws an exception – ‘ Error Not Supported’.
I also tried with Local files. it worked.. So does it mean the file format in the URL ( provided in the example ) is not supported..?
If yes .. how to go about it .. please explain.. I am new to Android..
Kindly help me out with this ASAP.
Thanks again,
yen
I checked it out. On atleast Android 1.5 mediaplayer won’t play a file that still has an open FileOutputStream connected to it.
If you close the FileOutputStream first, then is will prepare and play.
At least that is my experience.
But good tutorial as a guideline how the whole thing works.
By the way, here is my code where I used Biosopher’s code and modified it to support a continuous stream of audio instead of a file. It downloads X number of seconds and save that audio segment. Then it starts playing that audio clip while it downloads the next sections of audio in the background. Then queuing up the audio segments for playing next.
It is not perfect though.
I get a slight playback pause between audio segments though. Hopefully I will prefect it or find another way around.
http://code.google.com/p/mynpr/source/browse/trunk/mynpr/src/com/webeclubbin/mynpr/StreamingMediaPlayer.java?spec=svn9&r=9
This is great, CatDaaaady. Thanks for sharing!
I am getting this error… http://screencast.com/t/YTI3ZDA4YTIt any help
hi,
Wen i try to run dis tutorial i get the following error….
Can u please tell me how do I correct it. Thanks.
E/Player ( 5300): /data/data/com.example.streaming/cache/playingMedia1.dat
E/PlayerDriver( 36): Command PLAYER_SET_DATA_SOURCE completed with an error or
info PVMFErrNotSupported
E/MediaPlayer( 5300): error (1, -4)
E/com.example.media.StreamingMediaPlayer( 5300): Error initializing the MediaPla
er.
E/com.example.media.StreamingMediaPlayer( 5300): java.io.IOException: Prepare fa
iled.: status=0×1
E/com.example.media.StreamingMediaPlayer( 5300): at android.media.MediaPl
ayer.prepare(Native Method)
E/com.example.media.StreamingMediaPlayer( 5300): at com.example.media.Str
eamingMediaPlayer.startMediaPlayer(StreamingMediaPlayer.java:189)
E/com.example.media.StreamingMediaPlayer( 5300): at com.example.media.Str
eamingMediaPlayer.access$2(StreamingMediaPlayer.java:177)
E/com.example.media.StreamingMediaPlayer( 5300): at com.example.media.Str
eamingMediaPlayer$2.run(StreamingMediaPlayer.java:153)
E/com.example.media.StreamingMediaPlayer( 5300): at android.os.Handler.ha
ndleCallback(Handler.java:587)
E/com.example.media.StreamingMediaPlayer( 5300): at android.os.Handler.di
spatchMessage(Handler.java:92)
E/com.example.media.StreamingMediaPlayer( 5300): at android.os.Looper.loo
p(Looper.java:123)
E/com.example.media.StreamingMediaPlayer( 5300): at android.app.ActivityT
hread.main(ActivityThread.java:3948)
E/com.example.media.StreamingMediaPlayer( 5300): at java.lang.reflect.Met
hod.invokeNative(Native Method)
E/com.example.media.StreamingMediaPlayer( 5300): at java.lang.reflect.Met
hod.invoke(Method.java:521)
E/com.example.media.StreamingMediaPlayer( 5300): at com.android.internal.
os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782)
E/com.example.media.StreamingMediaPlayer( 5300): at com.android.internal.
os.ZygoteInit.main(ZygoteInit.java:540)
E/com.example.media.StreamingMediaPlayer( 5300): at dalvik.system.NativeS
tart.main(Native Method)
D/Sensors ( 58): sensors=00000000, real=00000000
D/KeyguardViewMediator( 58): screen is locked
W/ActivityManager( 58): Unable to start service Intent { action=android.accoun
ts.IAccountsService comp={com.google.android.googleapps/com.google.android.googl
eapps.GoogleLoginService} }: not found
hi,
when i run the tutorial, there’s not voice,
and the LogCat appear continuously the message:
“12-26 13:02:25.844: ERROR/MediaPlayer(742): Attempt to call getDuration without a valid mediaplayer”
and
“12-26 13:02:25.905: ERROR/MediaPlayer(742): Error (-38,0)”,
i don’t know how to solve the problem, do yo know the reason?
thanks
Hi,
I finally got around to updating my Android MediaPlayer streaming media tutorial Cupcake (v1.5). I last worked on this code nearly 18 months (for v1.0) so I had to update everything.
I’ll be posting an updated tutorial in a few days. In the meantime if you need the code, please post here and I’ll send it to you.
Cheers,
Anthony
Hi,
Thanks a lot, the v1.5 code works! And no error occur!
thanks again
Monkey
Great to hear. Thanks for letting me know.
Anthony
Well I’d be happy to receive the code so I can have a look at it and (obviously) test it on a device
The updated tutorials are avialable in these two new posts:
Streaming Media: http://blog.pocketjourney.com/2009/12/27/android-map-tutorials-updated-to-v1-5-cupcake-mapview-mapactivity Maps: http://blog.pocketjourney.com/2009/12/27/android-streaming-mediaplayer-tutorial-updated-to-v1-5-cupcake
Cheers, Anthony
The updated tutorials are avialable in these two new posts:
Streaming Media: http://blog.pocketjourney.com/2009/12/27/android-map-tutorials-updated-to-v1-5-cupcake-mapview-mapactivity/
Maps: http://blog.pocketjourney.com/2009/12/27/android-streaming-mediaplayer-tutorial-updated-to-v1-5-cupcake/
Cheers,
Anthony
Hi Anthony,
I have an issue regarding video play in android 2.0.1 emulator. When i try to play a video in android 2.0.1 emulator, i am getting a white screen in the view. But audio is working fine, also getting the following error message in the logcat,
ERROR/SurfaceFlinger(64): layer 0×3f8528, texture=2, using format 32, which is not supported by the GL
The error mentioned above keeps on repeating in
the logcat till the end of the video.
The same video is played without any errors in android 2.0 and previous version emulators. I am not sure about the android 2.0.1 devices. I am getting the above problem even in Apidemo video sample program. Is there any way to resolve this issue or is it an android 2.0.1 bug ? Any help appreciated.
thanks in advance,
Senthil.M
Hi Senthil,
Most likely this is a problem with your video file. Can you play this video file in a pre-2.0.1 version?
I found .3gpp to work well and most other formats to have problems. What format are you using?
Thanks for your reply Anthony. I am getting above problem only in android 2.0.1 emulator. It is working fine in all other previous versions. My video file is .3gp format only. I have checked the Apidemo video sample with the following url too.
http://www.pocketjourney.com/downloads/pj/video/famous.3gp
With this url also, it is not working in 2.0.1 version emulator.
thanks,
Senthil.M
What error messages are you seeing?
I am getting the following error message in logcat
ERROR/SurfaceFlinger(64): layer 0×3f8528, texture=2, using format 32, which is not supported by the GL
And this message is repeated till the end of the video play. Simply getting a white screen in the view. But audio is working fine. I found some links related to this issue posted by some people. I am attaching those links here below.
http://groups.google.com/group/android-developers/browse_thread/thread/9081b2f56654ec7/5c8ccb3fb06dd4e4#5c8ccb3fb06dd4e4
http://stackoverflow.com/questions/1855246/android-videoview-video-not-seen/1973723#1973723
Also i have posted this issue in android bug tracker site which can be referred here.
http://code.google.com/p/android/issues/detail?id=5696#makechanges
thanks,
Senthil
Regarding the video display issues – I have had similar problems. This is what I did and it fixed the issues.
1. Create an MP4 or 3GP file. Does not matter really. Up to you. There are plenty of utilities for doing this. One of the coolest is http://mediaconverter.org/ Place your newly created file on your hard drive.
2. Download MP4Box for Windows. Just do a search and download the command line MP4Box utility. This utility, among many other things it does, will add the appropriate headers to allow for progressive download. Do not run the executable from Windows. Place all of the contents in a folder and open a DOS session.
3. Place your video file in the MP4Box folder. From your DOS session type MP4Box yourvideofilename -hint
4. Upload your video to the server of choice.
Also, you will get format errors from MediaPlayer even if it cannot find the URL. I spent hours trying to figure this out when I discovered that the XML I was reading to get my URL path included quotes.
Hi Senthil,
Are you using the updated code that I released in my revised Streaming Media Tutorial?
http://blog.pocketjourney.com/2009/12/27/android-streaming-mediaplayer-tutorial-updated-to-v1-5-cupcake/
Also, did Tmac’s recommendations help solve your problem?
I found another way to do a similar thing but easier using AsyncPlayer (http://developer.android.com/reference/android/media/AsyncPlayer.html)
Here’s a short example:
protected void PlaySound(LocationEntry locEntry) {
Uri url = Uri.parse(“http://www.pocketjourney.com/downloads/pj/tutorials/audio.mp3″);
AsyncPlayer player = new AsyncPlayer(“test”);
player.stop();
player.play(this.context, url, false, AudioManager.STREAM_SYSTEM);
}
Hi Anthony,
great tutorials . but I am wondering how can I save that file to sqlite database or file system please suggest me ,if I go through the source code I can see commented line
//FileUtils.copyFile(downloadingMediaFile,bufferedFile);
if I un-comment is it going to work ……downloadingMediaFile contain every thing ?
Hi Riz,
FUtils refers to code that does not exist so simply delete that commented line.
The downloaded file is currently being copied to the file system. You can choose to capture the data and save it as a blob to a sqllite db, but the ‘lite’ db or really any db isn’t built for storing files. You should save to the file system and simply store the file path in the db.
Thanks CatDaaaady,,
But still there is gap in between switching over of files
What will be the workaround for that????
Please tell me solution.
Thanks
Kavitha
Hi Kavitha,
I just tested the streaming tutorial and don’t hear any gaps in the downloaded audio.
Anthony
I actually hear it in my app. In my app I am saving pieces of a live, continuous, stream and playing them one by one.
It is VERY subtle. But I know the gap is there. None of my users have complained about it yet though. So I assume maybe it is only for people with sensitive ears.
My plan to getting around it is to implement some type of live stream-to-rtp converter. So the program will download a portion of audio, put it into a RTP packet, then send that off to the audio player.
I “think” this is how other apps are doing it. I haven’t had time to do this just yet. I noticed some links on this page that mention RTP. Maybe they point the way even though it is for video? I think sometime next month, after I add a different feature to my app, I will tackle this rtp thing. I will report back.
Hi CatDaaaady and Biosopher,
Thanks for the replies.
Using catDaaady’s player idea,I am able to play continously an Internet Radio.
But when i change the Internet Radio link url,file is getting downloaded,but i am not able to play once again,,MediaPlayers hang up without even showing error.
I am calling player(File f) from another thread and pause it when user clicks on another url,clear mediaplayers vector in clear() ,,and again start thread when file gets downloaded.
Please tell me the solution.
Here is what I am doing when i change url
public void player(File ff){
final File f = ff;
final String TAG = “**************************************setupplayer*****:”;
Log.i(TAG, “File ” + f.getAbsolutePath());
// Runnable r = new Runnable(){
// public void run(){
try{
MediaPlayer mp=new MediaPlayer();
try{
FileInputStream ins = new FileInputStream( f );
mp.setDataSource(ins.getFD());
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setOnCompletionListener(playerlistener);
if ( ! started ){
mp.prepare();
} else {
//This will save us a few more seconds
mp.prepareAsync();
}
insertMedia(mp);
if ( ! started ){
startMediaPlayer();
}
}catch(Exception e){
Log.e(TAG, “:ERROR********:”+e.toString());
e.printStackTrace();
}
}catch(Exception e){
System.out.println(“********************ERROR IN PLAYER “+e);
e.printStackTrace();
}
// }
// };
// new Thread(r).start();
}
MediaPlayer.OnCompletionListener playerlistener = new MediaPlayer.OnCompletionListener () {
public void onCompletion(MediaPlayer mp){
onMediaPlayerCompletePlay(mp);
}
};
private void onMediaPlayerCompletePlay(MediaPlayer mp){
String TAG = “MediaPlayer.OnCompletionListener”;
Log.i(TAG, “Current size of mediaplayer list: ” + mediaplayers.size() );
MediaPlayer mp2 = getMedia();
if(mp2 != null)
mp2.start();
mp.release();
removefile();
}
public void insertMedia(MediaPlayer file){
///add file at last of vector
try{
mediaplayers.add(file);
available = true;
}catch(Exception e){
System.out.println(“EXCEPTION IN INSERTMEDIA”+e);
e.printStackTrace();
}
}
public MediaPlayer getMedia(){
try{
if(mediaplayers.size()<1){
available=false;
}
if(!available){
return null;
}
mediaplayers.remove(0);;
if(mediaplayers.size()<1){
return null;
}
}catch(Exception e){
System.out.println("EXCEPTION IN GETMEDIA"+e);
e.printStackTrace();
}
return mediaplayers.firstElement();
}
private void removefile (){
String TAG = "removefile ***:";
try{
File temp = new File(context.getCacheDir(),DOWNFILE + playedcounter);
Log.i(TAG, temp.getAbsolutePath());
temp.delete();
synchronized(this){
playedcounter++;
}
}catch(Exception e){
System.out.println("EXCEPTION IN REMOVEFILE"+e);
e.printStackTrace();
}
}
//Start first audio clip
private void startMediaPlayer() {
String TAG = "startMediaPlayer***:";
try{
//Grab out first media player
synchronized(this){
started = true;
MediaPlayer mp = mediaplayers.get(0);
mp.start();
}
}catch(Exception e){
System.out.println("EXCEPTION IN STARTMEDIAPLAYER"+e);
e.printStackTrace();
}
}
public void clear(){
String TAG = "CLEAR URL STREAMPLAYER***:";
try{
synchronized(this){
playedcounter = 1;
started = false;
available=false;
for(int i=0;i<mediaplayers.size();i++){
MediaPlayer mp=mediaplayers.get(i);
if(mp != null){
if( mp.isPlaying())
mp.pause();
mp.reset();
mp.release();
}
}
mediaplayers.removeAllElements();
}
}catch(Exception e){
Log.i(TAG, "ERROR CLEARING MEADIA PLAYERS : " + mediaplayers.size() );
e.printStackTrace();
}
I am not so sure on that one.
But maybe in your clear() try
mp.stop();
mp.release();
Instead of
mp.pause();
mp.reset();
mp.release();
It could be the mediaplayer resources are not getting released properly?
Thanks for the reply catdaaady.
I tried with mp.stop() and mp.release().
Still it is same.
Any other alternatives????
or else do you have any idea of converting audio to PCM and playing from AudioTrack class of Android?
HI
kavitha
you will try mp.reset();
and you must interrupt to buffer loading