Scrcpy: Is there a way to capture only a frame or screenshot rather than a video stream?

Created on 2 Aug 2019  路  12Comments  路  Source: Genymobile/scrcpy

I am looking for a minimalized version of what the video stream part of scrcpy does.

It is apparently not so straightforward to take a screenshot of an android device outside of the android context. I imagine similar frustrations occurred while learning how to attain the video stream. Is there a way to only attain one frame or a screenshot at the time of a request?

screenshot

Most helpful comment

What is the exact command you execute? Did you try with:

adb exec-out adb exec-out screencap -p > file.png
adb shell adb exec-out screencap -p > file.png

?

Actually, I just did

adb shell screencap -p /storage/emulated/0/Download/img.png

I'll have to see if those behave differently, though I don't understand why they would.

Edit: actually, I think you have a typo. Shouldn't those commands be:

adb exec-out screencap -p > file.png
adb shell screencap -p > file.png

Both of these result in empty files for me with protected apps. Both work on the home screen.

All 12 comments

does ascreenshot not accomplish what you need?

Is there a way to only attain one frame or a screenshot at the time of a request?

It requires some investigations to do it in Java without an Android context (I have no time to do this now).

Sometimes, the implementation of an existing command may help:

 adb exec-out screencap -p > file.png

But in this case, it's implemented in C++: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/cmds/screencap/screencap.cpp

does ascreenshot not accomplish what you need?

This is what I am wanting, I am not sure what you are suggesting.

adb exec-out screencap -p > file.png

This is similar to what I was already using, but with the stdout captured by the process and handled without writing to disk. This method, however does take about 1-2 seconds to work.

I did find a method that allows me to access a screenshot in about 0.07s. Which is much better, giving me about 14 fps maximum. Not ideal, but much better than using the screencap shell command.

SurfaceControl.screenshot method gives a HARDWARE.Bitmap, which unfortunately must be copied before it is read. Once copied, it can be converted into a bytebuffer and passed along the socket.

This is what I am wanting, I am not sure what you are suggesting.

Sorry, I thought I was in the wrong repo. I know that https://github.com/IntergalacticPenguin/mobile-toolkit has a feature to take screenshots that works pretty well for me. But I believe they are using screencap under the hood, so if that does not work for your use case then it may not work for you.

I looked into this a little bit more, and found that SurfaceControl invokes a native method, and this native method essentially executes "/system/bin/screencap". Now I wanted to see if a java program executing "/system/bin/screencap" as a subprocess would give any speed-up.

Something of this sort:

            try{
                Process process = Runtime.getRuntime().exec("/system/bin/screencap");
                BufferedReader ob = new BufferedReader(
                        new InputStreamReader(process.getInputStream()));
                int currentChar;
                while (( currentChar = ob.read()) != -1) {
                    buffer.putChar((char) currentChar);
                }
            } catch(Exception e){
                System.out.println(e);
            }

But this is about as fast as calling adb shell screencap (probably is the exact same thing)
This script takes 50 seconds to take 100 screencaps.

I am wondering, how is Surfacecontrol.java able to execute native code so much faster than Runtime.exec?

Am I missing something fundamental?

@toddsierens

SurfaceControl.screenshot method gives a HARDWARE.Bitmap, which unfortunately must be copied before it is read. Once copied, it can be converted into a bytebuffer and passed along the socket.

As you mentioned above, that's exactly what I've implemented in DroidCast.

This script takes 50 seconds to take 100 screencaps.
...
how is Surfacecontrol.java able to execute native code so much faster than Runtime.exec?

IMO, the reason behind this is IPC (via Android binder) seems more efficient than creating new Process and then getting the job done.

One good reason to add this feature directly to scrcpy is that some applications block taking a screenshot, and this affects the adb screencap tool too - it just saves an empty file for me. This apparently doesn't prevent adb itself from capturing the screen, so being able to save a screenshot with scrcpy would be very useful.

being able to save a screenshot with scrcpy would be very useful.

Yes.

it just saves an empty file for me

What is the exact command you execute? Did you try with:

adb exec-out screencap -p > file.png
adb shell screencap -p > file.png

?

What is the exact command you execute? Did you try with:

adb exec-out adb exec-out screencap -p > file.png
adb shell adb exec-out screencap -p > file.png

?

Actually, I just did

adb shell screencap -p /storage/emulated/0/Download/img.png

I'll have to see if those behave differently, though I don't understand why they would.

Edit: actually, I think you have a typo. Shouldn't those commands be:

adb exec-out screencap -p > file.png
adb shell screencap -p > file.png

Both of these result in empty files for me with protected apps. Both work on the home screen.

What is the exact command you execute? Did you try with:

adb exec-out adb exec-out screencap -p > file.png
adb shell adb exec-out screencap -p > file.png

?

Actually, I just did

adb shell screencap -p /storage/emulated/0/Download/img.png

I'll have to see if those behave differently, though I don't understand why they would.

Edit: actually, I think you have a typo. Shouldn't those commands be:

adb exec-out screencap -p > file.png
adb shell screencap -p > file.png

Both of these result in empty files for me with protected apps. Both work on the home screen.

I can confirm that I'm having the same issue. Is there any way to solve it?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

qymspace picture qymspace  路  3Comments

fleytman picture fleytman  路  4Comments

BloodPHamtOm picture BloodPHamtOm  路  3Comments

targor picture targor  路  3Comments

cutoseo picture cutoseo  路  4Comments