I am using a method to initialize and prepare a MediaPlayer (defined as class variable). It takes a String which is the name of the song as its parameter and it sets the DataSource to that particular path.
public void create_and_prepare_song(String x) {
if (mp != null)
mp.release();
mp = new MediaPlayer();
String filePath = Environment.getExternalStorageDirectory().getPath() + "/songsfolder/" + x + ".mp3";
try {
mp.setDataSource(filePath);
} catch (IOException e) {
e.printStackTrace();
}
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Now, somewhere inside my code I use this method to initialize and prepare "1.mp3". Then, as soon as this song is finished, I use an onCompletionListener so that "2.mp3" is played after, and "3.mp3" then. I use:
create_and_prepare_song("1");
i = 2;
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if (i <= 3) {
String int_to_String = i + "";
create_and_prepare_song(int_to_String); //1
mp.setOnCompletionListener(this);
mp.start();
i++;
}
}
});
mp.start();
Now, this causes app to stop from working! However, if I just copy and paste the body of the method to the //1 line instead, the app works fine, playing first, second and third song. Why is that so? Thanks a lot
Note that you are creating a new player inside of create_and_prepare_song() but the old one is still referenced inside of the listener.
That's because the global variable and the onCompletion parameter has the same name: mp.
Here's piece of code that works:
package com.example.simon.mplaylist;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import java.io.IOException;
/**
* Created by Simon on 2014 Jul 20.
*/
public class MainActivity extends Activity {
static int currentSong;
static MediaPlayer mediaPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (mediaPlayer != null)
return;
currentSong = 1;
create_and_prepare_song(currentSong);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if (currentSong++ >= 3) {
mediaPlayer = null;
return;
}
create_and_prepare_song(currentSong);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.start();
}
});
mediaPlayer.start();
}
public void create_and_prepare_song(int songNum) {
if (mediaPlayer != null)
mediaPlayer.release();
mediaPlayer = new MediaPlayer();
String storage = Environment.getExternalStorageDirectory().getPath();
String filePath = storage + "/songsfolder/" + String.valueOf(songNum) + ".mp3";
try {
mediaPlayer.setDataSource(filePath);
} catch (IOException e) {
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
NOTE also that I defined the MediaPlayer as static and also am checking # onCreate for it's presence. That way you avoid multiple songs playing at once if the activity is recreated (e.g. screen rotation).
You really shouldn't be starting actual playback inside create_and_prepare_song(). It should be started inside onPrepared() since there might be some delay from the call to prepare() and the media being ready to play.
Related
in my simple player i have play, and stop buttons and play and pause media player work fine, now after click on stop and play again, media player don't work and i'm not sure whats problem to resolve that
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
playMonthLesson();
...
}
#SuppressLint("DefaultLocale")
public void playMonthLesson() {
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(CoreApplication.MEDIAFOLDER + "/" + lesson.getFilename());
mediaPlayer.prepare();
mediaPlayer.start();
lesson_play.setImageResource(R.drawable.ic_pause);
int totalDuration = mediaPlayer.getDuration();
// set Progress bar values
lesson_progress_bar.setProgress(curretLessonProgress);
lesson_progress_bar.setMax(100);
// Updating progress bar
updateProgressBar();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
#OnClick(R.id.lesson_play)
public void lesson_play(View view) {
if (mediaPlayer == null) {
playMonthLesson();
} else if (mediaPlayer.isPlaying()) {
if (mediaPlayer != null) {
mediaPlayer.pause();
// Changing button image to play button
lesson_play.setImageResource(R.drawable.ic_play);
}
} else {
// Resume song
if (mediaPlayer != null) {
mediaPlayer.start();
// Changing button image to pause button
lesson_play.setImageResource(R.drawable.ic_pause);
}
}
}
#OnClick(R.id.lesson_stop)
public void setLesson_stop(View view) {
if (mediaPlayer != null) {
mediaPlayer.stop();
lesson_play.setImageResource(R.drawable.ic_play);
lesson_progress_bar.setProgress(0);
}
}
According to the MediaPlayer life cycle, which you can view in the Android API guide, I think that you have to call reset() instead of stop(), and after that prepare again the media player (use only one) to play the sound from the beginning. Take also into account that the sound may have finished. So I would also recommend to implement setOnCompletionListener() to make sure that if you try to play again the sound it doesn't fail.
The problem is that when you stop mediaplayer and click on play again your call will go to mediaplayer.play() as mediaplayer is not null.
You will have to null the mediaPlayer on stop method. Now, once you stop mediaplayer and again click on play it will call playMonthLesson();
#OnClick(R.id.lesson_stop)
public void setLesson_stop(View view) {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer = null;
lesson_play.setImageResource(R.drawable.ic_play);
lesson_progress_bar.setProgress(0);
}
}
change this code too,
#SuppressLint("DefaultLocale")
public void playMonthLesson() {
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.reset();
mediaPlayer.setDataSource(CoreApplication.MEDIAFOLDER + "/" + lesson.getFilename());
mediaPlayer.setOnPreparedListener(new OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
lesson_play.setImageResource(R.drawable.ic_pause);
int totalDuration = mediaPlayer.getDuration();
}
});
mediaPlayer.prepareAsync();
// set Progress bar values
lesson_progress_bar.setProgress(curretLessonProgress);
lesson_progress_bar.setMax(100);
// Updating progress bar
updateProgressBar();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
How to record audio and playing sound at the same time. Which process is better to implement in background and what to use Thread or AsyncTask? I haved tried playing sound in new thread and recordning on main thread but i have problem that on some devices i get error that the main thread is overload.
Is it better to use native rocordning, because i also need recorded buffer?
Does anybody have any example how to use native recording?
You can use following custom class:-
package com.app.controller;
import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.provider.SyncStateContract.Constants;
import android.widget.Toast;
public class MediaController implements OnPreparedListener{
public MediaController() {
// TODO Auto-generated constructor stub
}
public MediaPlayer mp;
public void getMediaPlayObject() {
try {
System.out.println("00000000000000");
mp = new MediaPlayer();
System.out.println("2222222222");
} catch (Exception e) {
// TODO: handle exception
System.out.println("exception in audia player====" + e.toString());
}
}
public void onPrepared(MediaPlayer player) {
mp.start();
}
boolean WORKING = true;
public void mediaPlayStart(final Context m_Context) {
try {
mp = new MediaPlayer();
mp.setDataSource(m_Context, Uri.parse(Contants.audioURL_OR_PATH));
mp.prepare();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setLooping(true);
} catch (Exception e) {
// TODO: handle exception
Toast.makeText(m_Context, "Service unavailable this time. Please try again!", Toast.LENGTH_LONG).show();
System.out.println("#####THE EXCEPTION IN THE MEDIA PLAYER PLAY==="+e.getMessage());
}
}
public void mediaPlayStop() {
try {
if (mp.isPlaying()) {
mp.stop();
}
} catch (Exception e) {
// TODO: handle exception
}
}
private static String getSoundPath(int countPositiong) {
// TODO Auto-generated method stub
String aa = "";
try {
if (countPositiong < 10) {
aa = "sounds/00" + countPositiong + ".mp4";
} else if (countPositiong < 100) {
aa = "sounds/0" + countPositiong + ".mp4";
} else {
aa = "sounds/" + countPositiong + ".mp4";
}
} catch (Exception e) {
// TODO: handle exception
}
System.out.println("name is : " + aa);
return aa;
}
}
I am developing an app for Android devices using Processing 2.0, now I have playMP3(); function but need to stop the sound using stopMP3();. I tried everything but what is the best way to load an mp3 and play/stop using processing?, snd.stop(); within the stopMP3 function does not work...
import android.media.*;
import android.content.res.*;
...
MediaPlayer snd;
...
void setup()
{
MediaPlayer snd = new MediaPlayer();
}
...
void playMP3()
{
try {
AssetManager assets = this.getAssets();
AssetFileDescriptor fd = assets.openFd("loop1.mp3");
snd.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
snd.prepare();
snd.start();
snd.setLooping(true);
}
catch (IllegalArgumentException e) {
e.printStackTrace();
}
catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
void stopMP3(){
????
}
this is a simple sample for media player
private MediaPlayer m_Player;
//Start Play Function
private void startPlaying() {
m_Player = new MediaPlayer();
m_Player.setOnCompletionListener(onComplete);
try {
if(m_Player.isPlaying())
stopPlaying();
m_Player.setDataSource(m_FileName);
m_Player.prepare();
m_Player.start();
} catch (IOException e) {
}
}
//Stop Play Function
private void stopPlaying() {
m_Player.stop();
m_Player.reset();
m_Player = null;
}
//and this is onComplete Listener
MediaPlayer.OnCompletionListener onComplete = new OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp)
{
stopPlaying();
}
};
i hope it's helping you
In the application I am currently writing, a user is able to select an entry from the database and play the contents of that entry: an entry is made up of a number of sound files (without a limit). In my application, I return the URI locations of the sound files of an entry (which have been stored in my database) in a List. The code is as follows:
public void audioPlayer() {
// set up MediaPlayer
MediaPlayer mp = new MediaPlayer();
DatabaseHandler db = new DatabaseHandler(this);
Entry retrieveEntry = new Entry();
retrieveEntry = db.getEntry();
List<String> path = retrieveEntry.getAudioUri();
path.size();
System.out.println("PATH SIZE: " +path.size());
System.out.println("FILEZ: " + path);
Iterator<String> i = path.iterator();
String myAudio;
int count = 0;
while (i.hasNext()) {
System.out.println(count);
myAudio = i.next();
System.out.println("MY AUDIO: " + myAudio);
MediaPlayer player = MediaPlayer.create(this, Uri.parse(myAudio));
player.start();
player.stop();
player = MediaPlayer.create(this, Uri.parse(myAudio));
player.start();
count++;
}
}
My users require that there be user input for playing a file - is there a way to play the first file, then wait for the user to press the button, then play the second file, then wait for the user to press the button, etc.? At the moment, when the play button is pressed, all of the sound files that have been returned get played at the same time, rather than one after the other.
Thanks in advance for any help provided!
You can use this class to play a playlist. This will start one audio, when that audio finishes, it will start playing next audio till the end of the list. If you want to play the playlist in looping i.e start first audio after reaching end, then pass isLooping=true in startPlayingPlaylist(list,looping)
AudioPlayer player = new AudioPlayer();
player.startPlayingPlaylist(list, false);
Class
public class AudioPlayer{
MediaPlayer player = null;
ArrayList<String> playlist = null;
int position = 0;
public AudioPlayer() {
super();
// TODO Auto-generated constructor stub
}
public void startPlayingPlaylist(ArrayList<String> list, boolean looping){
playlist = list;
if(player!=null){
player.release();
}
if(playlist!=null && playlist.size()>0){
player = MediaPlayer.create(LMApplicaton.getInstance(),Uri.parse(playlist.get(position)));
player.setWakeMode(LMApplicaton.getInstance(), PowerManager.PARTIAL_WAKE_LOCK);
player.setLooping(looping);
player.start();
// Set onCompletion listener
player.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
position = position+1;
if(position<playlist.size()){
try {
player.reset();
player.setDataSource(playlist.get(position));
player.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else if(player.isLooping()==true){
position = position%playlist.size();
try {
player.reset();
player.setDataSource(playlist.get(position));
player.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
else if(player.isLooping()==false){
player.release();
player = null;
}
}
});
player.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
player.start();
}
});
}
}
public void pause(){
if(player!=null && player.isPlaying()){
player.pause();
}
}
public void play(){
if(player!=null && player.isPlaying()==false){
player.start();
}
}
public boolean isPlaying(){
return player.isPlaying();
}
public void release(){
if(player!=null){
player.release();
}
}
}
Edit:
The class below receives a list of audios, then plays first Audio. It plays next audio when user calls startNextAudio() You can use any one of these according to your requirements
public class AudioPlayer{
MediaPlayer player = null;
ArrayList playlist = null;
int position = 0;
public AudioPlayer() {
super();
// TODO Auto-generated constructor stub
}
public void startPlayingPlaylist(ArrayList<String> list){
playlist = list;
if(player!=null){
player.release();
}
if(playlist!=null && playlist.size()>0){
player = MediaPlayer.create(LMApplicaton.getInstance(),Uri.parse(playlist.get(position)));
player.setWakeMode(LMApplicaton.getInstance(), PowerManager.PARTIAL_WAKE_LOCK);
player.start();
// Set onCompletion listener
player.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
player.start();
}
});
}
}
public void startNextAudio(){
position = position+1;
if(position<playlist.size()){
try {
player.reset();
player.setDataSource(playlist.get(position));
player.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else if(player.isLooping()==true){
position = position%playlist.size();
try {
player.reset();
player.setDataSource(playlist.get(position));
player.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}else{
Log.i("AudioPlayer","Playlist reached at the end");
}
}
public void pause(){
if(player!=null && player.isPlaying()){
player.pause();
}
}
public void play(){
if(player!=null && player.isPlaying()==false){
player.start();
}
}
public boolean isPlaying(){
return player.isPlaying();
}
public void release(){
if(player!=null){
player.release();
}
}
}
One approach would be to implement the MediaPlayer.OnCompletionListener interface. This gives you the MediaPlayer.onCompletion() callback method which you could use like so:
#Override
public void onCompletion(MediaPlayer mp) {
if (i.hasNext) {
// ...hand mp the next file
// ...show the user the 'play next' button
}
}
Note you also will need to call the MediaPlayer.setOnCompletionListener() method in your setup.
I have a problem with this code for live streaming:
package cm.ex.wwd;
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;
public class AudioStream extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String url = "http://www.songblasts.com/songs/hindi/t/three-idiots/01-Aal_Izz_Well-(SongsBlasts.Com).mp3";
MediaPlayer mp = new MediaPlayer();
try {
mp.setDataSource(url);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.prepare();
mp.start();
} catch (Exception e) {
Log.i("Exception", "Exception in streaming mediaplayer e = " + e);
}
}
}
url you are giving is not a valid one.it is showing 404 NOT FOUND.so it is creating problem for you.give a valid one
Without knowing the exact problem it is difficult to answer. If you do this on your UI Thread you might also run into an application crash as the call to prepare() might take to long. Better use prepareAsync() and the associated listeners when using streaming.
As mentioned before, also the URL gives a 404.
i have done little changes in above code. check out this one.
player = new MediaPlayer();
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
player.setDataSource("http://www.hubharp.com/web_sound/BachGavotte.mp3");
player.setOnErrorListener(this);
player.setOnPreparedListener(this);
player.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onDestroy() {
super.onDestroy();
player.release();
player = null;
}
#Override
public void onPrepared(MediaPlayer play) {
play.start();
}
#Override
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
return false;
}