如何通过adb尽快捕获屏幕?

时间:2012-12-21 03:51:55

标签: android adb

最近,我写了一个PC客户端,可以使用 adb 实时显示和控制我的Android手机屏幕。我使用猴子来控制设备,它工作正常。问题是如何抓住手机屏幕并顺利显示它。

我提出的第一个解决方案是不断抓住framebufferadb(就像DDMS的屏幕截图功能一样)。现在,当我这样做时,性能是非常不可接受的。从framebuffer捕获的帧速率低至每秒5帧(帧大小为800 * 480)。当我在手机上滑动时,我的程序看起来像打嗝。

我的程序是使用ddmslib用java编写来抓取framebuffer

添加:
我发现将原始framebuffer数据编码为.png格式要慢得多,否则这将是传输压缩原始图像的快速方法。

如何将屏幕捕捉速度提升到平稳水平?

12 个答案:

答案 0 :(得分:23)

adb shell screencap -p | perl -pe 's/\x0D\x0A/\x0A/g' > screen.png

来源:

http://blog.shvetsov.com/2013/02/grab-android-screenshot-to-computer-via.html

答案 1 :(得分:9)

您可以使用:

<击>     $ adb shell screencap -p&gt; sc.png

,遗憾的是不起作用(文件已损坏),因此您的选项是

$ adb shell screencap -p /mnt/sdcard/sc.png
$ adb pull /mnt/sdcard/sc.png

虽然速度相对较快,但可能并不像你需要的那么快。

答案 2 :(得分:8)

如果慢速部分是png转换的原始部分(time adb shell screencap -p /sdcard/x.pngtime adb shell screencap /sdcard/nonpng.raw慢得多,就像我在游戏中那样)并且没有必要使用png,那么你可以这样做{{3 }}。它将原始数据转换为简单的ppm格式,并使用imagemagick将ppm转换为bmp,在获取原始数据后几乎没有开销

UPD:

max_plenert的这个shell脚本是一个更好的例子:

adb shell screencap /sdcard/mytmp/rock.raw
adb pull /sdcard/mytmp/rock.raw
adb shell rm /sdcard/mytmp/rock.raw

// remove the header
tail -c +13 rock.raw > rock.rgba

// extract width height and pixelformat:
hexdump -e '/4 "%d"' -s 0 -n 4 rock.raw
hexdump -e '/4 "%d"' -s 4 -n 4 rock.raw
hexdump -e '/4 "%d"' -s 8 -n 4 rock.raw

convert -size 480x800 -depth 8 rock.rgba rock.png

答案 3 :(得分:4)

在我的mac上的.bash_profile中:

function droidShot() {
  /full_path_to_droid_sdk/platform-tools/adb shell screencap -p | perl -pe 's/\x0D\x0A/\x0A/g' > $1.png
}

用法:

droidshot whatever

,文件显示在whatever.png

答案 4 :(得分:3)

使用此方法,我的应用程序继续以其完整帧速率运行

adb pull /dev/graphics/fb0

这将从帧缓冲区中下拉原始数据。它似乎与屏幕的宽度相同,但高度是填充的。我的设备上的帧缓冲区似乎是RGBA8888格式。要准确获得屏幕上显示的内容,您应该忽略Alpha通道。

请注意,这需要大约0.8秒才能下载(resoultion:480x854),但如果我在连续循环下载它,它不会影响设备的帧速率。

答案 5 :(得分:2)

这是一个缓慢的解决方案,我相信这是您在基于adb的解决方案中找到的更快的方式,

# this line require a superuser privilege:
adb shell "su -c 'cat /dev/graphics/fb0 > /sdcard/capture.raw'"

adb pull /sdcard/capture.raw

ffmpeg -loglevel panic -f rawvideo -pix_fmt bgr32 -s 320x480 -i \ 
    capture.raw -vcodec png -vframes 1 capture.png; 

this is the same code into my web application

答案 6 :(得分:1)

来自docs

拍摄设备屏幕截图

screencap命令是一个shell实用程序,用于截取设备显示的屏幕截图。在shell中,语法为:

screencap <filename>

要从命令行使用screencap,请键入以下内容:

$ adb shell screencap /sdcard/screen.png

以下是一个示例屏幕截图会话,使用adb shell捕获屏幕截图和pull命令从设备下载文件:

$ adb shell
shell@ $ screencap /sdcard/screen.png
shell@ $ exit
$ adb pull /sdcard/screen.png

录制设备屏幕

screenrecord命令是一个shell实用程序,用于记录运行Android 4.4(API级别19)及更高版本的设备的显示。该实用程序将屏幕活动记录到MPEG-4文件中。

Note: Audio is not recorded with the video file.

开发人员可以使用此文件制作宣传或培训视频。在shell中,语法为:

screenrecord [options] <filename>

要从命令行使用screenrecord,请键入以下内容:

$ adb shell screenrecord /sdcard/demo.mp4

按Ctrl-C停止屏幕录制,否则录制将在三分钟或 - 时间限制设置的时间限制内自动停止。

要开始录制设备屏幕,请运行screenrecord命令录制视频。然后,运行pull命令将视频从设备下载到主机。这是一个示例录制会话:

$ adb shell
shell@ $ screenrecord --verbose /sdcard/demo.mp4
(press Ctrl-C to stop)
shell@ $ exit
$ adb pull /sdcard/demo.mp4

screenrecord实用程序可以以您请求的任何支持的分辨率和比特率进行录制,同时保留设备显示的宽高比。默认情况下,实用程序以原始显示分辨率和方向记录,最大长度为三分钟。

使用它时,您应该注意screenrecord实用程序的一些已知限制:

某些设备可能无法以原始显示分辨率进行录制。如果您在屏幕录制时遇到问题,请尝试使用较低的屏幕分辨率。 不支持录制期间旋转屏幕。如果在录制过程中屏幕确实旋转,则录制中会切断部分屏幕。

答案 7 :(得分:0)

我对@ steveha的解决方案进行了改进:

使用以下内容创建一个shell脚本:' android-screenshot ':

adb shell screencap -p | perl -pe 's/\x0D\x0A/\x0A/g' > screen-`date +%Y-%m-%d_%X`.png

将此文件放在您喜欢的本地bin目录或任何其他 $ PATH 中。

这将允许您在当前目录中保存带有时间戳的文件。

请记住使用

使shell脚本可执行
chmod +x android-screenshot

答案 8 :(得分:0)

有些人说在Perl中有很多方法可以做一件事。 :-)无论如何,这个可以表现得更好(因为没有正则表达式),并且可以解决MS Windows中的Cygwin中的问题(其Perl将\n定义为CRLF):

adb shell screencap -p | perl -pe 'BEGIN { $/="\cM\cJ"; $\="\cJ"; } chomp;' > screen-$(date +%Y%m%d_%H%M%S).png

答案 9 :(得分:0)

Android 4.4中有一个screenrecord程序

adb shell screenrecord /data/local/tmp/test-video.m4v
adb pull /data/local/tmp/test-video.m4v ~/test-video.m4v

答案 10 :(得分:-1)

adb shell screenrecord --bit-rate 8000000 --time-limit 30 /sdcard/example.mp4

您也可以更改比特率并更改视频时长。

答案 11 :(得分:-1)

adb shell screencap /sdcard/screen.png && adb pull /sdcard/screen.png my_screen01.png