最近,我写了一个PC客户端,可以使用 adb 实时显示和控制我的Android手机屏幕。我使用猴子来控制设备,它工作正常。问题是如何抓住手机屏幕并顺利显示它。
我提出的第一个解决方案是不断抓住framebuffer
到adb
(就像DDMS的屏幕截图功能一样)。现在,当我这样做时,性能是非常不可接受的。从framebuffer
捕获的帧速率低至每秒5帧(帧大小为800 * 480)。当我在手机上滑动时,我的程序看起来像打嗝。
我的程序是使用ddmslib
用java编写来抓取framebuffer
。
添加:
我发现将原始framebuffer
数据编码为.png
格式要慢得多,否则这将是传输压缩原始图像的快速方法。
如何将屏幕捕捉速度提升到平稳水平?
答案 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.png
比time adb shell screencap /sdcard/nonpng.raw
慢得多,就像我在游戏中那样)并且没有必要使用png,那么你可以这样做{{3 }}。它将原始数据转换为简单的ppm格式,并使用imagemagick将ppm转换为bmp,在获取原始数据后几乎没有开销
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;
答案 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