VideoView doesn't start when invisible - android

I have an AsyncTask, where I hide a video view, start the video playback, and show the video view when the video is playing.
But the video would just not start when the video view is set to invisible, the async task keeps hanging in onBackground. If I comment out this line, the video starts playing.
Why does the video view require a visible surface?
public void walk(final View v) {
new AsyncTask() {
#Override
protected void onPreExecute() {
super.onPreExecute();
mVideoView.setVisibility(View.INVISIBLE); // this line causes video not to start
mVideoView.start();
}
#Override
protected Object doInBackground(Object... objects) {
while (!mVideoView.isPlaying()) {}
return null;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
mVideoView.setVisibility(View.VISIBLE);
}
}.execute();
A bit of background why I'm doing this: I try to avoid the well-known issue of the black flash that you usually have when starting a video:
https://stackoverflow.com/search?q=%5Bandroid%5D+videoview+black
https://stackoverflow.com/search?q=%5Bandroid%5D+video+%5Bmediaplayer%5D+black

The VideoView is really a specialised SurfaceView. A SurfaceView works by creating another window behind the normal window (containing all of the views), and then having an area of transparency so that the new window (with its own drawing surface) can be seen behind it.
If a SurfaceView is no longer visible, its surface will be destroyed i.e. SurfaceHolder.Callback.surfaceDestroyed is called. The VideoView will not try to play its video if there is not a valid surface, hence your AsyncTask will be able to never leave doInBackground.
The Surface will be created for you while the SurfaceView's window is visible; you should implement surfaceCreated(SurfaceHolder) and surfaceDestroyed(SurfaceHolder) to discover when the Surface is created and destroyed as the window is shown and hidden.

Related

VideoView turn into black screen

I am developing multi player video app, so in that i created 9 views 3*3.
when i initialize all (3*3) videoview then working properly for few seconds and after some time video is goes to black screen, not show single video, i am not understand this issue is device oriented or android not supports more than 1 video in activity, anyone know how to resolve this issue, otherwise if video is turn into black then how to identify video is turned into black screen, if we found this then i will refresh view and again start video, i don't know it is correct way or not.
please anyone know about how to resolve this issue then please share information !
i use below code for show multiple video view in one activity
videoPlayer.setVideoPath("path");
videoPlayer.start();
videoPlayer.requestFocus();
videoPlayer.setKeepScreenOn(true);
set prepare listener
videoPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
}
set completion listener
videoPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
//play next
}
});
handle error listener
videoPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
// play next
return true;
}
});
when video play next before that i set some propertied to mediaplyer object
mediaPlayer.setDisplay(null);
mediaPlayer.reset();
mediaPlayer.setDisplay(videoPlayer.getHolder());
i share basic code of my project, please tell me if anything is missing from me or android is not supported multiple videos in same activity.

Android, hide video without stopping audio playback

(Sorry for my english)
I 'm trying to show video using TextureView, but I need to know if there is a way to hide the video without stopping audio playback.
Thus I am doing:
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mySurface = new Surface(surface);
if(MyService.mMediaPlayer != null) MyService.mMediaPlayer.setSurface(mySurface);
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
if(MyService.mMediaPlayer != null) MyService.mMediaPlayer.setSurface(null);
return false;
}
You can see that I'm trying using setSurface(null) but the audio does not remain when I try this.
EDIT:
I have a button in my main activity ( "show video") ; this button starts the second activity where I put the above code .
I need the audio keeps playing when I press the Back button or the home button
Set the visibility of your TextureView to INVISIBLE
mTextureView.setVisibility(View.INVISIBLE);

How to avoid MediaPlayer's starting black screen?

