Android::get a frame of a Video? - android

I have a video, and I need to get some of its frames.
I used to do the following: Create a standart bitmap with the size of the video in question, create a canvas and set it to draw on a bitmap.
I use a SurfaceView and a surfaceHolder. A mediaPlayer is drawing on the surfaceView, and I have a method that calls surfaceView.draw(canvas), which draws on the canvas, which draws to the bitmap, which I eventually take and use...
My problem is that 60% of the time I get black frames. The mediaplayer plays its content in a separete thread, and I do not know when the video has started, and when - not, so I believe this is what is getting my black screens.
I need a workaround, a fix, or another method to get the video frame.
Thanks in advance.

You might try looking at the source of the gallery app or wherever its video thumbnails come from if they are externally created

How about using MediaMetadataRetriever's getFrameAtTime(). For lower API versions use this

Related

Use opengl es to render video to SurfaceView but concerned about more overhead

I wrote a video play view, it is a SurfaceView with a MediaPlayer instance. I attached the mediaplayer to the surface holder when surface created then start the play.
This is easy and everyone knows the details. But I want to draw a bitmap which is the first frame of the video to the surfaceview.Canvas is not a choice to draw the bitmap, because it will disable the mediaplayer to connect.
Since api level 14, we can new a surface with surfacetexture. So we can use opengl es to draw video frame and bitmap. But I am concerned about the performance.This way of playing video is more complicated and will it cause more overhead? Who can give me some advices?
You have a few options:
Use a FrameLayout to put a custom View (or maybe just an ImageView) on top of the SurfaceView. Draw your content there. When video playback starts, hide the View.
Connect GLES, draw the first frame, disconnect GLES, connect the MediaPlayer, play the movie. This is essentially what Grafika's PlayMovieSurfaceActivity does to clear the screen to black (see clearSurface()) before playing a movie.
As noted in your question, you can send the video to a SurfaceTexture, and then choose to render your content or render the image from the texture onto the SurfaceView.
#1 is the easiest. #3 adds complexity and is more expensive.

Drawing over a videoView after calling setZOrderOnTop(true)

The accepted answer for avoiding the black flicker on VideoView is to do something like the following. This works great, in fact it's smooth and I can reset the video, change the file and everything without a flicker.
Now...How can I draw a View on top of the VideoView?
mVideoView.setZOrderMediaOverlay(true);
mVideoView.setZOrderOnTop(true);
The order of the view on the layout makes no difference at all, since we are calling those methods. I would love to show you guys a screenshot of what's going on but it's simply drawing the video over the other views.
Hate answering my own questions but here it goes:
The least painful way of doing this is actually to avoid using a VideoView and resulting to the use of a TextureView and playing the video in its surface. That way it doesn't necessarily try to be on top of everything but still allows us to draw things over it.

How to get FPS of the video played by MediaPlayer when using a SurfaceView?

I am using MediaPlayer to play video which can be zommed in and out and am trying to see if there is any difference in the performance between using a SurfaceView and a TextureView for the player's output.
For the TextureView, I used SurfaceTextureListener.onSurfaceTextureUpdated() to know when a frame is shown and thus compute the FPS.
However, I can't find a way to do something similar when using a SurfaceView. I tried creating my own class extending SurfaceView and overloading onDraw(), but it looks like onDraw() is never called when playing the movie.
Any idea if and how this can be achieved?

Android: onPreviewFrame never called without SurfaceView

On some devices, onPreviewFrame is not called if no SurfaceView was set to display the camera preview.
However, I handle the camera in a service, so I can't set a SurfaceView but I don't want to have visible preview anyway.
How can this be done? Can I programmatically create a SurfaceView and set it with Camera::setPreviewDisplay?
This must be possible or not?
It works on almost every phone without a SurfaceView but not on HTC One X and Google Nexus One...
According to this question, creating a SurfaceView in code works fine. Though I don't think you can create it through a service.
Another approach is to create a 1px-1px SurfaceView inside a RelativeLayout and hiding it with some other view on top of it. (visibility should still be VISIBLE). We use this trick for Path camera UI where we render preview buffers through OpenGL and it works fine.
According to documentation readily configured, visible and displayed surface view is necessary to activate camera preview. It may be overlayued though
From API 11 on, you can use a SurfaceTexture instead of a SurfaceView to get frames from the camera. Then, instead of using Camera.setPreviewDisplay, simply use Camera.setPreviewTexture.
This answer as well as this one discuss this point.

Is it Possible to Use Both Video and Bitmaps?

I've been using SurfaceView and Canvas to draw Bitmaps to the screen. I've been looking into using videos to speed up some animation, but drawing Bitmaps and playing videos are two different things. Is it possible to draw both Bitmaps and videos to the screen? According to this post it doesn't sound possible, but maybe there's another way?
The last comment in there seems to indicate that he got it working. Instead of trying to layer a VideoView and your SurfaceView you are going to have to make yourself a MediaPlayer and set it up to play on a designated portion of the SurfaceView that you already have. VideoView is made up of a MediaPlayer and a SurfaceView, and you are disallowed from stacking two SurfaceViews.
That link to the api demos in the last comment from your question shows you how you "tie together" a SurfaceView and a MediaPlayer to make it show a video file.

Categories

Resources