I try to play video in surfaceview. I use Fragment (extends Fragment) and I have NullPointerException. I have no idea what am I doing wrong. First time I used Activity and in Activity project worked perfect but I use Fragment and I have error
This is a my source
public class Layout1 extends Fragment implements OnBufferingUpdateListener,
OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener,
SurfaceHolder.Callback, MediaPlayerControl {
MediaPlayer mMediaPlayer;
SurfaceView mSurfaceView;
SurfaceHolder holder;
String video = "http://www.pocketjourney.com/downloads/pj/video/famous.3gp";
MediaController mcontroller;
Handler handler;
String videoUrl;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout1, null);
SurfaceView v = (SurfaceView) view
.findViewById(R.id.screen_tutorial_video_surface);
handler = new Handler();
holder = v.getHolder();
holder.addCallback(this);
playVideo();
return view;
}
private void playVideo() {
try {
mcontroller = new MediaController(getActivity());
mcontroller.setVisibility(View.INVISIBLE);
mMediaPlayer = MediaPlayer.create(getActivity(), Uri.parse(video));
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.setOnVideoSizeChangedListener(this);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
mMediaPlayer.setDisplay(holder);
try {
// progressDialog.dismiss();
mMediaPlayer.start();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
}
#Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void onPrepared(MediaPlayer mp) {
// mcontroller.setMediaPlayer(this);
// mcontroller
// .setAnchorView(findViewById(R.id.screen_tutorial_video_surface));
// mcontroller.setEnabled(true);
//
// handler.post(new Runnable() {
// public void run() {
// mcontroller.show();
// }
// });
}
#Override
public void onCompletion(MediaPlayer mp) {
}
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
}
public void start() {
mMediaPlayer.start();
}
public void pause() {
mMediaPlayer.pause();
}
public int getDuration() {
return mMediaPlayer.getDuration();
}
public int getCurrentPosition() {
return mMediaPlayer.getCurrentPosition();
}
public void seekTo(int i) {
mMediaPlayer.seekTo(1);
}
public boolean isPlaying() {
return mMediaPlayer.isPlaying();
}
public int getBufferPercentage() {
return 0;
}
public boolean canPause() {
return true;
}
public boolean canSeekBackward() {
return true;
}
public boolean canSeekForward() {
return true;
}
}
Error log
It seems that onSurfaceCreated is called before playVideo(). Initialize your mMediaPlayer (and handler too by the way) in Fragment's onCreate().
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handler = new Handler();
playVideo();
}
private void playVideo() {
mcontroller = new MediaController(getActivity());
mcontroller.setVisibility(View.INVISIBLE);
mMediaPlayer = MediaPlayer.create(getActivity(), Uri.parse(video));
// implement a fallback mechanism if it fails, for example if no internet or 404
if (mMediaPlayer == null) {
Log.w("Layout1", "Faileded to create MediaPlayer");
return;
}
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.setOnVideoSizeChangedListener(this);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout1, null);
SurfaceView v = (SurfaceView) view
.findViewById(R.id.screen_tutorial_video_surface);
v.getHolder().addCallback(this);
return view;
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
if (mMediaPlayer == null) {
// implement a fallback mechanism if it fails, for example if no internet or 404
Log.w("Layout1", "MediaPlayer was not created");
return;
}
// the holder reference is already passed as arg0 here
mMediaPlayer.setDisplay(arg0);
try {
// progressDialog.dismiss();
mMediaPlayer.start();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
After you removed catch (Exception e) in playVideo()
If you looked closely in logs you could have seen
Permission failure: android.permission.INTERNET from uid=10052 pid=1129
Request requires android.permission.INTERNET
Unable to create media player
create failed:
java.io.IOException: setDataSource failed.: status=0x80000000
Thus you also need to add permission
<uses-permission android:name="android.permission.INTERNET"/>
If it wasn't for the project you've attached we would never knew.
Related
I am trying to build a video player using surface view and media player. My data source is an online video and I have enabled internet permission in manifest.
However, the video does not pay but throws a warning about prepare method without any hint at what the problem is like below:
W/System.err: at android.media.MediaPlayer._prepare(Native Method)
at android.media.MediaPlayer.prepare(MediaPlayer.java:1188)
at in.sashi.androidvideoplayer.MainActivity.surfaceCreated(MainActivity.java:64)
here's my code for this purpose:
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, MediaPlayer.OnPreparedListener, View.OnClickListener {
private static final String TAG = MainActivity.class.getSimpleName();
private SurfaceView surfaceView;
private ImageView playIV, backIV;
private TextView videoNameTV;
private MediaPlayer mediaPlayer;
private SurfaceHolder holder;
// private static final String VIDEO_URL = "https://www.youtube.com/watch?v=vEVd0QMjCc8";
private static final String VIDEO_URL = "http://mic.duytan.edu.vn:83/FINAL.mp4";
private static final String VIDEO_NAME = "FALL HARDER | BASKETBALL MOTIVATION";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
surfaceView = findViewById(R.id.surfsceView);
playIV = findViewById(R.id.playIV);
backIV = findViewById(R.id.backIV);
videoNameTV = findViewById(R.id.videoNameTV);
videoNameTV.setText(VIDEO_NAME);
backIV.setOnClickListener(this);
playIV.setOnClickListener(this);
holder = surfaceView.getHolder();
holder.addCallback(this);
surfaceView.setKeepScreenOn(true);
mediaPlayer = new MediaPlayer();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
mediaPlayer.setDisplay(holder);
try {
mediaPlayer.setDataSource(VIDEO_URL);
mediaPlayer.prepare();
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.backIV:
onBackPressed();
break;
case R.id.playIV:
if (mediaPlayer.isPlaying()){
Log.d(TAG, "Pause Clicked");
mediaPlayer.pause();
playIV.setImageResource(R.drawable.play);
} else {
Log.d(TAG, "Play Clicked");
mediaPlayer.start();
playIV.setImageResource(R.drawable.pause);
}
break;
}
}
#Override
protected void onPause() {
super.onPause();
collect();
}
private void collect() {
if (mediaPlayer != null){
mediaPlayer.release();
mediaPlayer = null;
}
}
}
Can anyone help me to figure this out? Thanks.
Use mediaplayer object which is being defined globally.
#Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
}
How about this?
#Override
public void surfaceCreated(SurfaceHolder holder) {
mediaPlayer.setDisplay(holder);
try {
mediaPlayer.setDataSource(VIDEO_URL);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
}
I have a fragment where i am using media player and using my own custom controller class. I am not being able to set controller.setMediaPlayer inside fragment. I have implemented VideoControllerView.MediaPlayerControl class in fragment.
My fragment class is :
public class HomeFragment extends Fragment implements SurfaceHolder.Callback, VideoControllerView.MediaPlayerControl {
#BindView(R.id.videoSurfaceContainer)
FrameLayout videoContainer;
#BindView(R.id.videoSurface)
SurfaceView videoSurface;
#BindView(R.id.progress)
ProgressBar progressBar;
#BindView(R.id.errorTv)
RelativeLayout relativeLayout;
#BindView(R.id.errorTextView)
TextView errorTextView;
public MediaPlayer player;
public VideoControllerView controller;
private Context context;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_home, container, false);
ButterKnife.bind(this, v);
player = new MediaPlayer();
controller = new VideoControllerView(getActivity());
SurfaceHolder videoHolder = videoSurface.getHolder();
videoHolder.addCallback(this);
progressBar.setVisibility(View.VISIBLE);
playVideo("http://202.166.200.170:8081/otv/aastha.stream/playlist.m3u8");
relativeLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
relativeLayout.setVisibility(View.GONE);
player.reset();
progressBar.setVisibility(View.VISIBLE);
playVideo("http://202.166.200.170:8081/otv/aastha.stream/playlist.m3u8");
} catch (Exception e) {
e.printStackTrace();
}
}
});
return v;
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
player.setDisplay(surfaceHolder);
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
}
public void playVideo(String link) {
try {
videoSurface.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (controller.isShowing())
controller.hide();
else
controller.show();
return false;
}
});
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
controller.setMediaPlayer();
controller.setAnchorView((FrameLayout) getActivity().findViewById(R.id.videoSurfaceContainer));
player.start();
progressBar.setVisibility(View.GONE);
if (relativeLayout.isShown())
relativeLayout.setVisibility(View.GONE);
}
});
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDataSource(getActivity(), Uri.parse(link));
try {
player.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
player.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
progressBar.setVisibility(View.GONE);
errorMessage("Streaming Error");
player.reset();
errorTextView.setText(getResources().getString(R.string.error_msg_video));
return false;
}
});
player.setScreenOnWhilePlaying(true);
Log.d("after click", "last try");
} catch (Exception e) {
e.printStackTrace();
}
}
public void errorMessage(String message) {
try {
relativeLayout.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void start() {
}
#Override
public void pause() {
}
#Override
public int getDuration() {
return 0;
}
#Override
public int getCurrentPosition() {
return 0;
}
#Override
public void seekTo(int pos) {
}
#Override
public boolean isPlaying() {
return false;
}
#Override
public boolean canPause() {
return false;
}
#Override
public boolean isFullScreen() {
return false;
}
#Override
public void toggleFullScreen() {
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
context = activity;
}
if you see inside playVideo method inside setOnpreparedListener i am getting error in controller.setMediaPlayer() because i am not being able to pass the context here.
what can be done here to solve the error?
This is how we can use controller.setMediaPlayer()
// Implement MediaPlayer.OnPreparedListener
#Override
public void onPrepared(MediaPlayer mp) {
controller.setMediaPlayer(this);
controller.setAnchorView((FrameLayout)
findViewById(R.id.videoSurfaceContainer));
player.start();
}
// End MediaPlayer.OnPreparedListener
This is example to use costume controller
If you want, you could get the context from there using HomeFragment.this.getContext(), like:
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
controller.setMediaPlayer(HomeFragment.this.getContext());
controller.setAnchorView((FrameLayout) getActivity().findViewById(R.id.videoSurfaceContainer));
player.start();
progressBar.setVisibility(View.GONE);
if (relativeLayout.isShown())
relativeLayout.setVisibility(View.GONE);
}
});
I just moved controller.setMediaPlayer(this); to onCreateView and it worked.
I've implemented a recycler view and each item will play video. My problem is that I need to pause/play the video when it scrolls on/off the screen.
I've implemented that when the user scrolls the video keeps playing.
I have had an issue trying to keep track of the media player when the view scrolls off screen.
I have come up with a solution and I'm hoping I can get some advice to see if may be any issues with the solution.
So I'm using a texture view to display the media player in the recycler view as videoviews aren't compatible when looking to use a recycler or customise the controller.
So in the surface texture destroyed (signalling that the view has left the screen) I pause the media player and when the surfacetexture is available (signalling the view is on screen) I check if the media player is null (as it will be when the screen first loads) if not I start the media player. Below is my video player class in where you can see my implementation.
public class CustomVideoPlayer implements TextureView.SurfaceTextureListener, VideoControllerView.MediaPlayerControl, MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnVideoSizeChangedListener {
private Context mContext;
private MediaPlayer mMediaPlayer;
private SurfaceTexture mSurface;
private VideoControllerView mControllerView;
private TextureView mTextureView;
private ProgressBar mProgress;
private FrameLayout mView;
public CustomVideoPlayer(Context ctx, TextureView view, ProgressBar progressDialog, FrameLayout holderView){
this.mContext = ctx;
mTextureView = view;
mTextureView.setSurfaceTextureListener(this);
mProgress = progressDialog;
mControllerView = new VideoControllerView(ctx);
mView = holderView;
mTextureView.setOnTouchListener(new ControlTouchListener());
}
#Override
public boolean canPause() {
return true;
}
#Override
public boolean canSeekBackward() {
return true;
}
#Override
public boolean canSeekForward() {
return true;
}
#Override
public int getBufferPercentage() {
return 0;
}
#Override
public int getCurrentPosition() {
return mMediaPlayer.getCurrentPosition();
}
#Override
public int getDuration() {
return mMediaPlayer.getDuration();
}
#Override
public boolean isPlaying() {
return mMediaPlayer.isPlaying();
}
#Override
public void pause() {
mMediaPlayer.pause();
}
#Override
public void seekTo(int i) {
mMediaPlayer.seekTo(i);
}
#Override
public void start() {
mMediaPlayer.start();
}
#Override
public boolean isFullScreen() {
return false;
}
#Override
public void toggleFullScreen() {
}
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
}
#Override
public void onCompletion(MediaPlayer mp) {
}
#Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
}
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mSurface = surface;
if(mMediaPlayer!=null) {
mMediaPlayer.setSurface(new Surface(mSurface));
mMediaPlayer.start();
}
Log.i(VersysVideoPlayer.class.getSimpleName(), String.valueOf(surface)+"available");
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
//mSurface = surface;
if(mMediaPlayer==null){
Log.i(VersysVideoPlayer.class.getSimpleName(), "MEDIA PLAYER IS NULL");
}else{
Log.i(CustomVideoPlayer.class.getSimpleName(), "MEDIA PLAYER IS NOT NULL");
mMediaPlayer.pause();
}
Log.i(CustomVideoPlayer.class.getSimpleName(), String.valueOf(surface)+"destroyed");
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
public void changePlayState(){
if(mMediaPlayer!=null) {
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
} else {
mMediaPlayer.start();
}
}else{
Log.i(CustomVideoPlayer.class.getSimpleName(), "MEDIA PLAYER IS NULL");
}
}
public void startVideo(String url){
if(mMediaPlayer!=null){
mMediaPlayer.reset();
mMediaPlayer.release();
//mMediaPlayer = new MediaPlayer();
}else{
mMediaPlayer = new MediaPlayer();
}
if(!mMediaPlayer.isPlaying()){
try {
mMediaPlayer.setSurface(new Surface(mSurface));
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setDataSource(url);
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
mMediaPlayer.setOnPreparedListener(this);
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void onPrepared(MediaPlayer mp) {
Log.i(CustomVideoPlayer.class.getSimpleName(), "ON PREPARED CALLED");
mControllerView.setMediaPlayer(this);
mControllerView.setAnchorView(mView);
mControllerView.show();
mProgress.setVisibility(View.GONE);
mMediaPlayer.start();
// mMediaPlayer.setVolume(0,0);
}
//Touch listener to display video controls
class ControlTouchListener implements View.OnTouchListener{
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
mControllerView.show();
}
return false;
}
}
}
Any comments or opinions are welcomed.
I got stuck with one requirement i need to play a media file in android.I will post the screen shot of the page
Actual requirement is the user wants to play the audio file in his recordings list.The recordings list are shown through list adapter.I want to display the play progress of the audio file on the same page(as like shown in the screen shot).
Iam pasting the code which i have tried.
public class RecordingActivity extends ListActivity implements MediaPlayerControl {
MediaPlayer mMediaPlayer;
MediaController mMediaController;
Handler mHandler;
String OUTPUT_FILE;
RelativeLayout rl;
Context context = null;
Point p;
static final String[] recordings = new String[] {"Example1","Example2",
"Example3","Example4","Example5" };
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new FirstAdapter(this, recordings));
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
showPopup(RecordingActivity.this, p);
// get selected items
mMediaPlayer = new MediaPlayer();
mMediaController = new MediaController(this);
mHandler = new Handler();
mMediaController.setMediaPlayer(RecordingActivity.this);
OUTPUT_FILE = Environment.getExternalStorageDirectory()+"/recorder.mp3";
try{
mMediaPlayer.setDataSource(OUTPUT_FILE);
mMediaPlayer.prepare();
}
catch(Exception e){
}
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mHandler.post(new Runnable() {
public void run() {
mMediaController.show(10000);
mMediaPlayer.start();
mMediaController.setEnabled(true);
}
});
}
});
}
private void showPopup(final Activity context, Point p) {
int popupWidth = 200;
int popupHeight = 150;
// Inflate the popup_layout.xml
RelativeLayout viewGroup = (RelativeLayout) context.findViewById(R.id.reviewlist);
LayoutInflater layoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = layoutInflater.inflate(R.layout.activity_play, viewGroup);
// Creating the PopupWindow
final PopupWindow popup = new PopupWindow(context);
popup.setContentView(layout);
popup.setWidth(popupWidth);
popup.setHeight(popupHeight);
popup.setFocusable(true);
// Some offset to align the popup a bit to the right, and a bit down, relative to button's position.
int OFFSET_X = 30;
int OFFSET_Y = 30;
// Clear the default translucent background
popup.setBackgroundDrawable(new BitmapDrawable());
// Displaying the popup at the specified location, + offsets.
popup.showAtLocation(layout, Gravity.NO_GRAVITY,p.x+OFFSET_X,p.y+OFFSET_Y);
// Getting a reference to Close button, and close the popup when clicked.
ImageButton close = (ImageButton) layout.findViewById(R.id.close);
Button b1 =(Button) layout.findViewById(R.id.button1);
Button b2 =(Button) layout.findViewById(R.id.button2);
close.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
popup.dismiss();
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
mMediaPlayer.stop();
mMediaPlayer.release();
}
#Override
public boolean canPause() {
return true;
}
#Override
public boolean canSeekBackward() {
return false;
}
#Override
public boolean canSeekForward() {
return false;
}
#Override
public int getBufferPercentage() {
int percentage = (mMediaPlayer.getCurrentPosition() * 100) / mMediaPlayer.getDuration();
return percentage;
}
#Override
public int getCurrentPosition() {
return mMediaPlayer.getCurrentPosition();
}
#Override
public int getDuration() {
return mMediaPlayer.getDuration();
}
#Override
public boolean isPlaying() {
return mMediaPlayer.isPlaying();
}
#Override
public void pause() {
if(mMediaPlayer.isPlaying())
mMediaPlayer.pause();
}
#Override
public void seekTo(int pos) {
mMediaPlayer.seekTo(pos);
}
#Override
public void start() {
mMediaPlayer.start();
mMediaController.show();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
mMediaController.show();
return false;
}
}
The problem am facing is i am able to play the audio file ,but it is not showing any popup layout.
Media player
MediaPlayer mp = new MediaPlayer();
// Set data source -
setDataSource("/sdcard/path_to_song");
// Play audio
mp.start();
// Pause audio
mp.pause();
// Reset mediaplayer
mp.reset();
// Get song length duration - in milliseconds
mp.getDuration();
// Get current duration - in milliseconds
mp.getCurrentDuration();
// Move song to particular second - used for Forward or Backward
mp.seekTo(positon); // position in milliseconds
// Check if song is playing or not
mp.isPlaying(); // returns true or false
Hope this will give you some solution. Refer this link. It will solve your problem
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mMediaPlayer = new MediaPlayer();
mMediaController = new MediaController(this);
mMediaController.setMediaPlayer(PlayAudioActivity.this);
mMediaController.setAnchorView(findViewById(R.id.audioView));
String audioFile = "" ;
try {
mMediaPlayer.setDataSource(audioFile);
mMediaPlayer.prepare();
} catch (IOException e) {
System.out.println("Error in playing audio");
}
mMediaPlayer.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mHandler.post(new Runnable() {
public void run() {
mMediaController.show(10000);
mMediaPlayer.start();
}
});
}
});
}
if you have done this then.
#Override
protected void onDestroy() {
super.onDestroy();
mMediaPlayer.stop();
mMediaPlayer.release();
}
#Override
public boolean canPause() {
return true;
}
#Override
public boolean canSeekBackward() {
return false;
}
#Override
public boolean canSeekForward() {
return false;
}
#Override
public int getBufferPercentage() {
int percentage = (mMediaPlayer.getCurrentPosition() * 100) / mMediaPlayer.getDuration();
return percentage;
}
#Override
public int getCurrentPosition() {
return mMediaPlayer.getCurrentPosition();
}
#Override
public int getDuration() {
return mMediaPlayer.getDuration();
}
#Override
public boolean isPlaying() {
return mMediaPlayer.isPlaying();
}
#Override
public void pause() {
if(mMediaPlayer.isPlaying())
mMediaPlayer.pause();
}
#Override
public void seekTo(int pos) {
mMediaPlayer.seekTo(pos);
}
#Override
public void start() {
mMediaPlayer.start();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
mMediaController.show();
return false;
}
}
public class PlayAudioActivity extends Activity implements MediaPlayerControl {
private MediaController mMediaController;
private MediaPlayer mMediaPlayer;
private Handler mHandler = new Handler();
use this .
I am developing an application that, among other things, plays some video files (streaming). I would like to prepare the MediaPlayer in one activity but play the video once it is ready in another activity, so that the user can navigate through the content of the first activity to kill some time. Is this possible?
There is an static MediaPlayer defined in the Application class, like this:
public class EGDF_App extends Application {
private static MediaPlayer mediaPlayer = null;
public static MediaPlayer getMediaPlayer() {
if(mediaPlayer == null)
return new MediaPlayer();
else
return mediaPlayer;
}
}
I have a button with a text (Load video). This text is changed when the video is ready, and when the user clicks on it, it triggers the following activity.
The problem is that I get the following error in LogCat:
09-06 20:43:34.606: D/ChapterPlayer(31999): surfaceCreated called
09-06 20:43:34.684: V/ChapterPlayer(31999): startVideoPlayback
09-06 20:43:34.684: E/MediaPlayer(31999): start called in state 1
09-06 20:43:34.684: E/MediaPlayer(31999): error (-38, 0)
09-06 20:43:34.684: D/ChapterPlayer(31999): surfaceChanged called
09-06 20:43:34.700: E/MediaPlayer(31999): Attempt to call getDuration without a valid mediaplayer
09-06 20:43:34.715: E/MediaPlayer(31999): Error (-38,0)
09-06 20:43:34.715: D/ChapterPlayer(31999): onCompletion called
09-06 20:43:34.751: E/MediaPlayer(31999): Attempt to call getDuration without a valid mediaplayer
This is the code contained in the first Activity:
public void watchChapter(View view){
Log.i("Button", "Watch chapter button PRESSED");
Button b = (Button) view;
String loadChapter = getString(R.string.load_chapter_button_text);
String watchChapter = getString(R.string.watch_chapter_button_text);
if(((String) b.getText()).equals(loadChapter)){
prepareVideo(view);
}else if(((String) b.getText()).equals(watchChapter)){
Intent intent = new Intent(this,ChapterAsyncMediaPlayerActivity.class);
intent.putExtra(Constants.chapterVideoResParse, getIntent().getExtras().getString(Constants.chapterVideoResParse));
intent.putExtra("duration", String.valueOf(duration));
startActivity(intent);
}
}
private void prepareVideo(View view){
MediaPlayer mMediaPlayer;
String path;
final Button button = (Button) view;
String resource = extras.getString(Constants.chapterVideoResParse);
path = SecurityHandler.obtainURL(resource, this.getResources().openRawResource(R.raw.output), 10);
try {
// Gets the media player and set the listeners
mMediaPlayer = EGDF_App.getMediaPlayer();
mMediaPlayer.setDataSource(path);
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mp) {
button.setText(getString(R.string.watch_chapter_button_text));
Log.i("MediaPlayer", "MediaPlayer ready");
duration = mp.getDuration();
Log.i("Video duration", String.valueOf(mp.getDuration()));
}
});
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And this is the code in the second Activity:
public class ChapterAsyncMediaPlayerActivity extends Activity implements
OnBufferingUpdateListener, OnCompletionListener,
OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback, MediaPlayerControl {
private static final String TAG = "ChapterPlayer";
private int mVideoWidth;
private int mVideoHeight;
private MediaPlayer mMediaPlayer;
private MediaController mController;
private SurfaceView mPreview;
private SurfaceHolder holder;
// private String path;
// private boolean mIsVideoSizeKnown = false;
private boolean mIsVideoReadyToBePlayed = false;
private Handler handler = new Handler();
#SuppressWarnings("deprecation")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chapter_media_player);
mPreview = (SurfaceView) findViewById(R.id.mediaPlayerSurface);
holder = mPreview.getHolder();
holder.addCallback(this);
holder.setKeepScreenOn(true);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
mController.show();
return false;
}
private void playVideo() {
doCleanUp();
try {
// Create a new media player and set the listeners
mMediaPlayer = EGDF_App.getMediaPlayer();
// mMediaPlayer.setDataSource(path);
mMediaPlayer.setDisplay(holder);
// mMediaPlayer.prepareAsync();
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setOnVideoSizeChangedListener(this);
mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mController = new MediaController(this);
} catch (Exception e) {
Log.e(TAG, "error: " + e.getMessage(), e);
}
}
public void onPrepared(MediaPlayer mediaplayer) {
Log.d(TAG, "onPrepared called");
mIsVideoReadyToBePlayed = true;
mController.setMediaPlayer(this);
mController.setAnchorView(findViewById(R.id.mediaPlayerSurface));
handler.post(new Runnable(){
#Override
public void run() {
mController.setEnabled(true);
mController.show();
}
});
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
startVideoPlayback();
}
}
public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {
Log.d(TAG, "surfaceChanged called");
}
public void surfaceDestroyed(SurfaceHolder surfaceholder) {
Log.d(TAG, "surfaceDestroyed called");
}
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG, "surfaceCreated called");
playVideo();
mIsVideoReadyToBePlayed = true;
mController.setMediaPlayer(this);
mController.setAnchorView(findViewById(R.id.mediaPlayerSurface));
handler.post(new Runnable(){
#Override
public void run() {
mController.setEnabled(true);
mController.show();
}
});
if (mIsVideoReadyToBePlayed) {
startVideoPlayback();
}
}
#Override
protected void onPause() {
super.onPause();
mMediaPlayer.pause();
}
#Override
protected void onRestart() {
super.onPause();
mMediaPlayer.start();
}
#Override
protected void onDestroy() {
super.onDestroy();
releaseMediaPlayer();
doCleanUp();
}
private void releaseMediaPlayer() {
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
}
private void doCleanUp() {
mVideoWidth = 0;
mVideoHeight = 0;
mIsVideoReadyToBePlayed = false;
}
private void startVideoPlayback() {
Log.v(TAG, "startVideoPlayback");
holder.setFixedSize(mVideoWidth, mVideoHeight);
mMediaPlayer.start();
mMediaPlayer.setScreenOnWhilePlaying(true);
}
#Override
public boolean canPause() {
return true;
}
#Override
public boolean canSeekBackward() {
return true;
}
#Override
public boolean canSeekForward() {
return true;
}
#Override
public int getBufferPercentage() {
return 0;
}
#Override
public int getCurrentPosition() {
if(mMediaPlayer != null)
return mMediaPlayer.getCurrentPosition();
else
return 0;
}
#Override
public int getDuration() {
if(mMediaPlayer != null)
return mMediaPlayer.getDuration();
else
return 0;
}
#Override
public boolean isPlaying() {
if(mMediaPlayer != null)
return mMediaPlayer.isPlaying();
else
return false;
}
#Override
public void pause() {
if(mMediaPlayer != null)
mMediaPlayer.pause();
}
#Override
public void seekTo(int pos) {
mMediaPlayer.seekTo(pos);
}
#Override
public void start() {
if(mMediaPlayer != null)
mMediaPlayer.start();
}
public void onBufferingUpdate(MediaPlayer arg0, int percent) {
Log.d(TAG, "onBufferingUpdate percent:" + percent);
}
public void onCompletion(MediaPlayer arg0) {
Log.d(TAG, "onCompletion called");
}
#Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
Log.v(TAG, "onVideoSizeChanged called");
if (width == 0 || height == 0) {
Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
return;
}
mVideoWidth = width;
mVideoHeight = height;
if (mIsVideoReadyToBePlayed) {
startVideoPlayback();
}
}
}
I would appreciate some help or advice. Thanks!
I don't think you're saving the MediaPlayer in your application, you're just returning a new instance of it. Try changing it as so:
public static MediaPlayer getMediaPlayer() {
if(mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
}
return mediaPlayer;
}