Want to package a small video in the package for deployment - android

Is there any way to reference programmatically a very small video file adn include it in teh package - i.e. I don't want to have it separate on the SD card. I am thinking of putting it in the 'raw' package directory.
E.g. MPEG4 called 'video' in 'raw'
Am trying to work out what the correct format for Uri.parse() but it has beaten me. I thought it should be something like R.raw (as used when setting up a media player for audio myMediaPlayer = MediaPlayer.create(this, R.raw.audiocameralive1) - but it doesn't seem to be.
Any suggestions
Oliver

I see there have been a number of views, so in case anyone is looking for a solution, this is what I eventually did - and seems to work fine. There is probably cleaner way of doing the same but, this one makes sense to me ...
Oliver
public class ShowVideoActivity extends Activity
implements SurfaceHolder.Callback,
OnErrorListener,
OnPreparedListener,
OnCompletionListener
{
/** Called when the activity is first created. */
private MediaPlayer myMediaPlayer;
boolean bolMediaPlayerIsReleased = false;
// The SurfaceHolder and SurfaceView are used to display the video
// By implementing the SurfaceHolder.Callback interface means that we have
// to implement surfaceChanged(), surfaceCreated() and surfaceDestroyed()
private SurfaceView videoSurface;
private SurfaceHolder videoHolder;
Display currentDisplay;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.showvideo); // Inflate ShowVideo
// Identify the Surface that will be used to hold the camera image
videoSurface = (SurfaceView)findViewById(R.id.videosurface);
// The SurfaceHolder 'monitors' activity on the Surface
videoHolder = videoSurface.getHolder();
videoHolder.setKeepScreenOn(true);
// Data will be Pushed onto the buffers external to the surface
videoHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
videoHolder.setKeepScreenOn(true);
// Let the monitor know that 'this' activity is responsible for
// all the callback functions.
videoHolder.addCallback(this);
// It is now up to the 'callbacks' to do any further processing
myMediaPlayer = MediaPlayer.create(this,R.raw.filename);
myMediaPlayer.setOnCompletionListener(this);
myMediaPlayer.setOnErrorListener(this);
myMediaPlayer.setOnPreparedListener(this);
myMediaPlayer.setOnCompletionListener(this);
currentDisplay = getWindowManager().getDefaultDisplay();
}
// Set up a listener to wait for MediaPlayer End (Is this PlaybackCompleted()?)
public void onCompletion(MediaPlayer mp)
{
Wrapup(mp);
}
public void surfaceCreated(SurfaceHolder CreatedHolder) {
// Surface created, now it is possible to set the preview
myMediaPlayer.setDisplay(CreatedHolder);
}
public void surfaceDestroyed(SurfaceHolder DestroyedHolder)
{
if (myMediaPlayer != null)
{
if (myMediaPlayer.isPlaying() )
myMediaPlayer.stop();
myMediaPlayer.release();
bolMediaPlayerIsReleased = true;
}
}
public void surfaceChanged(SurfaceHolder ChangedHolder, int intFormat, int intWidth, int intHeight)
{
if (myMediaPlayer.isPlaying())
return;
else
{
setVideoSurfaceSize(myMediaPlayer);
myMediaPlayer.start();
}
}
public boolean onError(MediaPlayer mPlayer, int intError, int intExtra)
{
return false;
}
public void onPrepared(MediaPlayer mPlayer)
{
setVideoSurfaceSize(mPlayer);
mPlayer.start();
// From the 'Started' mode, the player can either be 'Stopped', 'Paused' or PlaybackCompleted'
} // End onPrepared
public void Wrapup(MediaPlayer mp)
{
if (mp != null)
{
if (myMediaPlayer.isPlaying() )
mp.stop();
mp.release();
bolMediaPlayerIsReleased = true;
}
// Now clean up before terminating. This is ESSENTIAL
// If cleanup is NOT done then the surfaceDestroyed will get called
// and screw up everything
// Firstly remove the callback
videoHolder.removeCallback(this); // Prevents callbacks when the surface is destroyed
ShowVideoActivity.this.finish();
}
}