So in my app MediaPlayer is based on SurfaceView by extending like:
public class VideoView extends SurfaceView {}
now, it uses MediaPlayer inside and what I want to achieve is to make starting color of screen white instead of black. VideoView is placed in white-backgrounded-layout by itself. It is white but atm it starts playing video the VideoView becomes black for a second. Video by itself has white background and its first frames are not black so I assume that its about MediaPlayer. When it starts playing it turns screen black by default. I had guessed that I could use transition like:
TransitionDrawable transition = new TransitionDrawable(new Drawable[]{new ColorDrawable(Color.WHITE), new ColorDrawable(Color.TRANSPARENT)});
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
this.setBackgroundDrawable(transition);
else
this.setBackground(transition);
transition.setCrossFadeEnabled(true);
transition.startTransition(1000);
However this doesn't help much. So is there a way to achieve my goal?
Forgot to mention that its local video file (from SD card) is being played. So black screen is not about a long HTTP-session establishing or other stream related things. And preparation is done via prepareAsync();
So I found a nasty solution finally. Oh well its better than nothing:
private TransitionDrawable transition;
private Animation videoViewFadeInAnimation;
#SuppressWarnings("deprecation")
public void start() {
if (videoViewFadeInAnimation == null){
videoViewFadeInAnimation = new AlphaAnimation(0, 1);
videoViewFadeInAnimation.setDuration(600);
videoViewFadeInAnimation.setFillAfter(true);
videoViewFadeInAnimation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation arg0) {}
#Override
public void onAnimationRepeat(Animation arg0) {}
#Override
public void onAnimationEnd(Animation arg0) {
if (DeviceInfo.hasAPI11())
setAlpha(1);
}
});
}
if (transition == null){
transition = new TransitionDrawable(new Drawable[]{new ColorDrawable(Color.WHITE), new ColorDrawable(Color.TRANSPARENT)});
transition.setCrossFadeEnabled(true);
if(DeviceInfo.hasAPI16())
this.setBackground(transition);
else
this.setBackgroundDrawable(transition);
}
if (isInPlaybackState()) {
if (mCurrentState!=STATE_PAUSED){
startAnimation(videoViewFadeInAnimation);
transition.startTransition(1);
}
hideVideoControls();
mMediaPlayer.start();
mCurrentState = STATE_PLAYING;
}
mTargetState = STATE_PLAYING;
}
its a method of my VideoView which starts video playing. Basically it makes 0 alpha for VideoView and a white bg for 1ms (doesn't work without bg transition) and then animates alpha from 0 to 1 for 600ms. If use value lt 600 then the annoying black screen becomes noticeable. However 600ms of no video visible also not the best thing cuz visually audio starts earlier. This solutions doesn't work always and don't know why.

retain videoview in fragment when rotating

I have a activity who hold 2 fragments (one SlidingMenu and other a VideoPlayer with control and other views).
How Can I retain the video playing status when I'm rotating the device? the video is a HLS Stream, so, I don't need to start again the buffering when rotate.
I start playing with the savedInstanceState, but i can't get it work
If you are using the same resources on on different screen orientations, you can prevent fragment from recreating.
If you need to recreate fragment, you can store playback progress, and after recreation scroll video to stored position
#Override
protected void onPause() {
...
if(playbackWasStarted) {
video.pause();
videoProgress = video.getCurrentPosition();
}
...
}
#Override
protected void onResume() {
...
if(playbackWasStarted && videoProgress!=0) {
video.seekTo(videoProgress);
video.start();
}
...
}
EDIT Oh, I didn't noticed that this question is veeeery old...

How to get current view of android screen

I am developing an Android application which should record a video. There are certain classes that I cannot change due to restrictions of the project, like Preview and VideoRec classes.
Application has one main screen activity and there is a toggle button. Whenever toggle button is checked, video recording should start and vice versa for the unchecked state.
However, VideoRec class' constructor takes a View type parameter for input (VideoRec(View x)). Main activity's screen has a surfaceview and several buttons. What I am trying to do is to just initiate video recording on the same screen, just like the default mediarecorder application of any phone.
My question is; I keep on failing to obtain the View of the screen. I can't use preview or surfaceView types, I get errors saying either classCast Exceptions or invalid preview/surface preview.
Long story short, how can i get the activity's screen as a type of View?
you can provide a public method in your Main Activity which returns the view you need.
Obviously you have to save a reference of that view in your onCreate method activity:
View myView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.the_layout_id);
myView = (View)findViewByID(R.id.your_id_view);
}
public View getTheView(){
return myView;
}
What I understand is you have 1 surfaceview where reproducing what you are recording.
So you must attach your PreviewCallback in the surfaceChanged(...) SurfaceHolder.Callback! After doing this, you'll continue to get preview frame data after a MediaRecorder is running!
For example:
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
mCamera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] _data, Camera _camera) {
Log.d("onPreviewFrame-surfaceChanged",String.format("Got %d bytes of camera data", _data.length));
}
});
}
Hope it helps!Cheers

Categories

Resources