I have a server with a number of audio files which from time to time more files are added. I want those files to be loaded in my android app so they an be played. How would I go about doing this?
I am using native android
Simple AudioHandler class to play, pause, resume audio etc
public class AudioHandler {
private SimpleExoPlayer simpleExoPlayer;
//Start Playing
public void playAudio(String URL) {
try {
if(simpleExoPlayer == null) {
simpleExoPlayer = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(mContext),
new DefaultTrackSelector(),
new DefaultLoadControl());
}
// Preparing from url
Uri uri = Uri.parse(URL);
MediaSource mediaSource = buildMediaSource(uri);
simpleExoPlayer.prepare(mediaSource, true, false);
simpleExoPlayer.setPlayWhenReady(true);
simpleExoPlayer.addListener(new Player.DefaultEventListener() {
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
super.onPlayerStateChanged(playWhenReady, playbackState);
switch(playbackState) {
case Player.STATE_READY:
// Update UI -- Audio has start playing
break;
case Player.STATE_ENDED:
ReleaseMediaPlayer();
// Update UI -- Audio has ended
break;
default:
break;
}
}
#Override
public void onPlayerError(ExoPlaybackException error) {
super.onPlayerError(error);
ReleaseMediaPlayer();
// Update UI -- error
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public void pauseAudio(){
try{
if (simpleExoPlayer != null) {
simpleExoPlayer.setPlayWhenReady(false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void resumeAudioa(){
try{
if (simpleExoPlayer != null) {
simpleExoPlayer.setPlayWhenReady(true);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void ReleaseMediaPlayer(){
try{
if (simpleExoPlayer != null) {
simpleExoPlayer.release();
simpleExoPlayer = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
private MediaSource buildMediaSource(Uri uri) {
return new ExtractorMediaSource.Factory(
new DefaultHttpDataSourceFactory("exoplayer-audios")).
createMediaSource(uri);
}
// Constructor and other methods...
}
Related
In my Media Player app I use default media player and in my app song stops in between 10-13 min
and that's starts from 0 again when click on pause icon.
I have an issue with Media player always stopping randomly after some few mins. then I put secondary buffer progress I have check my audio is not buffering after some time that's why it is not play after that buffering min.
is there any solution to over come this issue? please help me for this as soon as possible.
if (mediaPlayer == null)
mediaPlayer = new MediaPlayer();
initMediaplyer();
if (mediaPlayer.isPlaying()) {
Log.e("Playinggggg", "stoppppp");
mediaPlayer.stop();
isMediaStart = false;
isPrepare = false;
isPause = false;
}
mediaPlayer = new MediaPlayer();
initMediaplyer();
mediaPlayer.setDataSource(url);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mediaPlayer.setAudioAttributes(
new AudioAttributes
.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build());
}
mediaPlayer.prepareAsync();
isPause = false;
isPrepare = true;
} catch (IllegalStateException | IOException e) {
FileDescriptor fileDescriptor1 = null;
setMediaPlayer("0", fileDescriptor1);
e.printStackTrace();
}
if (!mediaPlayer.isPlaying()) {
mediaPlayer.setOnPreparedListener(mp -> {
Log.e("Playinggggg", "Startinggg");
mediaPlayer.start();
isMediaStart = true;
isprogressbar = false;
setMediaPlaybackState(STATE_PLAYING);
mediaPlayer.setOnBufferingUpdateListener((mediaPlayer, i) -> {
binding.simpleSeekbar.setSecondaryProgress(i);
});
mediaPlayer.setOnCompletionListener(mediaPlayer -> {
if(mediaPlayer.isPlaying()){
callComplete();
}
});
mediaPlayer.setOnErrorListener((mediaPlayer, i, i1) -> {
switch (i) {
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
Log.d("MediaPlayer Error", "MEDIA ERROR NOT VALID FOR PROGRESSIVE PLAYBACK " + i1);
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.d("MediaPlayer Error", "MEDIA ERROR SERVER DIED " + i1);
break;
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.d("MediaPlayer Error", "MEDIA ERROR UNKNOWN " + i1);
break;
default:
Log.d("MediaPlayer Error", "not conform " + i1);
break;
}
return false;
});
});
}
}
if (isPause) {
binding.llPlay.setVisibility(View.VISIBLE);
binding.llPause.setVisibility(View.GONE);
buildNotification(PlaybackStatus.PAUSED, ctx, mainPlayModelList, addToQueueModelList, playFrom, position);
} else {
binding.llPause.setVisibility(View.VISIBLE);
binding.llPlay.setVisibility(View.GONE);
buildNotification(PlaybackStatus.PLAYING, ctx, mainPlayModelList, addToQueueModelList, playFrom, position);
}
private void initMediaplyer() {
try {
if (mediaSessionManager != null) return;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mediaSessionManager = (MediaSessionManager) ctx.getSystemService(Context.MEDIA_SESSION_SERVICE);
}
mediaSession = new MediaSessionCompat(ctx.getApplicationContext(), "AudioPlayer");
//Get MediaSessions transport controls
transportControls = mediaSession.getController().getTransportControls();
mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mMediaControllerCompatCallback = new MediaControllerCompat.Callback() {
#Override
public void onPlaybackStateChanged(PlaybackStateCompat state) {
super.onPlaybackStateChanged(state);
if( state == null ) {
return;
}
switch( state.getState() ) {
case PlaybackStateCompat.STATE_PLAYING: {
mCurrentState = STATE_PLAYING;
break;
}
case PlaybackStateCompat.STATE_PAUSED: {
mCurrentState = STATE_PAUSED;
break;
}
}
}
};
mediaSession.setCallback(new MediaSessionCompat.Callback() {
// Implement callbacks
#Override
public void onPlay() {
super.onPlay();
callPlay();
}
#Override
public void onPause() {
super.onPause();
callPause();
}
#Override
public void onSkipToNext() {
super.onSkipToNext();
if (!url.equalsIgnoreCase("")) {
callNext();
}
}
#Override
public void onSkipToPrevious() {
super.onSkipToPrevious();
if (!url.equalsIgnoreCase("")) {
callPrevious();
}
}
#Override
public void onStop() {
super.onStop();
}
});
} catch (Exception e) {
Log.e("playwell init media err",e.getMessage());
e.printStackTrace();
}
}
}
I have a problem with changing URL of live stream in the MediaPlayer instance. When I tap on a ListView item for a first time, live streaming is started and video is displayed, but if I click on another object in the ListView, stream is not changed, the same stream continues to play which was executed at first time.
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, MediaPlayer.OnPreparedListener, VideoControllerView.MediaPlayerControl {
SurfaceView videoSurface;
MediaPlayer player;
VideoControllerView controller;
ArrayList<Channel> channels;
Channel clickedChannel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
videoSurface = (SurfaceView) findViewById(R.id.videoSurface);
SurfaceHolder videoHolder = videoSurface.getHolder();
videoHolder.addCallback(this);
controller = new VideoControllerView(this);
player = new MediaPlayer();
channels = new ArrayList<Channel>();
CreateChannels();
ListView lvMain = (ListView) findViewById(R.id.lvMain);
CustomAdapter adapter = new CustomAdapter(this, channels);
lvMain.setAdapter(adapter);
lvMain.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Log.d(LOG_TAG, "itemClick: position = " + position + ", id = "
+ id);
clickedChannel = channels.get(position);
}
}
}
PlayStream(clickedChannel.Streams[0].URL);
}
});
}
public void PlayStream(String URL) {
try {
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDataSource(this, Uri.parse(URL));
player.setOnPreparedListener(this);
player.prepareAsync();
player.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
// missed code
#Override
public boolean onTouchEvent(MotionEvent event) {
controller.show();
return false;
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
player.setDisplay(holder);
}
#Override
public void onPrepared(MediaPlayer mp) {
controller.setMediaPlayer(this);
controller.setAnchorView((FrameLayout) findViewById(R.id.videoSurfaceContainer));
player.start();
}
}
Solved my problem by recreating player instance every time
public void PlayStream(String URL) {
releaseMP();
try {
player = new MediaPlayer();
player.setDisplay(videoHolder);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDataSource(this, Uri.parse(URL));
player.setOnPreparedListener(this);
player.prepareAsync();
player.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void releaseMP() {
if (player != null) {
try {
player.release();
player = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
protected void onDestroy() {
super.onDestroy();
releaseMP();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
}
I am stuck with a weird problem. I have an activity with a MediaPlayer that should play a just recorded audio file. At first the mediaplayer is initialized ok and the file can be played.
When I rotate the screen, the activity is destroyed and then reinitialized for the new orientation. Therefore, I re-initialize the mediaplayer too.
this works a couple of times, but at some point mediaPlayer.setDataSource() throws a NullPointerException because the file is suddenly gone. Sadly, I haven't seen any other error in the logs.
Here are some Code snippets:
player creation:
/**
* Creates and initializes the player with the proper file.
*/
private void createPlayer() {
synchronized (playerMutex) {
player = new MediaPlayer();
player.setLooping(false);
player.setOnPreparedListener(this);
player.setOnErrorListener(this);
player.setOnCompletionListener(this);
}
readGreeting();
}
player initialization:
isPrepared = false;
try {
final File file = new File(audioFilename);
in = new FileInputStream(file);
synchronized (playerMutex) {
player.setDataSource(in.getFD());
}
// using a runnable instead of prepareAsync to not accidentally call pause on media player while preparing
Runnable preparer = new Runnable() {
#Override
public void run() {
try {
synchronized (playerMutex) {
if (player != null) {
player.prepare();
}
}
} catch (Exception ex) {
Log.e(TAG, "Error preparing player for file " + file.getAbsolutePath(), ex);
}
}
};
new Thread(preparer).start();
} catch (Exception ex) {
btnPlayback.setEnabled(false);
Log.e(TAG, "Error preparing player", ex);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
Log.e(TAG, "initPlayer: ", e);
}
}
}
saving instance state...
#Override
protected void onPause() {
synchronized (playerMutex) {
if (isPlaying()) {
getIntent().putExtra(EXTRA_KEY_SEEK, player.getCurrentPosition());
pause();
}
}
setAudioModeBackToNormal();
super.onPause();
}
private void pause() {
synchronized (playerMutex) {
if (isPlaying()) {
player.pause();
}
}
btnPlayback.setVisibility(View.VISIBLE);
btnPause.setVisibility(View.GONE);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
final Bundle extras = getIntent().getExtras();
outState.putBundle("extras", extras);
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
getIntent().putExtras(savedInstanceState.getBundle("extras"));
}
cleanup:
private void stopPlayerAndFreeResources() {
synchronized (playerMutex) {
isPrepared = false;
if (player != null) {
player.stop();
player.release();
player = null;
}
}
if (in != null) {
try {
in.close();
in = null;
} catch (IOException e) {
Log.e(TAG, "Unexpected error", e);
}
}
}
Maybe I'm looking at the problem from the wrong angle and it has nothing to do with player. Has anybody ever had issues with disappearing files?
I had playlist files disappear once. The cause of the problem turned out to be certain media players that had an option to manage my playlists. In this case manage meant deleting the playlists I already had :(
I want to call new url after My custom Music Player complete played but It do not call and send new url to my player. Help me please thank you.
public void onCompletion(MediaPlayer arg0)
{
playing = "Stopped";
new Thread(new Runnable()
{
#Override
public void run()
{
now++;
try
{
onCompleteURL = new URL(musicUrl[now]);
onCompleteURLConnection = onCompleteURL.openConnection();
onCompleteReadIn = new BufferedReader(new InputStreamReader(onCompleteURLConnection.getInputStream()));
onCompleteUrl = onCompleteReadIn.readLine();
onCompleteReadIn.close();
}
catch (Exception e)
{
e.printStackTrace();
}
waitingGetNextDataHandler1.sendEmptyMessage(0);
}
}).start();
waitingGetNextDataHandler1 = new Handler()
{
public void handleMessage(Message msg)
{
super.handleMessage(msg);
try
{
/*mMediaPlayer.reset();
sendHTTPRequest();
startPlayer();*/
mMediaPlayer.reset();
mMediaPlayer.setDataSource(onCompleteUrl);
mMediaPlayer.prepare();
mMediaPlayer.start();
playing = "Started";
running = mMediaPlayer.isPlaying();
playPauseImageButton.setBackgroundResource(R.drawable.pause_button);
}
catch (Exception e)
{
e.printStackTrace();
}
if(mMediaPlayer != null)
{
if(mMediaPlayer.isPlaying() == true)
{
playPauseImageButton.setBackgroundResource(R.drawable.pause_button);
}
else
{
playPauseImageButton.setBackgroundResource(R.drawable.play_button);
}
setValue();
}
}
};
}
I need help/pointer to doc/sample code on how to load multiple audio files from a specific folder on the SD card and have it play a random file back(i think i can figure out the last step if i could just figure out how to load multiple files). Here is my incredibly poorly written app so far, don't judge too harshly as I'm learning as I go.
public class zazenbox extends Activity implements OnClickListener{
File filecheck;
MediaPlayer player;
Button playerButton;
Integer var1;
String path1;
AlertDialog.Builder alertbox;
public void onClick(View v) {
if (v.getId() == R.id.play) {
playPause();
}
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
demoLoad();
playerButton = (Button) this.findViewById(R.id.play);
playerButton.setText(R.string.stop);
playerButton.setOnClickListener(this);
demoPlay();
}
#Override
public void onPause() {
super.onPause();
player.pause();
}
#Override
public void onStop() {
super.onStop();
player.stop();
}
private void demoLoad() {
dirfilecheck();
player = new MediaPlayer();
player.setLooping(true);
try {
player.setDataSource(path1);
player.prepare();
}
catch (IOException e) { e.printStackTrace(); }
catch (IllegalArgumentException e) { e.printStackTrace(); }
catch (IllegalStateException e) { e.printStackTrace(); }
}
private void dirfilecheck() {
filecheck = new File(Environment.getExternalStorageDirectory() + "/zazenbox");
if(filecheck.exists() && filecheck.isDirectory()) {
// load files.
var1 = 1;
path1 = filecheck + "/bm10" + var1 + ".wav";
} else {
// create folder, dl sample loop, and instruct user how to add music/loops.
filecheck.mkdirs();
alertbox = new AlertDialog.Builder(this);
alertbox.setMessage("Please put loopable media in zazenbox on your sdcard.");
alertbox.setNeutralButton("Ok, I will.", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
Toast.makeText(getApplicationContext(), "Please plug in your device now", Toast.LENGTH_LONG).show();
}
});
alertbox.show();
}
}
private void demoPause() {
player.pause();
playerButton.setText(R.string.play);
}
private void demoStop() {
player.stop();
playerButton.setText(R.string.play);
}
private void demoPlay() {
player.start();
playerButton.setText(R.string.stop);
}
private void playPause() {
if(player.isPlaying()) {
demoStop();
//demoPause();
//player.release();
var1++;
path1 = filecheck + "/bm10" + var1 + ".wav";
/*try {
player.setDataSource(path1);
player.prepare();
}
catch (IOException e) { e.printStackTrace(); }
catch (IllegalArgumentException e) { e.printStackTrace(); }
catch (IllegalStateException e) { e.printStackTrace(); }*/
//player.start();
//demoPlay();
} else {
//do stuff
demoPlay();
}
}
}
Memory is extremely limited on mobile devices, so you wouldn't want to load songs you're not going to play. So what you should do is find all of the audio files in that folder, and then choose one and THEN load and play it.
You just need to stop the current player and create a new instance.
MediaPlayer player = MediaPlayer.create(this, Uri.parse("Path/To/Media"));
player.start();
// change track
player.stop();
player = MediaPlayer.create(this, Uri.parse("New/Path/To/Media"));
player.start();