Use Activity.getAssets() to get an AssetManager. The load the file with open.

Related

android app with multiple media players in same activity - how to use efficiently

I am creating an android activity that will have many mediaplayers inside. The activity will have many mediaplayer objects and if i could describe it its like a
4 X 1 grid of media players. I created the 4X1 grid by using TextureView class's in android.
so the xml layout for the activity looks like this more or less:
<TextureView
android:id="#+id/surface_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextureView
android:id="#+id/surface_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextureView
android:id="#+id/surface_three"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextureView
android:id="#+id/surface_four"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
So each textureView will be the surface where the MediaPlayers will play there video.
programatically i've set up SurfaceTextureListener's so that i know when the surface is available like this for each one:
TextureView tv1 = (TextureView)findViewById(R.id.surface_one);
tv1.setSurfaceTextureListener(new SurfaceListener_1());
and likewise for the rest. here is how i would do the second texture view setup:
TextureView tv2 = (TextureView)findViewById(R.id.surface_two);
tv2.setSurfaceTextureListener(new SurfaceListener_2());
Then in code i am creating 4 MediaPlayer Objects and setting there surface like this for mediaplayer #1:
private class SurfaceListener_1 implements TextureView.SurfaceTextureListener {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
Surface sfc = new Surface(surface);
try {
m_mp1 = new MediaPlayer();
m_mp1.setSurface(sfc); //critical , here i am adding the surface so the media player can play on it
m_mp1.setDataSource(m_context, m_videoUri_one);
m_mp1.prepareAsync();
m_mp1.setLooping(true);
m_mp1.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
video1Prepared = true;
}
});
m_mp1.setOnErrorListener(new MediaPlayer.OnErrorListener(){
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return true;
}
});
} catch (Exception e) {
e.printStackTrace();
}
finally {
//release the surface as its now set in the media player
if(sfc!=null)
sfc.release();
}
}
//...... the rest of the call backs not important...
and for the other media players i repeat the same thing so that they all have surfaces to play on. here is how i would do mediaplayer # 2:
private class SurfaceListener_2 implements TextureView.SurfaceTextureListener {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
Surface sfc = new Surface(surface);
try {
m_mp2 = new MediaPlayer();
m_mp2.setSurface(sfc); //critical , here i am adding the surface so the media player can play on it
m_mp2.setDataSource(m_context, m_videoUri_two);
m_mp2.prepareAsync();
m_mp2.setLooping(true);
m_mp2.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
video2Prepared = true;
}
});
m_mp2.setOnErrorListener(new MediaPlayer.OnErrorListener(){
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return true;
}
});
} catch (Exception e) {
e.printStackTrace();
}
finally {
//release the surface as its now set in the media player
if(sfc!=null)
sfc.release();
}
}
//...... the rest of the call backs not important...
so in the end what i have created is 4 surfaces where i can play a video. All 4 media players play different video files.
Once all the media players are prepared, i call their start() method on all of them and they play at the same time.
The issue i am facing is that this can be cpu intensive. On some devices i can get a ANR or the app just gets slow to respond.
The media file i am playing is a MP4 and the size of the media files are all about 9 MB.
Is there anything you can recommend so that i can be more cpu efficient in this already heavy task ? For example, can i get the GPU to help ?
Or if i change media type will that make it more efficient ? the video's do not have sound there only visual if that helps.

Android MediaPlayer : IllegalStateException when app closes/press back button

