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();
}
}
Related
I have a class that plays audio files located in some folders...Problem is i cant manage to use only one instance of the Media Player to play multiple audio files. Every time i attempt to play a different song, a new instance of the Media Class is created and the new song plays in parallel with the previous one which is really annoying...Can anyone help me use only one instance of the Media Payer to play different songs, one after the other like in normal audio players
//The files are listed as an array into a ListView, so i added a ListView.OnItemClickListener to play that location which the user has selected
ListView audiolist=(ListView)findViewById(R.id.audiolist);
audiolist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(position==id){
File mypath=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
String mystring=(String)audiolist.getItemAtPosition(position);
if(mystring.contains(".mp3")) {
File myfile = new File(mypath.toString(), "/" + mystring);
Uri newuri = Uri.fromFile(myfile);
//I think this line is the one creating the mutiple instances of the MediaPayer
mp=new MediaPlayer();
mp.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mp.setAudioAttributes(
new AudioAttributes.Builder().setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).setUsage(AudioAttributes.USAGE_MEDIA)
.build()
);
try {
mp.setDataSource(getApplicationContext(),newuri);
mp.setDisplay(holder);
mp.prepare();
mp.setOnBufferingUpdateListener(Audio_Player.this);
mycontroller=new MediaController(Audio_Player.this);
mycontroller.setMediaPlayer(Audio_Player.this);
mp.start();
} catch (IOException e) {
e.printStackTrace();
}
}//end of if
});//end of listview method
Root cause
Every time users click on an item of a ListView, you always create a new MediaPlayer instance and do not stop the current one. That explains why you see multiple audios are playing at the same time.
Solution
Just create a new MediaPlayer instance if there is no one existing, otherwise, stop the current one before playing the new one. Change your code from
File mypath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
String mystring = (String)audiolist.getItemAtPosition(position);
if (mystring.contains(".mp3")) {
File myfile = new File(mypath.toString(), "/" + mystring);
Uri newuri = Uri.fromFile(myfile);
// I think this line is the one creating the mutiple instances of the MediaPayer
mp = new MediaPlayer();
mp.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mp.setAudioAttributes(
new AudioAttributes.Builder().setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).setUsage(AudioAttributes.USAGE_MEDIA)
.build()
);
try {
mp.setDataSource(getApplicationContext(),newuri);
mp.setDisplay(holder);
mp.prepare();
mp.setOnBufferingUpdateListener(Audio_Player.this);
mycontroller=new MediaController(Audio_Player.this);
mycontroller.setMediaPlayer(Audio_Player.this);
mp.start();
} catch (IOException e) {
e.printStackTrace();
}
}
to
File mypath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
String mystring = (String) audiolist.getItemAtPosition(position);
if (mystring.contains(".mp3")) {
File myfile = new File(mypath.toString(), "/" + mystring);
Uri newuri = Uri.fromFile(myfile);
// I think this line is the one creating the mutiple instances of the MediaPayer
// Create a new MediaPlayer instance if there is no one existing.
if (mp == null) {
mp = new MediaPlayer();
mp.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
AudioAttributes.Builder builder = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA);
mp.setAudioAttributes(builder.build());
mp.setOnBufferingUpdateListener(Audio_Player.this);
mycontroller = new MediaController(Audio_Player.this);
mycontroller.setMediaPlayer(Audio_Player.this);
mp.setDisplay(holder);
}
// If the MediaPlayer is playing, then stop it and switch to another audio,
try {
if (mp.isPlaying()) {
mp.reset();
}
mp.setDataSource(getApplicationContext(), newuri);
mp.prepare();
mp.start();
} catch (IOException e) {
e.printStackTrace();
}
}//end of if
I'm totally new to Android Development and to Android devices in general, so I don't know how things are working here.
I want to make an app that will stream music from my url and still playing the song after I minimize the application.
I searched my question but a lot of answers were for mp3 songs or other types, but my url is from a live radio so it isn't one song only.
One of the answers that I found and were good for my problem was this and uses this code:
Uri myUri = Uri.parse("your url here");
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(myUri, "audio/*");
startActivity(intent);
This prompt me to choose a music player.
Is there any way to just press my "play" button and hear the music?
In my iOS app I use this code and I can start and stop the streaming music whenever I want without an external player:
func prepareToPlay() {
let url = URL(string: "myUrl")
playerItem = AVPlayerItem(url: url!)
player = AVPlayer(playerItem: playerItem)
player?.play()
}
Thanks in advance
EDIT
After suggested in comments and answer I tried to play it with MPlayer, I made a function and I called it when I tapped my button like this:
public void playM() {
String url = "http://android.programmerguru.com/wp-content/uploads/2013/04/hosannatelugu.mp3";
mPlayer = new MediaPlayer();
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mPlayer.setDataSource(url);
} catch (IllegalArgumentException e) {
Toast.makeText(getApplicationContext(), "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
} catch (SecurityException e) {
Toast.makeText(getApplicationContext(), "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
} catch (IllegalStateException e) {
Toast.makeText(getApplicationContext(), "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
try {
mPlayer.prepare();
} catch (IllegalStateException e) {
Toast.makeText(getApplicationContext(), "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
}
mPlayer.start();
}
But I get an error (the fourth message) and I saw in the logs this:
Unable to create media player
prepareAsync called in state 1, mPlayer(0x0)
start called in state 1, mPlayer(0x0)
error (-38, 0)
Intent with ACTION flag is intended to open another app in most cases. Since you don't need it. You want your own custom player. So Android has a Media Player class for such scenarios.
Create instance of it and pass your stream-URL. Now, set the data-source and call prepare() after that in onBtnClickListener() start the music by calling mp.start()
Uri myUri = ....; // initialize Uri here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.prepare();
mediaPlayer.start();
P.S: Catch all the exceptions and make sure the PERMISSIONS in manifest file
Intent is using only for sending some data between activities/services and system. It won't play the music. It don't do anything except saying to some activity what to do. You need the mechanism which will play your multimedia stream. You should use MediaPlayer class for playing multimedia inside your application.
Here's some tutorial, how to play music from stream: http://programmerguru.com/android-tutorial/android-mediaplayer-example-play-from-internet/
I have a Uri formed like
Uri sound = Uri.parse("file:///pathinmymobile/a?.mp3")
but because of the question mark, in MediaPlayer creation throws a setDataSource problem. I've also tested without the "file://", and with
URLEncoder.encode("file:///pathinmymobile/a?.mp3", "UTF-8").
and other more combinations. Is it possible to play a file containing special characters as question marks ?
If your file is in Android assets folder. This might help
try {
MediaPlayer mediaPlayer = new MediaPlayer();
AssetFileDescriptor descriptor = getAssets().openFd("intro.mp3");
mediaPlayer.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
descriptor.close();
mediaPlayer.prepare();
mediaPlayer.setVolume(1f, 1f);
mediaPlayer.setLooping(true);
mediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
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.
I m using the MediaPlayer to play one of the internal alarm ringtone.
i m using the setVolume(1.0f, 1.0f) to maximize the volume when the ringtone is played. but the ringtone doesn't play full volume ( when I compare it to playing the ringtone separately or through the built it android alarm)
here is my code
mediaPlayer.setDataSource(context, ringtoneUri);
mediaPlayer.setLooping(looping);
mediaPlayer.setVolume(1.0f, 1.0f);
mediaPlayer.prepare();
mediaPlayer.start();
I added the following permission android.permission.MODIFY_AUDIO_SETTINGS
( not sure if this is needed )
Any Idea why the mediaPlayer still won't play the sound at maximum?
Here is the solution I found.
AudioManager amanager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
int maxVolume = amanager.getStreamMaxVolume(AudioManager.STREAM_ALARM);
amanager.setStreamVolume(AudioManager.STREAM_ALARM, maxVolume, 0);
MediaPlayer mediaPlayer= new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM); // this is important.
mediaPlayer.setDataSource(context, ringtoneUri);
mediaPlayer.setLooping(looping);
mediaPlayer.prepare();
mediaPlayer.start();
I encountered the same issue, and then noticed this this in the MediaPlayer documentation:
While in the Prepared state, properties such as audio/sound volume, screenOnWhilePlaying, looping can be adjusted by invoking the corresponding set methods.
Calling setVolume after calling prepare fixes this, so that audio is played at max volume. Actually, according to the docs I just quoted, you should call setLooping after prepare as well:
mediaPlayer.setDataSource(context, ringtoneUri);
mediaPlayer.prepare();
mediaPlayer.setLooping(looping);
mediaPlayer.setVolume(1.0f, 1.0f);
mediaPlayer.start();
Since setAudioStreamType() is now deprecated you should use the method setAudioAttributes() instead. Below is the full example
var mediaPlayer: MediaPlayer = MediaPlayer()
fun playAudio(audioUrl: String) {
mediaPlayer.apply {
if (isPlaying) {
stop()
reset()
release()
}
}
mediaPlayer = MediaPlayer()
try {
mediaPlayer.apply {
setAudioAttributes(
AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.setUsage(AudioAttributes.USAGE_ALARM)
.build()
)
setVolume(2f,2f)
setDataSource(audioUrl)
prepare()
start()
}
} catch (e: IOException) {
e.printStackTrace()
}
}