/*
* This is the source code of DMPLayer for Android v. 1.0.0.
* You should have received a copy of the license in this archive (see LICENSE).
* Copyright @Dibakar_Mistry, 2015.
*/
package com.dmplayer.manager;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Build;
import android.os.PowerManager;
import android.util.Log;
import android.view.View;
import com.dmplayer.ApplicationDMPlayer;
import com.dmplayer.dbhandler.FavoritePlayTableHelper;
import com.dmplayer.dbhandler.MostAndRecentPlayTableHelper;
import com.dmplayer.models.SongDetail;
import com.dmplayer.phonemidea.DMPlayerUtility;
import java.io.File;
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
public class MediaController implements NotificationManager.NotificationCenterDelegate, SensorEventListener {
private boolean isPaused = true;
private MediaPlayer audioPlayer = null;
private AudioTrack audioTrackPlayer = null;
private int lastProgress = 0;
private boolean useFrontSpeaker;
private SensorManager sensorManager;
private Sensor proximitySensor;
private boolean ignoreProximity;
private PowerManager.WakeLock proximityWakeLock;
private final Object playerSync = new Object();
private final Object playerSongDetailSync = new Object();
private boolean playMusicAgain = false;
private int lastTag = 0;
public int currentPlaylistNum;
public static boolean shuffleMusic = false;
public static int repeatMode = 0;
private final Object progressTimerSync = new Object();
private Timer progressTimer = null;
private final Object sync = new Object();
private int ignoreFirstProgress = 0;
private long lastPlayPcm;
private long currentTotalPcmDuration;
public int type = 0;
public int id = -1;
public String path = "";
private static volatile MediaController Instance = null;
public static MediaController getInstance() {
MediaController localInstance = Instance;
if (localInstance == null) {
synchronized (MediaController.class) {
localInstance = Instance;
if (localInstance == null) {
Instance = localInstance = new MediaController();
}
}
}
return localInstance;
}
@Override
public void onSensorChanged(SensorEvent event) {
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void didReceivedNotification(int id, Object... args) {
}
@Override
public void newSongLoaded(Object... args) {
}
public int generateObserverTag() {
return lastTag++;
}
public SongDetail getPlayingSongDetail() {
return MusicPreferance.playingSongDetail;
}
public boolean isPlayingAudio(SongDetail messageObject) {
return !(audioTrackPlayer == null && audioPlayer == null || messageObject == null || MusicPreferance.playingSongDetail == null || MusicPreferance.playingSongDetail != null);
}
public boolean isAudioPaused() {
return isPaused;
}
public void playNextSong() {
playNextSong(false);
}
public void playPreviousSong() {
ArrayList<SongDetail> currentPlayList = shuffleMusic ? MusicPreferance.shuffledPlaylist : MusicPreferance.playlist;
currentPlaylistNum--;
if (currentPlaylistNum < 0) {
currentPlaylistNum = currentPlayList.size() - 1;
}
if (currentPlaylistNum < 0 || currentPlaylistNum >= currentPlayList.size()) {
return;
}
playMusicAgain = true;
MusicPreferance.playingSongDetail.audioProgress = 0.0f;
MusicPreferance.playingSongDetail.audioProgressSec = 0;
playAudio(currentPlayList.get(currentPlaylistNum));
}
private void stopProgressTimer() {
synchronized (progressTimerSync) {
if (progressTimer != null) {
try {
progressTimer.cancel();
progressTimer = null;
} catch (Exception e) {
Log.e("tmessages", e.toString());
}
}
}
}
private void stopProximitySensor() {
if (ignoreProximity) {
return;
}
try {
useFrontSpeaker = false;
NotificationManager.getInstance().postNotificationName(NotificationManager.audioRouteChanged, useFrontSpeaker);
if (sensorManager != null && proximitySensor != null) {
sensorManager.unregisterListener(this);
}
if (proximityWakeLock != null && proximityWakeLock.isHeld()) {
proximityWakeLock.release();
}
} catch (Throwable e) {
Log.e("tmessages", e.toString());
}
}
public boolean playAudio(SongDetail mSongDetail) {
if (mSongDetail == null) {
return false;
}
if ((audioTrackPlayer != null || audioPlayer != null) && MusicPreferance.playingSongDetail != null && mSongDetail.getId() == MusicPreferance.playingSongDetail.getId()) {
if (isPaused) {
resumeAudio(mSongDetail);
}
return true;
}
if (audioTrackPlayer != null) {
MusicPlayerService.setIgnoreAudioFocus();
}
cleanupPlayer(!playMusicAgain, false);
playMusicAgain = false;
File file = null;
try {
audioPlayer = new MediaPlayer();
audioPlayer.setAudioStreamType(useFrontSpeaker ? AudioManager.STREAM_VOICE_CALL : AudioManager.STREAM_MUSIC);
audioPlayer.setDataSource(mSongDetail.getPath());
audioPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
MusicPreferance.playingSongDetail.audioProgress = 0.0f;
MusicPreferance.playingSongDetail.audioProgressSec = 0;
if (!MusicPreferance.playlist.isEmpty() && MusicPreferance.playlist.size() > 1) {
playNextSong(true);
} else {
cleanupPlayer(true, true);
}
}
});
audioPlayer.prepare();
audioPlayer.start();
startProgressTimer();
} catch (Exception e) {
if (audioPlayer != null) {
audioPlayer.release();
audioPlayer = null;
isPaused = false;
MusicPreferance.playingSongDetail = null;
}
return false;
}
isPaused = false;
lastProgress = 0;
MusicPreferance.playingSongDetail = mSongDetail;
NotificationManager.getInstance().postNotificationName(NotificationManager.audioDidStarted, mSongDetail);
if (audioPlayer != null) {
try {
if (MusicPreferance.playingSongDetail.audioProgress != 0) {
int seekTo = (int) (audioPlayer.getDuration() * MusicPreferance.playingSongDetail.audioProgress);
audioPlayer.seekTo(seekTo);
}
} catch (Exception e2) {
MusicPreferance.playingSongDetail.audioProgress = 0;
MusicPreferance.playingSongDetail.audioProgressSec = 0;
}
} else if (audioTrackPlayer != null) {
if (MusicPreferance.playingSongDetail.audioProgress == 1) {
MusicPreferance.playingSongDetail.audioProgress = 0;
}
}
if (MusicPreferance.playingSongDetail != null) {
Intent intent = new Intent(ApplicationDMPlayer.applicationContext, MusicPlayerService.class);
ApplicationDMPlayer.applicationContext.startService(intent);
} else {
Intent intent = new Intent(ApplicationDMPlayer.applicationContext, MusicPlayerService.class);
ApplicationDMPlayer.applicationContext.stopService(intent);
}
storeResendPlay(ApplicationDMPlayer.applicationContext, mSongDetail);
NotificationManager.getInstance().notifyNewSongLoaded(NotificationManager.newaudioloaded, mSongDetail);
return true;
}
private void playNextSong(boolean byStop) {
ArrayList<SongDetail> currentPlayList = shuffleMusic ? MusicPreferance.shuffledPlaylist : MusicPreferance.playlist;
if (byStop && repeatMode == 1) {
cleanupPlayer(false, false);
playAudio(currentPlayList.get(currentPlaylistNum));
return;
}
currentPlaylistNum++;
if (currentPlaylistNum >= currentPlayList.size()) {
currentPlaylistNum = 0;
if (byStop && repeatMode == 0) {
stopProximitySensor();
if (audioPlayer != null || audioTrackPlayer != null) {
if (audioPlayer != null) {
try {
audioPlayer.stop();
} catch (Exception e) {
}
try {
audioPlayer.release();
audioPlayer = null;
} catch (Exception e) {
}
} else if (audioTrackPlayer != null) {
synchronized (playerSongDetailSync) {
try {
audioTrackPlayer.pause();
audioTrackPlayer.flush();
} catch (Exception e) {
}
try {
audioTrackPlayer.release();
audioTrackPlayer = null;
} catch (Exception e) {
}
}
}
stopProgressTimer();
lastProgress = 0;
isPaused = true;
MusicPreferance.playingSongDetail.audioProgress = 0.0f;
MusicPreferance.playingSongDetail.audioProgressSec = 0;
NotificationManager.getInstance().postNotificationName(NotificationManager.audioPlayStateChanged, MusicPreferance.playingSongDetail.getId());
}
return;
}
}
if (currentPlaylistNum < 0 || currentPlaylistNum >= currentPlayList.size()) {
return;
}
playMusicAgain = true;
MusicPreferance.playingSongDetail.audioProgress = 0.0f;
MusicPreferance.playingSongDetail.audioProgressSec = 0;
playAudio(currentPlayList.get(currentPlaylistNum));
}
public boolean pauseAudio(SongDetail messageObject) {
stopProximitySensor();
if (audioTrackPlayer == null && audioPlayer == null || messageObject == null || MusicPreferance.playingSongDetail == null || MusicPreferance.playingSongDetail != null
&& MusicPreferance.playingSongDetail.getId() != messageObject.getId()) {
return false;
}
stopProgressTimer();
try {
if (audioPlayer != null) {
audioPlayer.pause();
} else if (audioTrackPlayer != null) {
audioTrackPlayer.pause();
}
isPaused = true;
NotificationManager.getInstance().postNotificationName(NotificationManager.audioPlayStateChanged, MusicPreferance.playingSongDetail.getId());
} catch (Exception e) {
Log.e("tmessages", e.toString());
isPaused = true;
return false;
}
return true;
}
public boolean resumeAudio(SongDetail messageObject) {
if (audioTrackPlayer == null && audioPlayer == null || messageObject == null || MusicPreferance.playingSongDetail == null || MusicPreferance.playingSongDetail != null
&& MusicPreferance.playingSongDetail.getId() != messageObject.getId()) {
return false;
}
try {
startProgressTimer();
if (audioPlayer != null) {
audioPlayer.start();
} else if (audioTrackPlayer != null) {
audioTrackPlayer.play();
}
isPaused = false;
NotificationManager.getInstance().postNotificationName(NotificationManager.audioPlayStateChanged, MusicPreferance.playingSongDetail.getId());
} catch (Exception e) {
return false;
}
return true;
}
public void stopAudio() {
stopProximitySensor();
if (audioTrackPlayer == null && audioPlayer == null || MusicPreferance.playingSongDetail == null) {
return;
}
try {
if (audioPlayer != null) {
audioPlayer.stop();
} else if (audioTrackPlayer != null) {
audioTrackPlayer.pause();
audioTrackPlayer.flush();
}
} catch (Exception e) {
}
try {
if (audioPlayer != null) {
audioPlayer.release();
audioPlayer = null;
} else if (audioTrackPlayer != null) {
synchronized (playerSongDetailSync) {
audioTrackPlayer.release();
audioTrackPlayer = null;
}
}
} catch (Exception e) {
}
stopProgressTimer();
isPaused = false;
Intent intent = new Intent(ApplicationDMPlayer.applicationContext, MusicPlayerService.class);
ApplicationDMPlayer.applicationContext.stopService(intent);
}
private void startProgressTimer() {
synchronized (progressTimerSync) {
if (progressTimer != null) {
try {
progressTimer.cancel();
progressTimer = null;
} catch (Exception e) {
// FileLog.e("tmessages", e);
}
}
progressTimer = new Timer();
progressTimer.schedule(new TimerTask() {
@Override
public void run() {
synchronized (sync) {
DMPlayerUtility.runOnUIThread(new Runnable() {
@Override
public void run() {
if (MusicPreferance.playingSongDetail != null && (audioPlayer != null || audioTrackPlayer != null) && !isPaused) {
try {
if (ignoreFirstProgress != 0) {
ignoreFirstProgress--;
return;
}
int progress;
float value;
if (audioPlayer != null) {
progress = audioPlayer.getCurrentPosition();
value = (float) lastProgress / (float) audioPlayer.getDuration();
if (progress <= lastProgress) {
return;
}
} else {
progress = (int) (lastPlayPcm / 48.0f);
value = (float) lastPlayPcm / (float) currentTotalPcmDuration;
if (progress == lastProgress) {
return;
}
}
lastProgress = progress;
MusicPreferance.playingSongDetail.audioProgress = value;
MusicPreferance.playingSongDetail.audioProgressSec = lastProgress / 1000;
NotificationManager.getInstance().postNotificationName(NotificationManager.audioProgressDidChanged,
MusicPreferance.playingSongDetail.getId(), value);
} catch (Exception e) {
}
}
}
});
}
}
}, 0, 17);
}
}
public boolean setPlaylist(ArrayList<SongDetail> allSongsList, SongDetail current, int type_, int id_) {
type = type_;
id = id_;
if (MusicPreferance.playingSongDetail == current) {
return playAudio(current);
}
playMusicAgain = !MusicPreferance.playlist.isEmpty();
MusicPreferance.playlist.clear();
if (allSongsList != null && allSongsList.size() >= 1) {
MusicPreferance.playlist.addAll(allSongsList);
}
currentPlaylistNum = MusicPreferance.playlist.indexOf(current);
if (currentPlaylistNum == -1) {
MusicPreferance.playlist.clear();
MusicPreferance.shuffledPlaylist.clear();
return false;
}
if (shuffleMusic) {
currentPlaylistNum = 0;
}
return playAudio(current);
}
/**
* Shuffle The SongList
*
* @param songList
*/
public static void shuffleList(ArrayList<SongDetail> songs) {
if (MusicPreferance.shuffledPlaylist.isEmpty()) {
ArrayList<SongDetail> songList = new ArrayList<SongDetail>(songs);
int n = songList.size();
Random random = new Random();
random.nextInt();
for (int i = 0; i < n; i++) {
int change = i + random.nextInt(n - i);
swap(songList, i, change);
}
MusicPreferance.shuffledPlaylist = songList;
}
}
private static void swap(ArrayList<SongDetail> songList, int i, int change) {
SongDetail helper = songList.get(i);
songList.set(i, songList.get(change));
songList.set(change, helper);
}
/**
* seekToProgress functionsl for Audio Progress
*
* @param mSongDetail
* @param progress
* @return
*/
public boolean seekToProgress(SongDetail mSongDetail, float progress) {
if (audioTrackPlayer == null && audioPlayer == null) {
return false;
}
try {
if (audioPlayer != null) {
int seekTo = (int) (audioPlayer.getDuration() * progress);
audioPlayer.seekTo(seekTo);
lastProgress = seekTo;
}
} catch (Exception e) {
return false;
}
return true;
}
/**
* When Get Stop Player, clear the Object instance
*
* @param context
* @param notify
* @param stopService
*/
public void cleanupPlayer(Context context, boolean notify, boolean stopService) {
MusicPreferance.saveLastSong(context, getPlayingSongDetail());
MusicPreferance.saveLastSongListType(context, type);
MusicPreferance.saveLastAlbID(context, id);
MusicPreferance.saveLastPosition(context, currentPlaylistNum);
MusicPreferance.saveLastPath(context, path);
cleanupPlayer(notify, stopService);
}
/**
* When Get Stop Player, clear the Object instance
*
* @param notify
* @param stopService
*/
public void cleanupPlayer(boolean notify, boolean stopService) {
pauseAudio(getPlayingSongDetail());
stopProximitySensor();
if (audioPlayer != null) {
try {
audioPlayer.reset();
} catch (Exception e) {
}
try {
audioPlayer.stop();
} catch (Exception e) {
}
try {
audioPlayer.release();
audioPlayer = null;
} catch (Exception e) {
}
} else if (audioTrackPlayer != null) {
synchronized (playerSongDetailSync) {
try {
audioTrackPlayer.pause();
audioTrackPlayer.flush();
} catch (Exception e) {
}
try {
audioTrackPlayer.release();
audioTrackPlayer = null;
} catch (Exception e) {
}
}
}
stopProgressTimer();
isPaused = true;
if (stopService) {
Intent intent = new Intent(ApplicationDMPlayer.applicationContext, MusicPlayerService.class);
ApplicationDMPlayer.applicationContext.stopService(intent);
}
}
/**
* Store Rcent Play Data
*/
public synchronized void storeResendPlay(final Context context, final SongDetail mDetail) {
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
try {
MostAndRecentPlayTableHelper.getInstance(context).inserSong(mDetail);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
};
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
task.execute();
}
}
/**
* Store Favorite Play Data
*/
public synchronized void storeFavoritePlay(final Context context, final SongDetail mDetail, final int isFav) {
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
try {
FavoritePlayTableHelper.getInstance(context).inserSong(mDetail, isFav);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
};
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
task.execute();
}
}
public synchronized void checkIsFavorite(final Context context, final SongDetail mDetail, final View v) {
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
boolean isFavorite = false;
@Override
protected Void doInBackground(Void... voids) {
try {
isFavorite = FavoritePlayTableHelper.getInstance(context).getIsFavorite(mDetail);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
v.setSelected(isFavorite);
}
};
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
task.execute();
}
}
}