Im streaming an mp3 audio from a url by using mediaplayer, Now im able to play music , But when i press back button or close the app, it crashes.
can anyone pls help me to find my mistake.
thank you.
My code is :
private ImageView play, forward, backward;
private MediaPlayer mediaPlayer;
private boolean playing = false;
private ProgressDialog dialog;
private String mp3link;
private SeekBar seekbar;
private Handler handler = new Handler();
private int mediaPos;
private int mediaMax;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final String url ="";
initWidgets();
}
private void initWidgets() {
mp3link = "http://loc8app.com/church/uploads/audio/749928ad6fcb7b1aceefdf03bd7a9465.mp3";
play = (ImageView) findViewById(R.id.control);
seekbar = (SeekBar) findViewById(R.id.seekBar);
// forward = (ImageView) findViewById(R.id.playeer_forward);
// backward = (ImageView) findViewById(R.id.playeer_back);
mediaPlayer = new MediaPlayer();
play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
playFunction();
}
});
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(mediaPlayer != null && fromUser){
mediaPlayer.seekTo(progress);
}
}
});
}
private void playFunction() {
if (!playing) {
try {
dialog = ProgressDialog
.show(MainActivity.this,
"",
getString(com.root5solutions.music.R.string.buffering),
true);
dialog.setCancelable(true);
dialog.show();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(mp3link);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
play.setBackgroundResource(R.drawable.pause);
playing = true;
//this is new
mediaPos = mp.getCurrentPosition();
mediaMax = mp.getDuration();
seekbar.setMax(mediaMax);
seekbar.setProgress(mediaPos);
//this line is the error
handler.removeCallbacks(moveSeekBarThread);
handler.postDelayed(moveSeekBarThread, 100);
mp.start();
dialog.dismiss();
}
});
mediaPlayer.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
dialog.dismiss();
}
} else {
play.setBackgroundResource(R.drawable.play);
mediaPlayer.stop();
mediaPlayer.release();
playing = false;
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
private Runnable moveSeekBarThread = new Runnable() {
public void run() {
if (mediaPlayer.isPlaying()) {
int mediaPos_new = mediaPlayer.getCurrentPosition();
int mediaMax_new = mediaPlayer.getDuration();
seekbar.setMax(mediaMax_new);
seekbar.setProgress(mediaPos_new);
handler.postDelayed(this, 1000); // Looping the thread after 1 second
}
}
};
}
Logcat shows :
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.root.music, PID: 26981
java.lang.IllegalStateException
at android.media.MediaPlayer.isPlaying(Native Method)
at com.root.music.MainActivity$4.run(MainActivity.java:132)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5351)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:947)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:742)
The issue appears to be being caused by the moveSeekBarThread Runnable, from which the exception is being raised, continuing to execute after mediaPlayer is released in onBackPressed(). This results in the the isPlaying() method being executed, which as per the documentation will result in an IllegalStateException:
if the internal player engine has not been initialized or has been released.
Looking at moveSeekBarThread, it seems to be configured to reschedule itself endlessly by posting itself back into the handler Handler instance with a delay. This process is not being stopped when the user leaves the activity, which explains why moveSeekBarThread keeps running. So, based on the above, one solution could be to make sure that any instances of moveSeekBarThread in handler's queue are removed before calling mediaPlayer.release() when the user leaves the activity.
You should be able to do that by calling handler.removeCallbacks(moveSeekBarThread); before you call mediaPlayer.release(). For example, as follows:
#Override
public void onBackPressed() {
super.onBackPressed();
handler.removeCallbacks(moveSeekBarThread);
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
It should be okay to call it right before mediaPlayer.release(), but I think it's safer to call it regardless of whether mediaPlayer is playing. This way, if the Runnable does get or remain started somehow despite the media player not having being started or having been stopped, the Runnable will still be cleared.
As an aside, while I don't have any experience with MediaPlayer, I happened to notice that the documentation of the release method has the following to say:
It is considered good practice to call this method when you're done using the MediaPlayer. In particular, whenever an Activity of an application is paused (its onPause() method is called), or stopped (its onStop() method is called), this method should be invoked to release the MediaPlayer object, unless the application has a special need to keep the object around. In addition to unnecessary resources (such as memory and instances of codecs) being held, failure to call this method immediately if a MediaPlayer object is no longer needed may also lead to continuous battery consumption for mobile devices, and playback failure for other applications if no multiple instances of the same codec are supported on a device.
So unless there is that special need to keep the media player around in the activity in your case, it might be better to handle the release process (including clearing moveSeekBarThread from handler) in onPause or onStop instead.
Hope that helps!
you are getting IllegalStateException .
Signals that a method has been invoked at an illegal or inappropriate
time .
Call super.onBackPressed(); after if condition
#Override
public void onBackPressed()
{
if (mediaPlayer!= null)
{
if(mediaPlayer.isPlaying())
mediaPlayer.stop();
mediaPlayer.release();
}
super.onBackPressed(); // Call here
}
First you need to understand what illegalStateException means:
According to Android docs:
It Signals that a method has been invoked at an illegal or inappropriate time. In other words, the Java environment or Java application is not in an appropriate state for the requested operation.
have a look at the state diagram of a media player:
https://developer.android.com/images/mediaplayer_state_diagram.gif
Calling setDataSource(FileDescriptor), or setDataSource(String), or setDataSource(Context, Uri), or setDataSource(FileDescriptor, long, long), or setDataSource(MediaDataSource) transfers a MediaPlayer object in the Idle state to the Initialized state.
An IllegalStateException is thrown if setDataSource() is called in any other state.
It is good programming practice to always look out for IllegalArgumentException and IOException that may be thrown from the overloaded setDataSource methods.

Soundpool or MediaPlayer ? - Android

I am so confused of those two classes.
I have a problem that I have 1000 of .wav files, it depends on user to load different sounds.
as well as, user can play many sounds in a row, like 4 sounds sequentially.
so which should I use? SoundPool is better for wav files but it is not good that it loads and keep the files loaded.
any recommendation for this situation?
I have done it on my way using MediaPlayer, Thanks for #blipinsk, After i read this answer StackOverFlow suggested by him in the comment above.
My files are a bit larger that SoundPool can tolerate, as well as, I want to play many files sequentially. Which i had to implement it myself using threads in SoundPool. On the contrary, It is ready in MediaPlayer using OnCompletionListener. So that, I used MediaPlayer.
Actually i tried SoundPool with threads, it works but since it does not support large media files, i used Media Player.
I wrote this class which wrap the MediaPlayer to run a playList, you can add to the playlist and the media player will run them one after another. so here is the class:
import android.media.MediaPlayer;
import android.os.Environment;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Created by MBH on 01.08.2015.
*/
public class THSafeListMediaPlayer {
private static final String TAG_DEBUG = "MBH";
private String PATH_OF_SOUND_FILES; // I use it because i will put all sound clips in one folder
// , then i will pass the name of the folder only.
private LinkedBlockingQueue<String> playList;
private MediaPlayer mediaPlayer; // The media player to play the sounds, even in background
private ExecutorService executorService; // For making sure there is only one thread at a time
// adding to the queue
private boolean isPaused = false;
private int pausedPosition = -1;
/**
* Constructor will take care of initializing all the important variables
*/
public THSafeListMediaPlayer() {
// initializing the variables
executorService = Executors.newSingleThreadExecutor();
playList = new LinkedBlockingQueue<>();
mediaPlayer = new MediaPlayer();
PATH_OF_SOUND_FILES = Environment.getExternalStorageDirectory().getPath() + "/mbh/sounds/";
}
/**
* It will only add file to the PlayList
*
* #param fileName: The file name
*/
public void addFile(String fileName) {
// you may add executorService here for safer threads adding here
// here i use offer, because it is thread safe
playList.offer(fileName);
}
/**
* It will add file and play the last add file and continue to the play list
*
* #param fileName: the file name, playing the soundtrack will start from this file
*/
public void addFileAndPlay(final String fileName) {
// For MultiThreaded
// executorService.submit(new Runnable() {
// #Override
// public void run() {
// playList.offer(fileName);
// if (!mediaPlayer.isPlaying())
// play(playList.poll());
// }
// });
// For single threaded
playList.offer(fileName);
if (!mediaPlayer.isPlaying())
play(playList.poll());
}
/**
* Start playing the play list if there is files in the playlist
*
* #return: True if playing successfully done, otherwise, false;
*/
public boolean play() {
if (mediaPlayer != null) {
if (!mediaPlayer.isPlaying()) {
if (isPaused) {
mediaPlayer.seekTo(pausedPosition);
mediaPlayer.start();
pausedPosition = -1;
isPaused = false;
return true;
} else if (!playList.isEmpty()) {
play(playList.poll());
return true;
}
}
}
return false;
}
/**
* Pause the current played track, if there is track playing
*/
public void pause() {
if(isPaused)
return;
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
pausedPosition = mediaPlayer.getCurrentPosition();
isPaused = true;
}
}
}
/**
* it will play the given file, when it finishes, or fails, it will play the next from the list
*
* #param fileName: the file name to start playing from it
*/
private void play(String fileName) {
if (mediaPlayer != null) {
if (!mediaPlayer.isPlaying()) {
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(fileName);
mediaPlayer.prepare();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
playNextSoundTrack();
}
});
mediaPlayer.start();
} catch (Exception e) {
// TODO: Remove this error checking before publishin
// If the current file is not found, play the next track if there is
playNextSoundTrack();
}
}
}
}
/**
* this function will be called recursively to play the next track
*/
private void playNextSoundTrack() {
if (playList.size() != 0) {
play(playList.poll());
}
}
}
I struggled for a while with it. I hope it will help others.
NOTE: I used LinkedBlockingQueue to keep the playList tracks in it, because it is implemented to be thread safe.
If you want to use this class in threads, i suggest you to use the executorService if u will use it in multithreaded app.

