use enums to track internal states instead of int. Fixed 'unknown state' bug with the addition of loading state. Mega commit, lost some history.

This commit is contained in:
Lorin Beer 2012-06-28 15:36:28 -07:00
parent 3d5e2340ca
commit 0cf9f51816

273
framework/src/org/apache/cordova/AudioPlayer.java Executable file → Normal file
View File

@ -31,6 +31,8 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.cordova.AudioPlayer.MODE;
/** /**
* This class implements the audio playback and recording capabilities used by Cordova. * This class implements the audio playback and recording capabilities used by Cordova.
* It is called by the AudioHandler Cordova class. * It is called by the AudioHandler Cordova class.
@ -42,14 +44,19 @@ import java.io.IOException;
*/ */
public class AudioPlayer implements OnCompletionListener, OnPreparedListener, OnErrorListener { public class AudioPlayer implements OnCompletionListener, OnPreparedListener, OnErrorListener {
private static final String LOG_TAG = "AudioPlayer"; // AudioPlayer modes
public enum MODE { NONE, PLAY, RECORD };
// AudioPlayer states // AudioPlayer states
public static final int MEDIA_NONE = 0; public enum STATE { MEDIA_NONE,
public static final int MEDIA_STARTING = 1; MEDIA_LOADING,
public static final int MEDIA_RUNNING = 2; MEDIA_STARTING,
public static final int MEDIA_PAUSED = 3; MEDIA_RUNNING,
public static final int MEDIA_STOPPED = 4; MEDIA_PAUSED,
MEDIA_STOPPED
};
private static final String LOG_TAG = "AudioPlayer";
// AudioPlayer message ids // AudioPlayer message ids
private static int MEDIA_STATE = 1; private static int MEDIA_STATE = 1;
@ -66,15 +73,18 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
private AudioHandler handler; // The AudioHandler object private AudioHandler handler; // The AudioHandler object
private String id; // The id of this player (used to identify Media object in JavaScript) private String id; // The id of this player (used to identify Media object in JavaScript)
private int state = MEDIA_NONE; // State of recording or playback private MODE mode = MODE.NONE; // Playback or Recording mode
private STATE state = STATE.MEDIA_NONE; // State of recording or playback
private String audioFile = null; // File name to play or record to private String audioFile = null; // File name to play or record to
private float duration = -1; // Duration of audio private float duration = -1; // Duration of audio
private MediaRecorder recorder = null; // Audio recording object private MediaRecorder recorder = null; // Audio recording object
private String tempFile = null; // Temporary recording file name private String tempFile = null; // Temporary recording file name
private MediaPlayer mPlayer = null; // Audio player object private MediaPlayer player = null; // Audio player object
private boolean prepareOnly = true; private boolean prepareOnly = true; // playback after file prepare flag
private int seekOnPrepared = 0; // seek to this location once media is prepared
/** /**
* Constructor. * Constructor.
@ -86,18 +96,6 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
this.handler = handler; this.handler = handler;
this.id = id; this.id = id;
this.audioFile = file; this.audioFile = file;
this.mPlayer = new MediaPlayer();
try {
this.loadAudioFile(file);
} catch (Exception e) {
e.printStackTrace();
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
}
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
this.tempFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/tmprecording.mp3";
} else {
this.tempFile = "/data/data/" + handler.ctx.getActivity().getPackageName() + "/cache/tmprecording.mp3";
}
} }
/** /**
@ -105,13 +103,13 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
*/ */
public void destroy() { public void destroy() {
// Stop any play or record // Stop any play or record
if (this.mPlayer != null) { if (this.player != null) {
if ((this.state == MEDIA_RUNNING) || (this.state == MEDIA_PAUSED)) { if ((this.state == STATE.MEDIA_RUNNING) || (this.state == STATE.MEDIA_PAUSED)) {
this.mPlayer.stop(); this.player.stop();
this.setState(MEDIA_STOPPED); this.setState(STATE.MEDIA_STOPPED);
} }
this.mPlayer.release(); this.player.release();
this.mPlayer = null; this.player = null;
} }
if (this.recorder != null) { if (this.recorder != null) {
this.stopRecording(); this.stopRecording();
@ -126,12 +124,14 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
* @param file The name of the file * @param file The name of the file
*/ */
public void startRecording(String file) { public void startRecording(String file) {
if (this.mPlayer != null) { switch (this.mode) {
case PLAY:
Log.d(LOG_TAG, "AudioPlayer Error: Can't record in play mode."); Log.d(LOG_TAG, "AudioPlayer Error: Can't record in play mode.");
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});"); this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});");
} break;
case NONE:
// Make sure we're not already recording // Make sure we're not already recording
else if (this.recorder == null) { if (this.recorder == null) {
this.audioFile = file; this.audioFile = file;
this.recorder = new MediaRecorder(); this.recorder = new MediaRecorder();
this.recorder.setAudioSource(MediaRecorder.AudioSource.MIC); this.recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
@ -141,7 +141,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
try { try {
this.recorder.prepare(); this.recorder.prepare();
this.recorder.start(); this.recorder.start();
this.setState(MEDIA_RUNNING); this.setState(STATE.MEDIA_RUNNING);
return; return;
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
e.printStackTrace(); e.printStackTrace();
@ -150,7 +150,8 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
} }
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});"); this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});");
} }
else { break;
case RECORD:
Log.d(LOG_TAG, "AudioPlayer Error: Already recording."); Log.d(LOG_TAG, "AudioPlayer Error: Already recording.");
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});"); this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});");
} }
@ -179,9 +180,9 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
public void stopRecording() { public void stopRecording() {
if (this.recorder != null) { if (this.recorder != null) {
try{ try{
if (this.state == MEDIA_RUNNING) { if (this.state == STATE.MEDIA_RUNNING) {
this.recorder.stop(); this.recorder.stop();
this.setState(MEDIA_STOPPED); this.setState(STATE.MEDIA_STOPPED);
} }
this.moveFile(this.audioFile); this.moveFile(this.audioFile);
} }
@ -191,16 +192,21 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
} }
} }
//==========================================================================
// Playback
//==========================================================================
/** /**
* Start or resume playing audio file. * Start or resume playing audio file.
* *
* @param file The name of the audio file. * @param file The name of the audio file.
*/ */
public void startPlaying(String file) { public void startPlaying(String file) {
if (this.playerReady(file)) { if (this.readyPlayer(file)) {
this.mPlayer.start(); this.player.start();
this.setState(MEDIA_RUNNING); this.setState(STATE.MEDIA_RUNNING);
} else { } else {
//
this.prepareOnly = false; this.prepareOnly = false;
} }
} }
@ -209,11 +215,14 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
* Seek or jump to a new time in the track. * Seek or jump to a new time in the track.
*/ */
public void seekToPlaying(int milliseconds) { public void seekToPlaying(int milliseconds) {
if (this.playerReady(this.audioFile)) { if (this.readyPlayer(this.audioFile)) {
this.mPlayer.seekTo(milliseconds); this.player.seekTo(milliseconds);
Log.d(LOG_TAG, "Send a onStatus update for the new seek"); Log.d(LOG_TAG, "Send a onStatus update for the new seek");
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_POSITION + ", " + milliseconds / 1000.0f + ");"); this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_POSITION + ", " + milliseconds / 1000.0f + ");");
} }
else {
this.seekOnPrepared = milliseconds;
}
} }
/** /**
@ -222,12 +231,12 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
public void pausePlaying() { public void pausePlaying() {
// If playing, then pause // If playing, then pause
if (this.state == MEDIA_RUNNING) { if (this.state == STATE.MEDIA_RUNNING) {
this.mPlayer.pause(); this.player.pause();
this.setState(MEDIA_PAUSED); this.setState(STATE.MEDIA_PAUSED);
} }
else { else {
Log.d(LOG_TAG, "AudioPlayer Error: pausePlaying() called during invalid state: " + this.state); Log.d(LOG_TAG, "AudioPlayer Error: pausePlaying() called during invalid state: " + this.state.ordinal());
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_NONE_ACTIVE + "});"); this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_NONE_ACTIVE + "});");
} }
} }
@ -236,12 +245,12 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
* Stop playing the audio file. * Stop playing the audio file.
*/ */
public void stopPlaying() { public void stopPlaying() {
if ((this.state == MEDIA_RUNNING) || (this.state == MEDIA_PAUSED)) { if ((this.state == STATE.MEDIA_RUNNING) || (this.state == STATE.MEDIA_PAUSED)) {
this.mPlayer.stop(); this.player.stop();
this.setState(MEDIA_STOPPED); this.setState(STATE.MEDIA_STOPPED);
} }
else { else {
Log.d(LOG_TAG, "AudioPlayer Error: stopPlaying() called during invalid state: " + this.state); Log.d(LOG_TAG, "AudioPlayer Error: stopPlaying() called during invalid state: " + this.state.ordinal());
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_NONE_ACTIVE + "});"); this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_NONE_ACTIVE + "});");
} }
} }
@ -249,10 +258,10 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
/** /**
* Callback to be invoked when playback of a media source has completed. * Callback to be invoked when playback of a media source has completed.
* *
* @param mPlayer The MediaPlayer that reached the end of the file * @param player The MediaPlayer that reached the end of the file
*/ */
public void onCompletion(MediaPlayer mPlayer) { public void onCompletion(MediaPlayer player) {
this.setState(MEDIA_STOPPED); this.setState(STATE.MEDIA_STOPPED);
} }
/** /**
@ -261,8 +270,8 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
* @return position in msec or -1 if not playing * @return position in msec or -1 if not playing
*/ */
public long getCurrentPosition() { public long getCurrentPosition() {
if ((this.state == MEDIA_RUNNING) || (this.state == MEDIA_PAUSED)) { if ((this.state == STATE.MEDIA_RUNNING) || (this.state == STATE.MEDIA_PAUSED)) {
int curPos = this.mPlayer.getCurrentPosition(); int curPos = this.player.getCurrentPosition();
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_POSITION + ", " + curPos / 1000.0f + ");"); this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_POSITION + ", " + curPos / 1000.0f + ");");
return curPos; return curPos;
} }
@ -303,7 +312,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
} }
// If audio file already loaded and started, then return duration // If audio file already loaded and started, then return duration
if (this.mPlayer != null) { if (this.player != null) {
return this.duration; return this.duration;
} }
@ -321,31 +330,28 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
/** /**
* Callback to be invoked when the media source is ready for playback. * Callback to be invoked when the media source is ready for playback.
* *
* @param mPlayer The MediaPlayer that is ready for playback * @param player The MediaPlayer that is ready for playback
*/ */
public void onPrepared(MediaPlayer mPlayer) { public void onPrepared(MediaPlayer player) {
// Listen for playback completion // Listen for playback completion
this.mPlayer.setOnCompletionListener(this); this.player.setOnCompletionListener(this);
// If start playing after prepared // If start playing after prepared
if (!this.prepareOnly) { if (!this.prepareOnly) {
this.player.start();
// Start playing this.setState(STATE.MEDIA_RUNNING);
this.mPlayer.start();
// Set player init flag
this.setState(MEDIA_RUNNING);
} else { } else {
this.setState(MEDIA_STARTING); this.setState(STATE.MEDIA_STARTING);
} }
// Save off duration // Save off duration
this.duration = getDurationInSeconds(); this.duration = getDurationInSeconds();
// reset prepare only flag
this.prepareOnly = true; this.prepareOnly = true;
// seek to any location received while not prepared
this.seekToPlaying(this.seekOnPrepared);
// reset seek location
this.seekOnPrepared = 0;
// Send status notification to JavaScript // Send status notification to JavaScript
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_DURATION + "," + this.duration + ");"); this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_DURATION + "," + this.duration + ");");
} }
/** /**
@ -354,23 +360,23 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
* @return length of clip in seconds * @return length of clip in seconds
*/ */
private float getDurationInSeconds() { private float getDurationInSeconds() {
return (this.mPlayer.getDuration() / 1000.0f); return (this.player.getDuration() / 1000.0f);
} }
/** /**
* Callback to be invoked when there has been an error during an asynchronous operation * Callback to be invoked when there has been an error during an asynchronous operation
* (other errors will throw exceptions at method call time). * (other errors will throw exceptions at method call time).
* *
* @param mPlayer the MediaPlayer the error pertains to * @param player the MediaPlayer the error pertains to
* @param arg1 the type of error that has occurred: (MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_SERVER_DIED) * @param arg1 the type of error that has occurred: (MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_SERVER_DIED)
* @param arg2 an extra code, specific to the error. * @param arg2 an extra code, specific to the error.
*/ */
public boolean onError(MediaPlayer mPlayer, int arg1, int arg2) { public boolean onError(MediaPlayer player, int arg1, int arg2) {
Log.d(LOG_TAG, "AudioPlayer.onError(" + arg1 + ", " + arg2 + ")"); Log.d(LOG_TAG, "AudioPlayer.onError(" + arg1 + ", " + arg2 + ")");
// TODO: Not sure if this needs to be sent? // TODO: Not sure if this needs to be sent?
this.mPlayer.stop(); this.player.stop();
this.mPlayer.release(); this.player.release();
// Send error notification to JavaScript // Send error notification to JavaScript
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', { \"code\":" + arg1 + "});"); this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', { \"code\":" + arg1 + "});");
@ -382,12 +388,24 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
* *
* @param state * @param state
*/ */
private void setState(int state) { private void setState(STATE state) {
if (this.state != state) { if (this.state != state) {
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_STATE + ", " + state + ");"); this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_STATE + ", " + this.state.ordinal() + ");");
}
this.state = state;
} }
this.state = state; /**
* Set the mode and send it to JavaScript.
*
* @param state
*/
private void setMode(MODE mode) {
if (this.mode != mode) {
//mode is not part of the expected behaviour, so no notification
//this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_STATE + ", " + mode + ");");
}
this.mode = mode;
} }
/** /**
@ -396,7 +414,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
* @return int * @return int
*/ */
public int getState() { public int getState() {
return this.state; return this.state.ordinal();
} }
/** /**
@ -405,7 +423,26 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
* @param volume * @param volume
*/ */
public void setVolume(float volume) { public void setVolume(float volume) {
this.mPlayer.setVolume(volume, volume); this.player.setVolume(volume, volume);
}
/**
* attempts to put the player in play mode
* @return true if in playmode, false otherwise
*/
private boolean playMode() {
switch(this.mode) {
case NONE:
this.setMode(MODE.PLAY);
break;
case PLAY:
break;
case RECORD:
Log.d(LOG_TAG, "AudioPlayer Error: Can't play in record mode.");
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
return false; //player is not ready
}
return true;
} }
/** /**
@ -413,45 +450,51 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
* @param file the file to play * @param file the file to play
* @return false if player not ready, reports if in wrong mode or state * @return false if player not ready, reports if in wrong mode or state
*/ */
private boolean playerReady(String file) { private boolean readyPlayer(String file) {
//make sure we are in the right mode if (playMode()) {
if (this.recorder != null) { switch (this.state) {
Log.d(LOG_TAG, "AudioPlayer Error: Can't play in record mode."); case MEDIA_NONE:
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});"); if (this.player == null) {
return false; //player is not ready this.player = new MediaPlayer();
} }
if (this.mPlayer == null) {
this.mPlayer = new MediaPlayer();
try { try {
this.loadAudioFile(file);
} catch (Exception e) {
e.printStackTrace();
}
return false;
case MEDIA_LOADING:
//cordova js is not aware of MEDIA_LOADING, so we send MEDIA_STARTING insntead
Log.d(LOG_TAG, "AudioPlayer Loading: startPlaying() called during media preparation: " + STATE.MEDIA_STARTING.ordinal());
this.prepareOnly = false; this.prepareOnly = false;
return false;
case MEDIA_STARTING:
case MEDIA_RUNNING:
case MEDIA_PAUSED:
return true;
case MEDIA_STOPPED:
//if we are readying the same file
if (this.audioFile.compareTo(file) == 0) {
//reset the audio file
player.seekTo(0);
player.pause();
return true;
} else {
//reset the player
this.player.reset();
try {
this.loadAudioFile(file); this.loadAudioFile(file);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});"); this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
} }
//if we had to prepare= the file, we won't be in the correct state for playback
return false; return false;
} }
try {
switch (this.state) {
case MEDIA_STOPPED:
this.mPlayer.reset();
this.loadAudioFile(file);
return true;
case MEDIA_PAUSED:
return true;
case MEDIA_STARTING:
return true;
case MEDIA_RUNNING:
return true;
default: default:
Log.d(LOG_TAG, "AudioPlayer Error: startPlaying() called during invalid state: " + this.state); Log.d(LOG_TAG, "AudioPlayer Error: startPlaying() called during invalid state: " + this.state);
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});"); this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
} }
} catch (Exception e) {
e.printStackTrace();
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
} }
return false; return false;
} }
@ -465,33 +508,33 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
*/ */
private void loadAudioFile(String file) throws IllegalArgumentException, SecurityException, IllegalStateException, IOException { private void loadAudioFile(String file) throws IllegalArgumentException, SecurityException, IllegalStateException, IOException {
if (this.isStreaming(file)) { if (this.isStreaming(file)) {
this.mPlayer.setDataSource(file); this.player.setDataSource(file);
this.mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); this.player.setAudioStreamType(AudioManager.STREAM_MUSIC);
//altered meaning of states here //if it's a streaming file, play mode is implied
//this.setState(MEDIA_STARTING); this.setMode(MODE.PLAY);
this.setState(MEDIA_NONE); this.setState(STATE.MEDIA_STARTING);
this.mPlayer.setOnPreparedListener(this); this.player.setOnPreparedListener(this);
this.mPlayer.prepareAsync(); this.player.prepareAsync();
} }
else { else {
if (file.startsWith("/android_asset/")) { if (file.startsWith("/android_asset/")) {
String f = file.substring(15); String f = file.substring(15);
android.content.res.AssetFileDescriptor fd = this.handler.ctx.getActivity().getAssets().openFd(f); android.content.res.AssetFileDescriptor fd = this.handler.ctx.getActivity().getAssets().openFd(f);
this.mPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength()); this.player.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
} }
else { else {
File fp = new File(file); File fp = new File(file);
if (fp.exists()) { if (fp.exists()) {
FileInputStream fileInputStream = new FileInputStream(file); FileInputStream fileInputStream = new FileInputStream(file);
this.mPlayer.setDataSource(fileInputStream.getFD()); this.player.setDataSource(fileInputStream.getFD());
} }
else { else {
this.mPlayer.setDataSource("/sdcard/" + file); this.player.setDataSource("/sdcard/" + file);
} }
} }
//this.setState(MEDIA_STARTING); this.setState(STATE.MEDIA_STARTING);
this.mPlayer.setOnPreparedListener(this); this.player.setOnPreparedListener(this);
this.mPlayer.prepare(); this.player.prepare();
// Get duration // Get duration
this.duration = getDurationInSeconds(); this.duration = getDurationInSeconds();