I'm developing a new app and am using VideoView to display mpeg clips.
I need to switch between videos very quickly, however, loading a new clip to a VideoView seems to take about half a second of black screen.
The transition must be seamless, how would you go about solving this kind of problem?
I had a similar issue and resolved with a still-image (ImageView) transition:
build a FrameLayout with an ImageView over the VideoView
the ImageView shows the first frame of the video
initially the ImageView is visible
start the video, wait for an arbitrary time (e.g. 2-300ms)
hide the ImageView
to switch two videos:
- show the image
- switch the video
- hide the image
a bit hackish but worked for me
I faced the same problem, but I used mediaplayer, my code is:
Here I use a button to trigger the switch action, before switching, I have already loaded the video and prepare for switching. When you need to do so, you just need to stop and release the old mediaplayer and starting the new one.The key point for seamless switching is the sleep(), when the process is sleeping, actually the video is still going on, but give the system some time to prepare for the next one.
switch_button = (Button) findViewById(R.id.button_switch);
switch_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Button switch_button = (Button) v;
VideoPlayer2 = new MediaPlayer();
try {
VideoPlayer2.setDataSource("rtsp://" + hostIP + ":1935/vod/Timer.mp4");
VideoPlayer2.prepare();
VideoPlayer2.setAudioStreamType(AudioManager.STREAM_MUSIC);
} catch (IOException e) {
e.printStackTrace();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
VideoPlayer.release();
VideoPlayer2.setDisplay(vidHolder);
VideoPlayer2.start();
}
});
Related
I have a ViewPager with items extending from FrameLayout, each one of them represents a video. Code for initialization:
try {
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setDataSource(getContext(), Uri.parse(mVideo.getVideo().getPreviewMedium().getUrl()));
mPlayer.setOnPreparedListener(mOnPreparedListener);
mPlayer.prepareAsync();
} catch (Exception e) {
LOG.toLog(e);
}
And in onPrepared :
mPlayer.start();
As i know, ViewPager is trying to initialize 3 items : current, previous and next, so if i'm switching between these 3 it works fine, but if i'm going further and then reurning back - video is loading again after mPlayer.setDataSource
Question: Is there any chance to cache it after first setup, so future calls of mPlayer.setDataSource will work instantly?
viewpager.setoffsetlimit() to the size of you item.
Use is prepared to check if is prepared.If it's prepared , you neednt't setData.
I am working on android app which can grab frame from video when user performs button click, the android app which is configured to play video using a TextureView. For capturing the frame as a bitmap, i am using:
Bitmap bit = textureView.getBitmap(width, height);
It works fine, but "getBitmap" takes quite long time (around 150-200 ms for a 640x480 frame). The issue is while getBitmap is being called the a gray frame is getting displayed on the view. This looks like some thing is flicking. Is there a way to get ride of this issue?
Thanks
You should use Handler to avoid delay time
new Handler().post(new Runnable() {
#Override
public void run() {
try {
Bitmap bit = textureView.getBitmap(width, height);
//you could save the video frames to use later
} catch (Exception ex) {
ex.printStackTrace();
}
}});
I have created an array of sounds that is randomly accessed to play via MediaPlayer when a button is pressed - this works fine my only issue is that when testing it and pressing the button rapidly the sound would stop and not play anymore - is there some way I can implement a start stop thing? I tried beginning my onClick method with a butPress.stop() but my android emulator didn't like it. the code follows :
public void onClick(View arg0) {
try{
display.setText(pp.getText());
int x = r.nextInt(sfx.length);
butPress = MediaPlayer.create(PitchMaker.this, sfx[x]);
butPress.start();
}catch(Exception e){
display.setText("Whoops we had a problem. Please try again");
}
}
Please use this line of code in the catch block so that we can get the exact error report.
Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_SHORT).show();
Hey guys I have come across an issue when using the MediaPlayer class in Android
Before you suggest SoundPool, I need an OnCompletion event to fire when the sound clip is done playing otherwise I would use it.
So the problem is is that when 3 or more clips are activated at the same time I only get the OnCompletion for the last 2 events, not all of them, anyone know a solution to this problem or know why it is happening?
// When the user clicks on the Chicken Image, this Function is called
public void onChickenClicked(View view)
{
// ToastMsg( "You Clicked the Chicken", Toast.LENGTH_SHORT );
// Then play the sound,
mMediaPlayer[CHICKEN] = MediaPlayer.create(MainActivity.this, R.raw.chicken_sound );
// Start playing the sound
mMediaPlayer[CHICKEN].start();
// This is to catch when the sound clip has ended, this will be
// used to stop the animation for the chicken
mMediaPlayer[CHICKEN].setOnCompletionListener( new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
System.err.println("Chicken On Complete");
// Stop the animation of the Chicken here
mAnimation.cancel();
mAnimation.reset();
// Then switch the image back to the original Chicken pic
ImageView imgView = (ImageView) findViewById(R.id.imageViewofChicken);
imgView.setImageResource(R.drawable.chicken);
mMediaPlayer[CHICKEN].reset();
}} );
// Finds the ImageView, replaces the base img with the alternate img, and plays the sound
animatePicture( R.id.imageViewofChicken, R.drawable.chicken_tongue);
}
public void onCowClicked(View view)
{
// ToastMsg( "You Clicked the Cow", Toast.LENGTH_SHORT );
// Then play the sound,
mMediaPlayer[COW] = MediaPlayer.create(MainActivity.this, R.raw.cow_sound );
// Start playing the sound
mMediaPlayer[COW].start();
// This is to catch when the sound clip has ended, this will be
// used to stop the animation for the chicken
mMediaPlayer[COW].setOnCompletionListener( new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
System.err.println("Cow On Complete");
// Stop the animation of the Chicken here
mAnimation.cancel();
mAnimation.reset();
// Then switch the image back to the original Chicken pic
ImageView imgView = (ImageView) findViewById(R.id.imageViewofCow);
imgView.setImageResource(R.drawable.cow);
mMediaPlayer[COW].reset();
}} );
// Finds the ImageView, replaces the base img with the alternate img, and plays the sound
animatePicture( R.id.imageViewofCow, R.drawable.cow_tongue);
}
//there are more but you get it idea here.
Anyone have any ideas on how I can get all of the OnCompleteListeners to fire?
So I figured it out, I simply replaced the MediaPlayer with the SoundPool, and then used
private final ScheduledExecutorService mScheduler = Executors.newScheduledThreadPool(MAX_ANIMALS);
to handle when the sound clips were done with, based on a function I saw on stackoverflow using the MediaPlayer to load the sound, then get the duration in milliseconds, and use it as the delay for the scheduler (mScheduler[x]).
It's a hack, but it got it done.
I want to play video with MediaPlayer in the background so when the user leave my app he will still hear the audio and when he is returning to the app he will see the video. I managed to do the first part with Service that plays the MediaPlayer, but I have a problem in the second part. When I leave the app and return the video does not show in the SurfaceView.
When the user return I created new Surface, so I tried this:
public void surfaceCreated(SurfaceHolder holder) {
if(mService!=null && mService.player.isPlaying()){
try {
mService.player.setDisplay(holder);
mService.player.prepare();
mService.player.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
While mService is my Service and he holds the MediaPlayer player.
In my research I saw this post:
Black screen when returning to video playback activity in Android
But this was posted a year ago so maybe anyone has any different and new answer.
EDIT:
I forgot to say that the video is streaming, so reset is not good option (i tried :)).
is it possible to save the SurfaceView in the Service and when the user return to take the view and add it dynamically to the current layout?
When you first launch Activity: onResume()->onSurfaceCreated()->onSurfaceChanged().
When you leave Activity: onPause()->onSurfaceDestroyed()
So i you leave your app, surface will be automatically destroy, you also can not save surfaceview in service.
Remember, if you want to show video again, surfaceview and holder callback must created again in onStart in case your home or lockscreen pressed
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
holder = surfaceView.getHolder();
holder.setFixedSize(800, 480);
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);