I like this site very much because I can find many useful solutions help me very much especially I'm beginner in android programming and this is my first question so I hope find helping from this great community.
The Problem:
I play video in my app and make it playing in full screen in landscape when user orient screen so I want to make video restart playing from the same point by using seekTo() and getCurrentPosition() - but the problem that video play many seconds after the position I mean that video seek to same point in time but when start play it add many seconds.
My Code:
//initialise everything
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
v = (VideoView) findViewById(R.id.videoView1);
v.setVideoPath(dir + videoName + ".3gp");
v.setMediaController(new MediaController(this));
if (savedInstanceState == null){
v.start();
}
else {
playingTime = savedInstanceState.getInt("restartTime", 0);
v.seekTo(playingTime);
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
if (file.exists()){
playingTime = v.getCurrentPosition();
v.stopPlayback();
outState.putInt("restartTime", playingTime);
}
}
I try many solution such as this
How to keep playing video while changing to landscape mode android
I'm using Galaxy Nexus to test my app .. I would be grateful for any hint.
Sorry for my bad English and thanks very much.
In your activity, keep everything normal. It boils down to saving the position when activity is recreated. Here is one approach:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//initialise everything
//finally
if(savedInstanceState!=null) {
int seekValue = savedInstanceState.getInt("where");
//now seekTo(seekValue)
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
int seekValue; //set this to the current position;
outState.putInt("where", seekValue);
super.onSaveInstanceState(outState);
}
}
Related
There is a video activity, I need to handle:
1) when the first time enter the activity, get the position from intent and play the video
2) keep the same position after rotate
Here is the code to handle first requirement
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video_full_screen);
ButterKnife.bind(this);
if (getIntent() != null) {
video_url = getIntent().getStringExtra("video_url");
pos = (int)getIntent().getLongExtra("time", 0);
}
player.setOnPreparedListener(this);
player.setVideoURI(Uri.parse(video_url));
}
#Override
public void onPrepared(MediaPlayer mp) {
player.seekTo(pos);
player.start();
}
Here is the code to handle second requirement
#Override
protected void onSaveInstanceState(Bundle outState)
{
outState.putInt("time", (int)player.getCurrentPosition());
player.pause();
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
int last_pos = savedInstanceState.getInt("time");
player.seekTo(last_pos);
player.start();
super.onRestoreInstanceState(savedInstanceState);
}
The problem is the handling is conflict to each other.
If first time enter progess is 10s , when I play at e.g. 30s and rotate , it still go to 10s instead of 30s.
It is caused by the seekTo(pos) at the onPrepared function but I can not remove that as it handle the first requirement.
How to fix that? Thanks for helping.
Rotating the screen calls onDestroy(). Are you saving the time progress in onDestroy()? For more info on android life cycle see: https://androidcookbook.com/Recipe.seam?recipeId=2636
YouTube player has been released when devices rotate and activity recreated. Then play video. Shows YouTube player has released. I don't know where it released. I have already set it to Null onDestroy Method.
`mPlayer.loadVideo(videoId);`
//pointing YouTube Player released
My solution is to save the current playing time by YouTubePlayer getCurrentTimeMillis() in onSaveInstanceState(Bundle state) when screen rotation gets triggered, and get the time back from onRestoreInstanceState(Bundle state).
Sample code would be:
static final String CURRENT_PLAY_TIME = "current_play_time";
int current_time;
#Override
protected void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
state.putInt(CURRENT_PLAY_TIME, youTubePlayer.getCurrentTimeMillis());
}
#Override
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
current_time = state.getInt(CURRENT_PLAY_TIME);
}
And after restoring the current playing time let YouTubePlayer load video with it.
youTubePlayer.loadVideo(VIDEO_ID, current_time);
Hope it helps!
A posible solution is make your app vertical or horizontal permanent
For doing this write within your manifest:
<android:screenOrientation="portrait"> //vertical
<android:screenOrientation="landscape"> //horizontal
I have found my Excelent solution..all going good with youtube player
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
if (mPlayer != null)
//Set YouTube Player here;
}
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
if (mPlayer != null)
//Set YouTube Player here;
}
}
I have a problem in running a video in Samsung S3(Android 4.1.1), the issue seems to be because the videoview is on a fragment because if I put it on and activity, it works.
Also I found out that if I turn on the GPU hardware acceleration on, the video works.
I have also a game made by drawing on a SurfaceView and that view doesn't work as well(only with GPU on)... The rest of the app content is displayed as it supposed to (buttons and other layouts).
I tested the app on Nexus S and on the emulator and it works fine, also on other devices..
Does anyone know what the problem could be?
Thank you!
And here is the code:
public class VideoFragment extends Fragment implements MediaPlayer.OnCompletionListener,
MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener {
private Video mVideo;
private VideoView mVideoView;
// The video position
private int mPosition;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View fragmentView = inflater.inflate(R.layout.screen_video, container, false);
mVideoView = (VideoView) fragmentView.findViewById(R.id.VideoView);
return fragmentView;
}
#Override
public void onPause() {
super.onPause();
// Pause the video if it is playing
if (mVideoView.isPlaying()) {
mVideoView.pause();
}
// Save the current video position
mPosition = mVideoView.getCurrentPosition();
}
#Override
public void onResume() {
super.onResume();
mVideoView.setOnCompletionListener(this);
mVideoView.setOnPreparedListener(this);
mVideoView.setOnErrorListener(this);
mVideoView.setKeepScreenOn(true);
// Initialize the media controller
MediaController mediaController = new MediaController(getActivity());
mediaController.setMediaPlayer(mVideoView);
// Set-up the video view
mVideoView.setMediaController(mediaController);
mVideoView.requestFocus();
mVideoView.setVideoPath(mVideo.getUrl());
if (mVideoView != null) {
// Restore the video position
mVideoView.seekTo(mPosition);
mVideoView.requestFocus();
}
}
#Override
public void onDestroy() {
super.onDestroy();
// Clean-up
if (mVideoView != null) {
mVideoView.stopPlayback();
mVideoView = null;
}
}
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
Log.e("VIDEO PLAY", "end video play");
}
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
// Start the video view
mediaPlayer.start();
Log.e("VIDEO PLAY", "video ready for playback");
}
#Override
public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
Log.e("VIDEO PLAY", "error: " + i);
return true;
}
}
I don't think it's something related to context(Application or Activity).. because on all other devices the Video and the games are displayed..
Thanks for the help!
I have a similar problem, and i solved it changing:
MediaController mediaController = new MediaController(getActivity().getApplicationContext());
to this (In a fragmet):
MediaController mediaController = new MediaController(getActivity());
Hope this helps,...
EDIT
Look at this class
http://code.google.com/p/sinaweibo-honeycomb/source/browse/branches/sinaweibo-merged/src/com/lenovo/dll/SinaWeibo/VideoFragment.java?r=71
If hardware acceleration fixes your issue then I would enable it for that view/window on that device.
In general I've found that when code works on one device but not another it is typically caused by one of the following problems:
Bug in the manufacturer's API implementation
Different interpretation of the API by the manufacturer
Concurrency problem (e.g. race condition, improper synchronization) in your own code that happens to trigger more frequently on a particular device
As far as I can tell you seem to be using the UI thread appropriately so I would imagine your issue falls into one of the first two categories and you'll just need to work around it.
Move MediaController mediaController = new MediaController(getActivity()) from onResume() to onCreateView.
I am developing an application in which i want to play a short 5 seconds video at the startup. which is the best format 3gp, mpg or something else? i have generated a title activity. I wanted to play the video before title. Help please!!! Below is the code of my title activity.
public class Title extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.title);
setTitle("M.I.S.T");
this.setTitleColor(Color.BLUE);
View title = getWindow().findViewById(android.R.id.title);
View titleBar = (View) title.getParent();
titleBar.setBackgroundColor(Color.YELLOW);
Thread timer = new Thread(){
public void run(){
try{
sleep(3000);
}catch (InterruptedException e){
e.printStackTrace();
}finally{
Intent open= new Intent("com.congestion6.asad.MENU");
startActivity(open);
}
}
};
timer.start();
}
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
finish();
}
}
mpeg can be compressing the video over a range of different formats/algorithms/codecs and some are supported some are not. 3gp is just one and it is supported (although a very poor format).
Try encoding a video yourself that you'll see all different options. Usually mp4 on H264 works flawlessly on mobiles.
I'm trying to make my app to play intro clip for only when I start activities.
But from my code it's always play the clip after wakeup before resume to app although I did not closed the app. What can I do to fix this prob?
From main:
startActivity(new Intent(this, MyIntro.class));
From MyIntro:
public class MyIntro extends Activity implements OnCompletionListener {
int a;
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.intro);
playIntro();
}
public void onConfigurationChanged(Configuration newConfig) {
setContentView(R.layout.intro);
}
public void onCompletion(MediaPlayer arg0) {
// TODO Auto-generated method stub
this.finish();
}
private void playIntro(){
setContentView(R.layout.intro);
VideoView video = (VideoView) this.findViewById(R.id.VideoView01);
Uri uri = Uri.parse("android.resource://real.app/" + R.raw.intro);
video.setVideoURI(uri);
video.requestFocus();
video.setOnCompletionListener(this);
video.start();
}
}
What function have you overridden in your main Activity - the one where you call
startActivity(new Intent(this, MyIntro.class))
?
I would assume it's onResume() and the line above is executed too many times, because of that. Read again the explanation of Activity lifecycle here, it's the first thing I do, when I have problems like that.
Get back to us with a little more info about the main Activity.
Evil hack:
Add a static pointer to your own activity, fill or override it when "onCreate" gets called. If it's null, play your movie, otherwise, don't.
You could do the same with a static boolean really.
private static boolean isRunning = false;
protected void onCreate(Bundle bundle) {
super.onCreate(bundle)
if(!isRunning)
{
isRunning = true;
//Play your video here
}
}
There are much more elegant and correct ways of doing this, but if you're in a hurry this will probably work.