Capture Screen Shot From VideoView

margret

Well-Known Member
Licensed User
Longtime User
Hello Guys,

I am trying to capture a screen shot from a video playing in a VideoView. This video is paused and on screen. The code I am using was from Agrahams post. It saves anything on the screen just fine other than a VideoView. The VideoView is saved, it's just a black image. The same thing happens when doing a screen shot from the B4A IDE. Hoping someone will know a way to mod the code so it will get the VideoView Image. Didn't know if the VideoView could be set as the Target?

B4X:
Sub ScreenShot2(my_fn As String)
   Dim Obj1, Obj2 As Reflector
   Dim bmp As Bitmap
   Dim c As Canvas
   Obj1.Target = Obj1.GetActivityBA
   Obj1.Target = Obj1.GetField("vg")
   bmp.InitializeMutable(Activity.Width, Activity.Height)
   c.Initialize2(bmp)
   Dim args(1) As Object
   Dim types(1) As String
   Obj2.Target = c
   Obj2.Target = Obj2.GetField("canvas")
   args(0) = Obj2.Target
   types(0) = "android.graphics.Canvas"
   Obj1.RunMethod4("draw", args, types) 
   Dim Out As OutputStream
   namevar = s.Left(my_fn, s.Len(my_fn)-3) & "jpg"
   Out = File.OpenOutput("/Removable/MicroSD/My Files/Videos", namevar, False)
   bmp.WriteToStream(out, 100, "JPEG")
   Out.Close
   Return
End Sub

Thanks,

Margret
 

thedesolatesoul

Expert
Licensed User
Longtime User
Hi margret,
I am fairly sure that this cannot be done.
Video playback on modern smartphones is done via hardware acceleration. The video cores write out the decoded image directly to memory/framebuffer. There is no buffering/caching/storing of the picture before display due to performance reasons. This is the same for graphics acceleration (OpenGL).
Maybe if hardware acceleration is turned off, the image will be cached and you can access it but I doubt it is easy to do and in that case it will be very hard to acheive 30 fps anyway.
One way could be to read the raw image from memory, if you know the address of the framebuffer, but that could be in any weird format.
In terms of Android, the VideoeView extends SurfaceView. I think this is the same view used in OpenGL acceleration, or atleast something similar. It seems that the SurfaceView is placed at the very end of the view hierarchy (i.e. zorder = 0) so it will be the last view at the bottom, and will be hard to capture.
This is obviously only my understanding. Maybe someone else will have a solution.
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
Windows will grab most anything on the screen and I was hoping this would too.
Windows has not always been like this. I used to experience black screens on older versions (not any more) when taking screenshots with some media players or game screen shots.
The reason:
Turn OverlayReason: When the video plays, it is actually displayed on a different surface/layer called overlay that is produced by hardware acceleration. When you take a normal screen capture, you're taking it of the normal surface where the video isn't displayed. That's why it comes out black as it is invisible to the screen capture software.
Source: How to take Screenshots of Movies


Any way to read the screen pixels directly and read each value of the pixel and write it into a .jpg?

Personally, I think it is a security breach to be able to read the screen buffer since any app can see what is on the screen. Android memory spaces should be protected from other apps but I am not sure, cant find the documentation.

Anyway, on a rooted device you can read the framebuffer from /dev/graphics/fb0
This will contain raw data, I am not sure in what format.

You can have a look at: api - How to capture the android device screen content? - Stack Overflow

Maybe one way to check is to download a hardware accelerated launcher like Nova Launcher or Regina 3D and try to take a screenshot. If that works then there should be a way to read the framebuffer.

So far I have tried the following on the emulator:
B4X:
cmd
adb -e shell
cat /dev/graphics/fb0 > /sdcard/frame.raw
exit
adb pull /sdcard/frame.raw .

Then tried to find an RGB565 viewer. So far found this: [Application] RGB565Converter v0.3c two way RGB565<->image converter - xda-developers

so I could see the image.( a bit distorted)

But honestly I dont know if this is what you are looking for. Its far too in the 'unsupported' zone.

Anyways, now I am getting sidetracked!

What you actually want is here: Android-er: Display Video thumbnail in ListView
 

Attachments

  • t.jpg
    t.jpg
    37.8 KB · Views: 614
Upvote 0

Arun

Member
Licensed User
Longtime User
The idea of video capture is interesting and the code looked so simple, so I tried it, but its not working.

Sorry if I sound like an ignoramus, but thats what I am when it comes to complicated graphic coding.

Instead of asking too many questions, could you please tell me what I am doing wrong. I think it is wrong use/position of bmp=na.CreateVideoThumb

Thank in advance

B4X:
Sub ScreenShot2
   Dim Obj1, Obj2 As Reflector
   Dim bmp As Bitmap
   Dim na As videoThumbnail
   Dim c As Canvas
    Dim now, i As Long
    Dim dt As String
   DateTime.DateFormat = "yyMMddHHmmss"
      now = DateTime.now
     dt = DateTime.Date(now) ' e.g.: "110812150355" is Aug.12, 2011, 3:03:55 p.m.
   Obj1.Target = Obj1.GetActivityBA
   Obj1.Target = Obj1.GetField("vg")
   bmp.InitializeMutable(Activity.Width, Activity.Height)
   c.Initialize2(bmp)
   Dim args(1) As Object
   Dim types(1) As String
   Obj2.Target = c
   Obj2.Target = Obj2.GetField("canvas")
   args(0) = Obj2.Target
   types(0) = "android.graphics.Canvas"
   Obj1.RunMethod4("draw", args, types)
   bmp=na.CreateVideoThumb(File.DirRootExternal & "/" & dt & ".jpg")
   Dim Out As OutputStream
   Out = File.OpenOutput(File.DirRootExternal, dt & ".jpg", False)
   bmp.WriteToStream(Out, 100, "JPEG")
   Out.Close
   Return
End Sub
 
Last edited:
Upvote 0

murdoch1976

Member
Licensed User
Longtime User
bmp = na.CreateVideoThumb(Path)

... generates an error, telling me I need to initialise the bitmap. so...

bmp.Initialize3(na.CreateVideoThumb(imagepath))

... Generates a java "null pointer" exception. Does this mean the CreateVideoThumb had failed to decode the raw image?

... if I just run na.CreateVideoThumb(imagepath) on it's own without assigning the results to a variable or object it seems to work fine.

Help? (please)
 
Upvote 0

nw11

Member
Licensed User
Longtime User
B4X:
   Dim n As videoThumbnail 
   Dim AppBmp As Bitmap 
   AppBmp = n.CreateVideoThumb(File.DirRootExternal & "/download/Vid.mp4")

   Dim Out As OutputStream    
   Out = File.OpenOutput(File.DirRootExternal, "/download/Vid.jpg", False)    
   appbmp.WriteToStream(Out, 100, "JPEG")    
   Out.Close
 
Upvote 0

intera

Member
Licensed User
Longtime User
bmp = na.CreateVideoThumb(Path)

... generates an error, telling me I need to initialise the bitmap. so...

bmp.Initialize3(na.CreateVideoThumb(imagepath))

... Generates a java "null pointer" exception. Does this mean the CreateVideoThumb had failed to decode the raw image?

... if I just run na.CreateVideoThumb(imagepath) on it's own without assigning the results to a variable or object it seems to work fine.

Help? (please)

1 year and a half after...how can you solved?same happens to me....
 
Upvote 0
Top