I would like to play frame by frame with the videoview.
I have this:
mVideoView.seekTo(mVideoView.getCurrentPosition()+1);
But after this I do not see the frame until I click play... I do not want that, I just want to see the next frame.
Also - can I do the same for previous frame?
Thanks in advance.
It will not seek while paused. But you can always pause right after seeking, if you use a SurfaceView and a MediaPlayer because VideoView doesn't have the onSeekComplete callback.
public void seek() {
mediaplayer.start();
mediaplayer.seekTo(mediaplayer.getCurrentPosition()+1);
}
public void onSeekComplete(MediaPlayer mp) {
mediaplayer.pause();
}
This will seek and display something. Unfortunately you will find that this does not allow you to play frame by frame.
You can use MediaMetadataRetriever to select the frame you want and next get it as a BitMap using MediaMetadataRetriever.getFrameAtTime(long timeUs). It will work much better than using a MediaPlayer.
I hope it is useful.
Related
I'm using ExoPlayer for video playback and I have a seekbar to allow user to move back or forward during playback.
What I want to achieve is for user to be able to seek while also be able to preview the frame at the current time relative to the seeker position.
Problem is, the player is displaying black frame until the user lets go of the seekbar. I'm think it's because seekTo is being called multiple times and the player just doesn't have enough time to load the frame?
Any idea how to work around this?
This is how I call the seekTo inside the seekbar listener
time_range.setOnRangeSeekbarChangeListener { minValue, maxValue ->
val mediaUri = Uri.parse(media?.dataUrl)
player?.prepare(buildClipMediaSource(mediaUri, startTime.toInt(), endTime.toInt()))
player?.seekTo((startTime * 1000f).toLong())
player?.playWhenReady = true
}
My app plays a video inside a surfaceview. And I stop the mediaplayer from playing when onPause(). However, when I return from another activity, the surfaceview is all black and starts to show frames only if I start playing video again. I want to know if there is a method to preserve the last frame when it stops. Thanks a lot.
I used 2 SurfaceViews, first for playing videos and second surf for displaying pictures.
when I return from pause, if mediaplayer is not playing, I get current frame of video by this part of code:
try {
mediaMDRetriever.setDataSource(mediaPath);
picBitmap = mediaMDRetriever.getFrameAtTime();
} catch (Exception e) {
}
and draw it on the second surfview.
you can clear second SurfaceView if needed by the following code:
Canvas surfCanvas = surfHolder2.lockCanvas();
surfCanvas.drawColor( 0, PorterDuff.Mode.CLEAR );
surfHolder2.unlockCanvasAndPost( surfCanvas );
I have a video player that gets reset and loaded with a new video in one activity. One of the problems I had with this approach was that the last frame of the previous window was still shown when the next video is loaded. Several people have the same issue.
I solved this by doing the following in the onCompletion listener, similar to what is explained in this question and this other one:
mPlayer.stop();
mPlayer.release();
Canvas canvas = mPlayView.getHolder().lockCanvas();
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
mPlayView.getHolder().unlockCanvasAndPost(canvas);
mPlayer = null;
Then later, I call this again:
mPlayer = new MediaPlayer();
mPlayer.setDataSource(videoPath);
mPlayer.setDisplay(mSurfaceHolder);
mPlayer.setScreenOnWhilePlaying(true);
mPlayer.setOnPreparedListener(this);
mPlayer.setOnCompletionListener(this);
mPlayer.setOnVideoSizeChangedListener(this);
mPlayer.setOnErrorListener(this);
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.prepare();
// wait for onPrepared callback and play
The problem is that the video play surface is still blackāno video is shown anymore.
How do I "reset" the canvas and make it show the video again?
Or if that does not work, how do I clear the canvas of the last frame instead? I tried this but the next loaded video still shows the last frame of the previous one.
Thank you for looking at my post. So I was going to make an AIR for Android game, so I got to work, and, well heres the problem.
stop();
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
btn_Play.addEventListener(TouchEvent.TOUCH_TAP, fl_TapHandler_2);
function fl_TapHandler_2(event: TouchEvent): void
{
gotoAndPlay(91);
}
When ever I tap the btn_Play, it just goes to Frame 1 and plays. BTW this is on Frame 90. Please help!
if you have only 90 frames and you define
gotoAndPlay(91);
you will go to frame 1, change to:
gotoAndPlay(90);
if you have more than 90 frames probably you need to read this:
http://www.kirupa.com/forum/showthread.php?335765-gotoAndPlay%28%29-and-frame-script-stop%28%29
Have you wrote stop() method at end of the frame? if not try this at end of the frame or how many frames are you using kindly check that.
stop()
I'm working with a VideoView for showing a video stream. Because I need the MediaController to be attached to the view itself and I want to prevent the black screen flicker caused by the videoview. I've tested the below code on my Nexus 7, worked like a charm. But now I tested it on my SGS2, and for some reason OnVideoSizeChanged is never called.
#Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
Log.i("ONPREP", "called");
mp.setOnVideoSizeChangedListener(new OnVideoSizeChangedListener() {
#Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
videoview.setMediaController(mc);
mc.setAnchorView(videoview);
videoview.setBackgroundColor(Color.TRANSPARENT);
Log.i("ONSIZECHANGE", "called");
}
});
}
The video is playing like it should, I tested this by removing the OnVideoSizeChangedListener and just putting the code in the onPrepared method, but this is bringing back the screen flicker issue and leaves the mediacontroller unattached. This behaviour is also shown by the Log info in LogCat, ONPREP tag shows but never the ONSIZECHANGE. On my N7 both show, obviously cause the background color is changed.
This is the code that sets and starts the video:
videoview.setOnPreparedListener(MainActivity.this);
mc = new MediaController(MainActivity.this);
mc.setMediaPlayer(videoview);
videoview.setVideoURI(videourI);
videoview.start();
So why is it called on one device and not on another?
Edit:
Tested it on my Note 2, same issue as on the SGS2.
onVideoSizeChanged is triggered by an event from the low-level player implementation, which can be different on different platforms. It is perfectly legal for the player to call onVideoSizeChanged before onPrepared.
Actually VideoView is setting its own OnVideoSizeChangedListener callback for managing surface size, so you probably shouldn't use it at all. From your example it is not clear to me why you are using it, setMediaController should be called in onPrepared, not onVideoSizeChanged (which can be called multiple times).
This seems to be a bug with the samsung devices.
I noticed in my application that if the videoview size is 0x0 (probably also if it is invisible/gone) the onVideoSizeChange is not called. Once I set the videoview size to a non 0x0 value the onVideoSizeChange is called correctly.