Best way to pass a SurfaceView to android.media.MediaPlayer

I'm writing an app that consumes media (audio/video) and that allows users to reply and/or post new media.
My question relates to the SurfaceView used to display the videos. This SurfaceView object is shared between the MediaRecorder (recording a video) and the MediaPlayer (consuming/playing the video).
The MediaPlayer is located on its own Service, which runs on its own thread, as per the NPR example: PlaybackService.java
Since the NPR example doesn't involve video, I was not sure about how to make the MediaPlayer on the Service aware of the SurfaceView in the UI. I ended up using a static variable to solve this issue:
// MyFragmentClass.java
// CameraPreview is the sample class shown int he media section
// of the Android Developer site:
// http://developer.android.com/guide/topics/media/camera.html#camera-preview
private static CameraPreview sCameraPreview;
#Override
public void onStart() {
super.onStart();
CameraPreview cameraPreview = new CameraPreview(getActivity());
FrameLayout preview = (FrameLayout) getView().findViewById(R.id.video_preview);
preview.addView(cameraPreview);
setCameraPreview(cameraPreview); // a static setter.
// Other classes are initialized afterwards, not relevant to this question...
}
public static CameraPreview getCameraPreview() {
return sCameraPreview;
}
public static void setCameraPreview(CameraPreview cameraPreview) {
sCameraPreview = cameraPreview;
}
Here's the method on the PlaybackService that takes care of preparing a video for playback:
// Params url and isVideo were extras on an Intent that triggers
// this method
synchronized private void prepareMediaPlayer(String url, boolean isVideo) {
if (mMediaPlayer == null) {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnErrorListener(this);
mMediaPlayer.setOnInfoListener(this);
mMediaPlayer.setOnPreparedListener(this);
} else {
mMediaPlayer.reset();
}
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setDataSource(mediaUrl);
if (isVideo) {
// this is the important line
mMediaPlayer.setDisplay(MyFragmentClass.getCameraPreview().getHolder());
mMediaPlayer.setScreenOnWhilePlaying(true);
}
mMediaPlayer.prepareAsync();
sendIntent(STATUS_PLAYBACK_PREPARED);
}
It gets the job done, but I'm wondering if there's any better way to do it, specially because I'm debugging a random bug where the shared surface is not released, and it got me thinking:
Is there a better way to make my service class aware of the Service?
Is it a good approach to have a single SurfaceView for both Recording and Playback?
Thanks!

