i am using the MediaPlayer class to loop music from youtube. So far no problem, but the MediaPlayer downloads the video every playback again from youtube, which causes a lot of traffic. Is there a way to let the video in the buffer of the MediaPlayer?
I'm using the following code:
try {
MediaPlayer mp = new MediaPlayer();
mp.setDataSource("http://r6---sn-4g57knsy.googlevideo.com/videoplayback?itag=18&key=yt5&ip=123.45.67.89&ipbits=0&ratebypass=yes&ms=au&source=youtube&sver=3&mt=1383664037&id=3fa390e8443132e0&expire=1383690428&sparams=gcr%2Cid%2Cip%2Cipbits%2Citag%2Cratebypass%2Csource%2Cupn%2Cexpire&fexp=935610%2C932206%2C916807%2C941242%2C916623%2C924616%2C907231%2C907240&mv=m&gcr=de&upn=9y98yq_WFEc&signature=98E548B5E368061D425FED483828E6D5AF1BBC2B.8AB359B7BA604F108D85578BC704844308E9B6EB");
mp.setLooping(true);
mp.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
mp.prepare();
} catch (Exception e) {
e.printStackTrace();
}
Thanks.
Short answer: no.
Long answer: write a simple proxy server to run on the device and cache it yourself. It's not incredibly hard, but it requires some thought to pull off seemlessly.
Related
I'm trying to play a .wav audio in Android from assets folder.
The problem is that there is no error but the audio isn't playing.
Here's my code
AssetFileDescriptor afd = null;
try {
afd = getAssets().openFd("success.wav");
player = new MediaPlayer();
player.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
player.setLooping(false);
player.prepare();
player.start();
} catch (IOException e) {
e.printStackTrace();
}
Your code is ok, i checked, its working.
Please ensure the \assets folder is placed
correctly(\app\src\main\assets)
Check your device volume level.
Play success.wav in PC media player and ensure it is audible.
Note:
Using device volume controls:
setVolumeControlStream(AudioManager.STREAM_MUSIC);
If your app is media related, use setVolumeControlStream API at your onResume() of activity or fragment and use device volume hard keys to increase/decrease volume. This set the application to only modify stream_music volume /media volume, otherwise it will modifiy ring volume.
Ref:https://developer.android.com/guide/topics/media-apps/volume-and-earphones
Did You try this?
MediaPlayer mediaPlayer = null;
public void playSound(final Context context, final String fileName) {
mediaPlayer = new MediaPlayer();
try {
AssetFileDescriptor afd = context.getAssets().openFd(fileName);
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
mediaPlayer.prepare();
} catch (final Exception e) {
e.printStackTrace();
}
mediaPlayer.start();
}
}
I am using the mediaplayer feature on Android. I basically have songs in the raw folder and I would just like to change to a new track but it fails. One music file plays and then I press a button after or during the music playing to skip to a random track but it fails.
Current code
mediaplayer.stop();
try {
mediaplayer.prepareAysn();
mediaPlayer.selectTrack(randomtrack_num - 1);
}
catch(Exception e){}
mediaplayer.start();
The error that I receive:
MediaPlayer: start called in state 64
MediaPlayer: error (-38, 0)
MediaPlayer: Error (-38,0)
I tried this without mediaplayer.stop() and still included mediaplayer.start() at the end and it would just replay the same track again.
Am I missing something?
Please let me know.
2nd Approach
After reading the document I realized this can only be done in the prepared state which I assume in my second approach it should work but it is not.
mediaPlayer.stop();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mp) {
try{
mp.selectTrack(randomtrack_num - 1);
}catch(Exception e){}
mp.start();
}
});
mediaPlayer.prepareAsync();
I get this error:/MediaPlayer: Should have subtitle controller already set
Basically the same track plays again and it does not go to the selected track.
You are calling mediaplayer.start() in wrong state. Firstly read this documentation:
https://developer.android.com/reference/android/media/MediaPlayer.html
You will have a better idea of correct implementation.
EDITED:
String[] url ; // initiliaze your URL array here
MediaPlayer myMediaPlayer = new MediaPlayer();
myMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
myMediaPlayer.setDataSource(url[0]);
myMediaPlayer.prepareAsync(); // might take long! (for buffering, etc)
} catch (IOException e) {
Toast.makeText(this, "mp3 not found", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
//mp3 will be started after completion of preparing...
myMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer player) {
player.start();
}
});
Playing different track after completions
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp)
{
myMediaPlayer.reset();
/* load the new source */
myMediaPlayer.setDataSource(url[position]);//select the path according to your need
/* Prepare the mediaplayer */
myMediaPlayer.prepareAsync();
}
I have tried to play many audio (mp3) files through MediaPlayer's setAudioStreamType(AudioManager.STREAM_VOICE_CALL); but mp.start(); does not play nor does it throw an exception.
The setup works with SoundPool but it is limited to like 5 seconds, some files playing upto 8 seconds.
I am attaching the part of code here:
String s = absolutepath.get(position);
Uri u = Uri.parse(s);
playing = (MediaPlayer) MediaPlayer.create(MainActivity.this, u);
playing.setOnPreparedListener(this);
onPrepared includes this:
#Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
spProgress.cancel();
mp.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
try {
mp.start();
} catch (IllegalStateException e) {
Toast.makeText(this, "exception", Toast.LENGTH_SHORT).show();
}
}
I have tried this without the try/catch and even without listener. The only time it plays is when I don't use the stream type STREAM_VOICE_CALL.
The same files can be played with SoundPool:
SoundPool sp = new SoundPool(1, AudioManager.STREAM_VOICE_CALL, 0);
sp.load(s, 1);
sp.setOnLoadCompleteListener(this);
Listener:
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
// TODO Auto-generated method stub
if (status == 0) {
spProgress.cancel();
sp.play(sampleId, 1, 1, 1, 0, 1);
} else {
Toast.makeText(this, "failed to load", Toast.LENGTH_SHORT).show();
}
}
I actually had the same problem, and Google's Guide is very bad here - it's indeed a bit tricky, but simple to explain:
As you need to change the STREAM, and then prepare() your MediaPlayer again, you'll get it working by doing this:
Resources res = getResources();
AssetFileDescriptor afd = res.openRawResourceFd(R.raw.tts_a);
mp = new MediaPlayer();
//mp.reset();
mp.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
mp.setLooping(false);
try {
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mp.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mp.start();
The actual trick is to NOT use the MediaPlayer.create, as it's calling the prepare itself! Therefore you're not able to set the Stream. By setting the File with AssetFileDescriptor, you can set the Stream and call your prepare() afterwards!
I'm a Beginner in android programming and I want to programming mp3 app to call some mp3 files from URL, so when I show "Media Player" in android developer I put the URL in the setDataSource and it's work fine, but the problem is the Activity take a lot of time to display it and in the sometimes app will be crashed. This is the part of my code :
file_url = Mp3_Linkes[num];
//Set Source
try {
mp.setDataSource(file_url);
} catch (Exception e) {
Toast.makeText(this, "Source Error !!", Toast.LENGTH_LONG).show();
}
//Prepare
try {
mp.prepare();
}catch(Exception e)
{
Toast.makeText(this, "Prepare Error !!", Toast.LENGTH_LONG).show();
}
//Start
mp.start();
Your activity is blocking because you are calling prepare on your Main Thread (UI thread)
Instead You can use prepareAsynch and OnPreparedListener to start specially when loading from remote source:
code :
try {
mp.setDataSource(file_url);
mp.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer player) {
player.start();
}
});
mp.prepareAsync();
I am trying to make music play in my app and have a song play after the first one has finished but i get some errors that i cannot resolve any help?
public class Music {
int count;
String[] titles = new String[] { "title1.mp3", "title2.mp3", "title3.mp3", "title4.mp3" };
public void GameMusic(){
count = 0;
MediaPlayer mp = MediaPlayer.create(this, R.raw.title1);
mp.start();
}
void onCompletion(MediaPlayer mp){
mp.stop();
if (count == titles.length -1) {
count = 0;
}
mp.setDataSource(titles[count]);
count++;
mp.prepare();
mp.start();
}
}
The errors are on:
MediaPlayer mp = MediaPlayer.create(this, R.raw.music);
(The method create(Context, int) in the type MediaPlayer is not applicable for the arguments (Music, int)
mp.setDataSource(titles[count]);
(Unhandled exception type IOException)
mp.prepare();
(Unhandled exception type IOException)
Any help would be appreciated.
Well the errors might be a little cryptic but they are self-explanatory.
You need to pass a Context to GameMusic() and use it to initialize MediaPlayer:
public void GameMusic(Context context){
count = 0;
MediaPlayer mp = MediaPlayer.create(context, R.raw.title1);
mp.start();
}
this only works if the class (in this case Music) extends Context, so you need to provide a Context another way.
And in onCompletion() use a try-catch block to handle the IOException:
try {
mp.setDataSource(titles[count]);
count++;
mp.prepare();
mp.start();
}
catch(IOException e) {
// Do something when MediaPlayer fails
}
Your Music Class is just a class and not an activity and hence the this passes an object and not a context. If this is your only music player class then you need it to extend Activity else you need to pass a context to it.
public void GameMusic(Context context){
count = 0;
MediaPlayer mp = MediaPlayer.create(context, R.raw.title1);
mp.start();
}
And for the other two exceptions, it states that the exceptions are unhandled. so you need to use a Try-Catch block the handle the uncaught IOException.
That should solve all the errors that you are getting now.
when setting the datasource to Mediaplayer try to use absolutepath of the music file
if it is stored in sd-card means ..try this
String ExternalStorageDirectoryPath = Environment.getExternalStorageDirectory()
.getAbsolutePath();
mp.setDataSource(ExternalStorageDirectoryPath +"/"+titles[count]);
after calling the
mp.prepare();
implement the onpreparedlistner ,after get the notification for this then start the mediaplayer
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
and handle the all kind of exception, so that u can easily track the issues.