宁可枝头抱香死,何曾吹落北风中。这篇文章主要讲述一键生成 Android 录屏 gif 的脚本相关的知识,希望能为你提供帮助。
目的 编写 bash 脚本, 实现一行命令得到 Android 手机录制屏幕 gif 动图文件.
博主使用 ubuntu 系统, shell 为 bash. 这个脚本也可以用在 mac 系统上.
听说 windows 系统出了 ubuntu on windows, 不知道能不能使用这个脚本.
原理
adb shell screenrecord android 4.4 版本后系统内预置了一个 screenrecord 命令, 可以用来将屏幕录制为 MP4 格式. 具体命令格式可以通过 –help 参数查看:
$ adb shell screenrecord --help
Usage: screenrecord [options] <
filename>
Android screenrecord v1.2.Records the device'
s display to a .mp4 file.Options:
--size WIDTHxHEIGHT
Set the video size, e.g. "
1280x720"
.Default is the device'
s main
display resolution (if supported), 1280x720 if not.For best results,
use a size supported by the AVC encoder.
--bit-rate RATE
Set the video bit rate, in bits per second.Value may be specified as
bits or megabits, e.g. '
4000000'
is equivalent to '
4M'
.Default 4Mbps.
--bugreport
Add additional information, such as a timestamp overlay, that is helpful
in videos captured to illustrate bugs.
--time-limit TIME
Set the maximum recording time, in seconds.Default / maximum is 180.
--verbose
Display interesting information on stdout.
--help
Show this message.Recording continues until Ctrl-C is hit or the time limit is reached.
举例:
adb shell screenrecord --size "
360x640"
--bit-rate 2000000 /sdcard/android_screenrecord_test.mp4
上面的命令将把所连接的手机屏幕录制为 宽高 360x640, 比特率 2M 的视频, 保存为手机 sd 卡根目录下的 android_screenrecord_test.mp4 文件.
该命令会持续录制, 直到用 ctrl-c 终止命令, 那么录制也就结束了.
也可以用 –time-limit TIME 参数来预先指定录制时长, 到时间会自动结束. 默认的最大时长为 3 分钟.
ffmpeg 使用 ffmpeg 抽帧的命令将视频提取为一系列图片:
ffmpeg -i video.mp4 -r 5 '
frames/frame-%03d.jpg'
其中:
-r 5
代表抽取的帧率, 即每秒视频抽取 5 帧出来.convert 使用 imagemagick 包中的 convert 命令将一系列图片组合为 gif 动图格式:
convert -delay 20 -loop 0 *.jpg myimage.gif
其中:
-delay 20
代表所生成的 gif 动图每帧之间的时间间隔, 即每 0.2 秒显示下一帧.如果系统内还没有 convert 命令, 可以用如下命令安装:ffmpeg 及 convert 参数设置 上面两个命令中,
sudo apt-get install imagemagick
博主使用 ubuntu 16.10, 这个命令是预置在系统里的, 不需要安装.
ffmpeg -r 5
和 convert -delay 20
这两个参数值, 分别是 视频抽帧间隔 和 gif每帧间隔, 假设其分别为 video_fps 和 gif_delay, 那么这两个参数在设置时必须满足如下条件: video_fps * gif_delay =
100
如果乘积小于 100, 则生成的 gif 会比原本的播放速度快;
如果乘积大于 100, 则生成的 gif 会比原本的播放速度慢.
至于原因, 结合上面对这两个参数的介绍, 思考一下就明白了.
捕获录制结束事件 上面三个命令分开调用, 实现录屏为 gif 已经相当简单了.
如果要将三条命令写在一个脚本里, 在一个过程中完成功能, 第一个要解决的是如何捕获录制结束事件, 即 ctrl-c 命令.
在 bash 中可以通过下面脚本实现:
# catch ctrl-c signal
CTRL_C() {
# ctrl-c hit, do something
}
trap CTRL_C SIGINT
有了这个方法获取录制结束事件, 再往下就简单了.
这里遇到一个坑, 就是如果捕获 ctrl-c 后直接开始转换 gif 的操作, 会失败. 试过几次后, 发现是 ctrl-c 后其实 Android 的 screenrecord 命令并没有处理完, 这时候的视频还不可用. 解决的办法简单粗暴, 让脚本原地 sleep 2秒, 再去操作所生成的 MP4 文件就可用了.
最终脚本 也不知道该写些啥了, 直接贴出完整脚本吧:
#!/bin/bash
# author : liuxu-0703@
163.com#=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
# define param group hereQUALITY_1=
("
360x640"
1000000425)
QUALITY_2=
("
360x640"
1000000520)
QUALITY_3=
("
360x640"
10000001010)
QUALITY_4=
("
720x1280"
1000000425)
QUALITY_5=
("
720x1280"
1000000520)#=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
QUALITY=
(${QUALITY_2[@
]})RESOLUTION=
${QUALITY[0]}
BIT_RATE=
${QUALITY[1]}
GIF_FPS=
${QUALITY[2]}
GIF_DELAY=
${QUALITY[3]}# GIF_FPS and GIF_DELAY must meet the following condition:
# GIF_FPS * GIF_DELAY =
100OUTPUT_FILE_NAME=
android_screen_record.$(date +
%m%d%H%M%S).gif
OUTPUT_FILE_DIR=
$(pwd)
OUTPUT_VIDEO_NAME=
screenrecord_$(date +
%m%d%H%M%S).mp4
OUTPUT_VIDEO_DEVICE_DIR=
/sdcard
TMP_DIR=
/tmp/android_screen_to_gif_$(date +
%m%d%H%M%S)RECORDING=
true# you may use adb by absolute file path. if so, specify it here
ADB=
"
adb"
#=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
# catch ctrl-c signal
CTRL_C() {
if $RECORDING;
then
echo "
stop recording. start convert..."
RECORDING=
false
else
# ctrl-c hit but not for stop recording, just exit.
exit $?
fi# adb screenrecord may still deal with mp4 file creating,
# just wait for it a little while.
sleep 2s
adb pull $OUTPUT_VIDEO_DEVICE_DIR/$OUTPUT_VIDEO_NAME $TMP_DIR
if [ -f $TMP_DIR/$OUTPUT_VIDEO_NAME ];
then
# remove video on phone
adb shell rm $OUTPUT_VIDEO_DEVICE_DIR/$OUTPUT_VIDEO_NAMEecho "
converting file: $TMP_DIR/$OUTPUT_VIDEO_NAME"
MP4ToGIF $TMP_DIR/$OUTPUT_VIDEO_NAME
else
echo "
* create screen record mp4 fail"
exit 2
fi
}
trap CTRL_C SIGINT# catch script exit event
CLEAR_WORK() {
if [ -e $TMP_DIR ];
then
# since the tmp files have been put into /tmp/ dir, they will get
# removed on system reboot. thus we are in no hurry to remove them now.
# un-commit this line if you want to remove tmp files immediately after script run
#rm $TMP_DIR
echo
fi
}
trap "
CLEAR_WORK"
EXIT#=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
function MP4ToGIF() {
echo "
*** extract frames ***"
mkdir $TMP_DIR/frames
ffmpeg -i $1 -r $GIF_FPS "
$TMP_DIR/frames/frame-%03d.jpg"
echo "
*** convert frames to gif ***"
convert -delay $GIF_DELAY -loop 0 "
$TMP_DIR/frames/*.jpg"
$OUTPUT_FILE_DIR/$OUTPUT_FILE_NAME
}#=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
if [ ! -d "
$OUTPUT_FILE_DIR"
];
then
echo "
* output dir not exists: $OUTPUT_FILE_DIR"
exit 1
fi
if [ ! -e $TMP_DIR ];
then
mkdir $TMP_DIR
fi
if [ ! -e $TMP_DIR ];
then
echo "
* tmp dir not exists: $TMP_DIR"
exit 1
fiecho "
params: $RESOLUTION, $BIT_RATE, $GIF_FPS, $GIF_DELAY"
adb shell screenrecord --verbose --size $RESOLUTION --bit-rate $BIT_RATE $OUTPUT_VIDEO_DEVICE_DIR/$OUTPUT_VIDEO_NAME
开头定义的那几个数组, 是为了便于测试. 最终生成的 gif 文件也直接保存在了当前目录下.
主要是因为加上参数化, 代码会多很多, 就不容易找到主要功能了.
带参数化, 带简易帮助文档的完整脚本, 可以在下面链接中找到:
android_screen2gif.sh
使用 使用前提:
- adb 可以正常连接到手机, 就是不能有 offline 之类的问题. (这里安利另一篇文章: 解决 ubuntu adb 设备识别问题)
- 手机必须是 4.4 以上系统.
$ cd /tmp/
$ android_screen2gif.sh
params: 360x640, 1000000, 5, 20
Main display is 720x1280 @
60.00fps (orientation=
0)
Configuring recorder for 360x640 video/avc at 1.00Mbps
Content area is 360x640 at offset x=
0 y=
0
这时录制正在进行, 命令行挂起. 等你认为录制可以结束了, 按下 ctrl-c, 录制结束, 开始转换 gif 的步骤. 一般需要3到4秒, 录屏的 gif 就在当前目录生成了.
^Cstop recording. start convert...
[100%] /sdcard/screenrecord_0407090859.mp4
converting file: /tmp/android_screen_to_gif_0407090859/screenrecord_0407090859.mp4
*** extract frames ***
ffmpeg version 3.0.7-0ubuntu0.16.10.1 Copyright (c) 2000-2017 the FFmpeg developers
......
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '
/tmp/android_screen_to_gif_0407090859/screenrecord_0407090859.mp4'
:
......
Output #0, image2, to '
/tmp/android_screen_to_gif_0407090859/frames/frame-%03d.jpg'
:
......
*** convert frames to gif ***
result gif file:
/tmp/android_screen_record.0407090859.gif
这一步输出较多, 用
......
代替了部分输出. 最后那行就是最终生成的 gif 录屏文件了.参数建议 根据自测 及 最终 gif 生成的过程, 可以得到如下结论:
视频解析度参数:
宽高越大越清晰, 最终生成的 gif 文件越大. 这个是很明显的.
最好按手机竖屏显示的方式, 将解析度设置为 9:16 的比例. 如果设置为其他比例, 比如 480:480, 则录制出的视频会有很宽的黑边.
【一键生成 Android 录屏 gif 的脚本】视频比特率参数:
先说结论: 比特率设置基本不会影响最终生成的 gif 文件质量.
因为最终 gif 文件来自视频抽帧, 视频比特率的大小对于比如每秒抽取10帧这样的需求, 对抽取出的图片清晰度影响不大. 因此为了中间文件更小, 建议把这个参数设低即可.
抽帧帧率 及 每帧间隔:
这两个参数对最终 gif 质量影响很大. 其中:
抽帧帧率越大, 最终 gif 质量越高;
每帧间隔越小, 最终 gif 质量越高.
如前述, 这两个参数必须成对设置. 如果这两个参数都取整数的话, 基本上可以设置的就下面这几对:
2, 50
4, 25
5, 20
10, 10
其中:
10, 10
这组, 设置每秒10帧, gif 每帧间隔 0.1 秒, 这样5秒的gif文件就要大概 10M 大小了. 2, 50
这组, 设置每秒2帧, gif 每帧间隔 0.5 秒, 最终gif文件卡顿就很严重了. 因此建议选取
5, 20
这组参数. 如果对gif质量要求很高, 可以试试 10, 10
这组参数.综上, 小伙伴们可以自己尝试下设置不同的参数组合, 试几次就能体会该怎么设置了.
参考:
create gif from mp4 via command line再次无耻的安利安利自己的脚本项目:
command convert doc
android_screen2gif.sh
原创文章, 转载请注明出处: http://blog.csdn.net/liuxu0703/article/details/69397154
推荐阅读
- 在Android Studio中打开Android Device Monitor时报错的解决方法
- 迅为开发板知识库-4418开发板编译Android镜像内容分享
- Android底层有一定的认识,研究过相关的Android源码
- 安卓工程的启动过程
- Android性能优化的一些方案
- Android开发菜单以及子菜单
- 最新人工智能和机器学习的5大趋势
- 任务管理软件合集(16款最佳任务管理软件(免费和付费))
- 网络安全术语解释(每个人都应该知道的25个网络安全术语)