MediaPlayer gives different results if it has to wait longer before .start() is called

I'm trying to use a MediaPlayer instance to play several audio files individually, in response to various sensor events.
I've found that when I load up the clip to be played right before calling MediaPlayer.start(), the audio clip will play fine. However, the application takes a major performance hit. Ideally, each audio clip should be loaded into the MediaPlayer immediately after the last one was played, leaving the MediaPlayer ready to start playback the instant the SensorEvent comes in.
I would expect this to be simple, but now that I made the change the audio just doesn't play. PlayAudioClip() is definitely still being called as expected, but something is going wrong after that. No errors are thrown, so I don't think the MediaPlayer is changing state, but could something be interfering with in the time that it's waiting to play?
Here is a simplified version of my code:
public class MainActivity extends Activity implements SensorEventListener {
private Random numGenerator;
private SensorManager manager;
private Sensor accelerometer;
private MediaPlayer mediaPlayer;
private Uri[] audioClips;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initVariables();
prepareNextAudioClip(); //load first audioClip
}
#Override
public void onSensorChanged(SensorEvent event) {
if(conditionsRight()){
playAudioClip();
}
}
}
private void playAudioClip() {
mediaPlayer.start();
prepareNextAudioClip();
}
private void prepareNextAudioClip() {
try {
mediaPlayer.reset();
Uri audioClip = audioclips[(int) Math.floor(numGenerator.nextDouble()*audioClips.length)];
mediaPlayer.setDataSource(this, audioClip);
mediaPlayer.prepare();
} catch (Exception e) {
e.printStackTrace();
}
}
//Code below here isn't very important... handling setup and teardown
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
protected void onResume() {
super.onResume();
manager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI);
}
private void initVariables() {
audioClips = new Uri[]{
Uri.parse("android.resource://com.example.afraidofflying/" + R.raw.audio1),
Uri.parse("android.resource://com.example.afraidofflying/" + R.raw.audio2),
Uri.parse("android.resource://com.example.afraidofflying/" + R.raw.audio3)
};
numGenerator = new Random();
mediaPlayer = new MediaPlayer();
manager = (SensorManager)getSystemService(SENSOR_SERVICE);
accelerometer = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if(null == accelerometer) finish();
}
protected void onPause() {
super.onPause();
manager.unregisterListener(this);
}
protected void onDestroy(){
mediaPlayer.release();
mediaPlayer = null;
}
}
PS: This has all been assuming I'll only use one instance of MediaPlayer but I'd also like input on if you think using multiple MediaPlayers and delegating each of them 1 audio clip would be advisable. My intuition is no because for my purposes I'd have to use 10-20 MediaPlayers, but it would be good to hear outside perspectives on it.
It's because you're resetting player right after starting playback.
private void playAudioClip() {
mediaPlayer.start(); //starting playback
prepareNextAudioClip(); //reset
}
if you want to play files in queue, than you can use one instance. But if you have to play several files simultaneusly, then you need to have several media player instances.
I think you have to look at subtle points regarding using Mediaplayer class
In your code you used:
initVariables();
prepareNextAudioClip(); //load first audioClip
initVariables() seems ok, Now lets see prepareNextAudioClip()
...
mediaPlayer.reset();
...
...
mediaPlayer.prepare();
The above code seems to corrupt Mediaplayer state machine. Please refer to http://developer.android.com/reference/android/media/MediaPlayer.html for details on using new, prepare,reset. It is better to write defensive MediaPlayer code using Errorlistener

Categories

Resources