bash 一键录屏 Android 生成 gif 文件脚本
目的编写 bash 脚本,实现一行命令得到 Android 手机录制屏幕 gif 动图文件. 博主使用 ubuntu 系统,shell 为 bash. 这个脚本也可以用在 mac 系统上. 原理adb shell screenrecordAndroid 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 文件. ffmpeg使用 ffmpeg 抽帧的命令将视频提取为一系列图片: ffmpeg -i video.mp4 -r 5 'frames/frame-%03d.jpg' 其中: convert使用 imagemagick 包中的 convert 命令将一系列图片组合为 gif 动图格式: convert -delay 20 -loop 0 *.jpg myimage.gif 其中: 如果系统内还没有 convert 命令,可以用如下命令安装: ffmpeg 及 convert 参数设置上面两个命令中, 如果乘积小于 100,则生成的 gif 会比原本的播放速度快; 至于原因,结合上面对这两个参数的介绍,思考一下就明白了. 捕获录制结束事件上面三个命令分开调用,实现录屏为 gif 已经相当简单了. # catch ctrl-c signal CTRL_C() { # ctrl-c hit,do something } trap CTRL_C SIGINT 有了这个方法获取录制结束事件,再往下就简单了. 最终脚本也不知道该写些啥了,直接贴出完整脚本吧: #!/bin/bash # author : liuxu-0703@163.com #======================================================== # define param group here QUALITY_1=("360x640" 1000000 4 25) QUALITY_2=("360x640" 1000000 5 20) QUALITY_3=("360x640" 1000000 10 10) QUALITY_4=("720x1280" 1000000 4 25) QUALITY_5=("720x1280" 1000000 5 20) #======================================================== 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 = 100 OUTPUT_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_NAME echo "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 fi echo "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 使用使用前提:
脚本本身就是为了使用简单写的. 只需在命令行直接执行脚本,即可开始手机屏幕录制. 因为是测试,选在 /tmp 目录操作. $ 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 生成的过程,可以得到如下结论: 视频解析度参数: 视频比特率参数: 抽帧帧率 及 每帧间隔: 2,50 4,25 5,20 10,10 其中: 综上,小伙伴们可以自己尝试下设置不同的参数组合,试几次就能体会该怎么设置了. 参考:create gif from mp4 via command line 脚本获取地址(github): android_screen2gif.sh (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |