Android mediaplayer reinitializes on screen rotation - android

I am streaming/playing already downloaded video in the VideoView. When I rotate the screen all the objects are reinitialized so that the video is played from the beginning or if get current position and set the position on screen rotation the video is streamed again. As the video from back end is encrypted,it takes so much time to load it resulting in a very bad user experience.
The following is what I've os far.
public class MainActivity extends AppCompatActivity {
VideoView videoView;
Context context;
int stopPosition = 0;
private static MediaController mediaController;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
videoView = (VideoView) findViewById(R.id.videoView1);
if (savedInstanceState != null) {
stopPosition = savedInstanceState.getInt("position");
Log.d("", "savedInstanceState called" + stopPosition);
}
mediaController = new MediaController(context);
mediaController.setAnchorView(videoView);
String path = "android.resource://" + getPackageName() + "/" + R.raw.videotest;
Uri uri = Uri.parse(path);
videoView.setMediaController(mediaController);
videoView.setVideoURI(uri);
videoView.requestFocus();
videoView.start();
}
#Override
public void onPause() {
Log.d("", "onPause called");
super.onPause();
videoView.pause();
}
#Override
protected void onResume() {
super.onResume();
Log.d("", "onResume called" + stopPosition);
videoView.seekTo(stopPosition);
videoView.resume();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
videoView.pause();
outState.putInt("position", 100);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
stopPosition = savedInstanceState.getInt("position");
}
}
When I used the following methods this problem is solved but some new one starts.
If I add android:configChanges="screenSize|orientation" to AndroidManifest.xml it works perfectly except onSaveInstanceState is not called. I've some works to do in it so I want it be called.
Another method I used is that using Mediaplayer and SurfaceView and it works too except the mediaplayer not functioned correctly in some cases(Video size changes in each videos)
Basically what I would like to have is that in above code onRestoreInstanceState should be called and video shouldn't reinitialized(or play without a delay) in screen rotation

Found a solution, if we add android:configChanges="screenSize|orientation" to manifest.xml then only onConfigurationChanged override is called, activity is not recreated. As I had one VideoView and a ListView in the screen which has parent LinearLayout, I changed orientation to horizontal from verical in onConfigurationChanged.
You have to dynamically set required views in Portrait or Landscape mode accordingly.

Related

How to keep video inside fragment playing after rotation?

I managed to get my video to play with VideoView but after I rotate my device video stops and starts playing from the beginning. I placed my VideoView inside fragment.
I tried this inside my fragment but without success:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public void onPause() {
super.onPause();
if(video.isPlaying()) {
video.pause();
progress = video.getCurrentPosition();
}
}
#Override
public void onResume() {
super.onResume();
if(video.isPlaying() && progress!=0) {
video.seekTo(progress);
video.start();
}
}
How to keep video playing after screen rotates?

Playing video from the pause state in VideoView

For custom videoview I had to override the MediaController (to change the design of the buttons and connect to the buttons pause / play a selector). The situation is this: put the video on pause and turning the application, and then again restored, the video starts playing again, and not from the point at which it was suspended, and therefore the question arose: how to make the video starts playing from the place , where it was stopped? What do I need to change in the VideoActivity?
public class VideoActivity extends Activity {
VideoView videoView;
VkMediaController mc;
private static final String CURRENT = "duration";
private static final String URL = "url";
private Uri mURI;
private int mCurrentPosition = -1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.video_view_player);
videoView = (VideoView) findViewById(R.id.videoViewplayer);
mc = new VkMediaController(this);
mURI = getIntent().getData();
if (savedInstanceState != null) {
mURI = Uri.parse(savedInstanceState.getString(URL));
mCurrentPosition = savedInstanceState.getInt(CURRENT);
}
videoView.setMediaController(mc);
videoView.setVideoURI(mURI);
videoView.requestFocus();
}
#Override
protected void onStart() {
super.onStart();
videoView.start();
if (mCurrentPosition != -1) {
videoView.seekTo(mCurrentPosition);
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putInt(CURRENT, videoView.getCurrentPosition());
outState.putString(URL, mURI.toString());
super.onSaveInstanceState(outState);
}
}
I think the problem is that videoView.getCurrentPosition() will always return 0 when you call inside onSaveInstanceState(Bundle outState), cos at that time the video already reset, so call videoView.getCurrentPosition() when onPause(), this will return you the desired value.
I had the same problem. I thought I did everything right but it didnt work. Then I just changed the order so I first call VideoView.seekTo() and then VideoView.start() . That worked.
I also have VideoView.requestFocus() in there but I dont know if that matters.
videoPlayer.requestFocus();
videoPlayer.seekTo(position);
videoPlayer.start();
So if youre sure you position variable has the right value, this might be your answer.
You may not be able to seek when the Video is not loaded. Implement onPreparedListener like this:
public class VideoActivity extends Activity implements OnPreparedListener {
VideoView videoPlayer;
int position;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState!=null){
position=savedInstanceState.getInt("pos")
}
// setting up the videoview
setContentView(R.layout.activity_video);
getIntent().getExtras().getString("url");
Uri videouri = Uri.parse(getIntent().getExtras().getString("url"));
videoPlayer = (VideoView) findViewById(R.id.videoView);
videoPlayer.setOnPreparedListener(this);
videoPlayer.setKeepScreenOn(true);
videoPlayer.setVideoURI(videouri);
}
/**
* Start the plaback when the video is loaded
*
* #param mp
* #see android.media.MediaPlayer.OnPreparedListener#onPrepared(android.media.MediaPlayer)
*/
public void onPrepared(MediaPlayer mp) {
//this is a TextView infront of the VideoView which tells the User the Video is loading- hide that
findViewById(R.id.tv_video_load).setVisibility(View.GONE);
videoPlayer.requestFocus();
videoPlayer.seekTo(position)
videoPlayer.start();
}
}
Portrait to LandScape LifeCycle Demo
VideoView videoView;
int lastPosition;
int Video_STATE_POSITION = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null)
{
String message = savedInstanceState.getString("message");
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
lastPosition=savedInstanceState.getInt("STATE_POSITION");
videoView.seekTo(lastPosition);
videoView.start();
Log.e("Keshav", "MainActivity onCreate() is called savedInstanceState lastPosition->" + lastPosition);
}
}
#Override
public void onSaveInstanceState(Bundle outState)
{
outState.putString("message", "This is my message to be reloaded");
outState.putInt("STATE_POSITION", Video_STATE_POSITION);
super.onSaveInstanceState(outState);
}
#Override
protected void onPause() {
super.onPause();
Video_STATE_POSITION = videoView.getCurrentPosition();
Log.e("Keshav", "MainActivity onPause is called ->" +Video_STATE_POSITION);
}

Resume playing VideoView from onResume

I have a VideoView and it is pause when I start an Email intent. When the email intent is done, I want the videoView to continue playing, however, it restarts from the beginning.
#Override
public void onPause() {
Log.d(TAG, "onPause called");
super.onPause();
videoView.pause();
}
#Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume called");
videoView.start();//resume() doesnt work
}
How can I get the videoView to resume from where it left off.
What about this:
#Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume called");
videoView.seekTo(stopPosition);
videoView.start(); //Or use resume() if it doesn't work. I'm not sure
}
// This gets called before onPause so pause video here.
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
stopPosition = videoView.getCurrentPosition();
videoView.pause();
outState.putInt("position", stopPosition);
}
Then in your onCreate() call the stopPosition from the bundle and set it globally
#Override
protected void onCreate(Bundle args) {
super.onCreate(args);
if( args != null ) {
stopPosition = args.getInt("position");
}
Using seekTo gives a slight flickering efeect while resuming the video. Better approach would be using pause() and start() methods of MediaPlayer class instead of using methods from VideoView. The start() method of VideoView restarts the video from the beginning, but start() method of MediaPlayer resumes the video if the pause() method had been previously called.
Here is what official android doc says
public void start ()
Added in API level 1 Starts or resumes playback. If playback had
previously been paused, playback will continue from where it was
paused. If playback had been stopped, or never started before,
playback will start at the beginning.
You can get the MediaPlayer associated with a VideoView in OnPreparedListener of VideoView.
public class MainActivity extends Activity {
private MediaPlayer mMediaPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
VideoView videoView = (VideoView) findViewById(R.id.videoView1);
videoView.setVideoPath(path);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mMediaPlayer = mp;
}
});
}
}
Then subsequent pause() and resume() methods can be called on MediaPlayer object itself.
//To pause the video
mMediaPlayer.pause();
//To resume the video
mMediaPlayer.start();
Very simple yet efficient solution. Hope it helps!

landscape mode video activity is restarting

I am playing videos in my app, video should play portrait and landscape mode withought restarting actvity, please any can give examples are links.
using video view for playing video.
public class PlayVideoActivity extends Activity {
private VideoView video;
private ImageButton back;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
back = (ImageButton)findViewById(R.id.backbutton);
back.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
finish();
}
});
video=(VideoView)findViewById(R.id.videoView);
video.setDrawingCacheEnabled(true);
video.setDrawingCacheQuality(VideoView.DRAWING_CACHE_QUALITY_HIGH);
video.setVideoURI(Uri.parse("android.resource://"+ getPackageName() +"/" + R.raw.fillings_class_1));
video.requestFocus();
video.setMediaController(new MediaController(this));
video.start();
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//restore the relevant information
}
}
If you really need to prevent the activity from being restarted on an orientation change, you need to set the configChanges attribute for the Activity in the manifest to include orientation.

VideoView Activity Malfunctions when Intent is called from current Activity's View

I have my main Activity, it starts with a custom SurfaceView called DrawView being set by setContentView. The Main Activity (Draw) has the following method within it
public void launchCutScene(int scene) {
Intent intent = new Intent(Draw.this, CutScene.class);
startActivityForResult(intent, 0);
}
if I call this method directly after setContentView the new Activity CutScene loads properly. CutScene is as follows
public class CutScene extends Activity implements OnCompletionListener, OnPreparedListener{
String pathToFile = "";
VideoView videoPlayer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pathToFile = "EM Math/" + "st.mp4";
setContentView(R.layout.main);
File root = Environment.getExternalStorageDirectory();
videoPlayer = (VideoView) findViewById(R.id.myvideoview);
videoPlayer.setOnPreparedListener(this);
videoPlayer.setOnCompletionListener(this);
videoPlayer.setKeepScreenOn(true);
videoPlayer.setVideoPath(root + "/" + pathToFile);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
protected void onStop() {
super.onStop();
}
#Override
public void onPrepared(MediaPlayer vp) {
videoPlayer.start();
}
#Override
public void onCompletion(MediaPlayer mp) {
finish();
}
#Override
public boolean onTouchEvent (MotionEvent ev){
if(ev.getAction() == MotionEvent.ACTION_DOWN){
if(videoPlayer.isPlaying()){
videoPlayer.pause();
} else {
videoPlayer.start();
}
return true;
} else {
return false;
}
}
}
However, if within DrawView I call draw.launchCutScene(0) then the activity still comes up, but the video glitches, it either stays as a black screen and you have to press back to make the activity crash, in which case it will bring up the first activity. Or it will play the sound only but multiple times and un-synced. Either way after it crashes if a launchCutScene call is done again within the DrawView class the video now works fine.
Why is this happening? does anybody understand what I need to do?
Okay, Finely fixed the error!
All I had to do was set my threads runnable boolean to false, then call the activity. Once activity closes my program reinitiates the thread, and everything work hunkydorry now!!!!... So if your getting this Video Bug with your Video Views it's probably because you are running a thread in the background!

Categories

Resources