2019-04-09 晚的更新

更新了一下昨晚写的垃圾代码, 有如下改进。

  1. 有了更好看的输出信息
    • 需要安装有 Nerd Fonts 字体才能正确显示
  2. 修复了开始/结束录屏后需要手动 restart 一下 i3wm 才能显示录屏信息的问题
    • 按理说 i3blocks 正确使用的话,应该不会出现这个问题,不过文档我看的不是很明白
    • 这也会导致出现另一个影响体验的问题 (开始/结束录屏时会闪一下屏),不过不会影响所录的视频

写在前面

以前录屏都是按照 这里的方法 进行操作的 (需要结束录屏就 kill 掉 ffmepg 的进程)。

虽然这种方法很不优雅, 但录屏功能并不常用, 所以还能将就将就。

不过这两天录屏需求比较多, 感觉不能再将就了。

具体实现

直接上代码 (点击 此处 下载脚本)

下面代码实现了开始录屏, 结束录屏和输出录屏信息 (录屏时间和文件大小) 功能。

#!/bin/bash
# Copyright (C) 2019 文正•喵 <ivlioioilvi@outlook.com>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

#
# 使用 FFmpeg + i3blocks 进行录屏
#

# 定义变量
#
# 日志路径
LOG_PATH="$HOME/.cache"
# 具体的日志文件
REAL_LOG_FILE="$LOG_PATH/scf.log"
# 视频输出路径
VIDEO_PATH="$HOME/Pictures"
# 具体的视频输出文件
REAL_VIDEO_FILE="$VIDEO_PATH/Screen-Capture-$(date +'%Y-%m-%d-%H:%M:%S').mp4"
# 分辨率
RESOLUTION_VALUE="1920x1080"

# 开始录屏
start_Action() {
    # 判断是否存在 i3-msg 命令 (存在就手动刷新)
    if command -v i3-msg >/dev/null 2>&1; then
        i3-msg restart
    fi

    # 方案一 (有损编码,产生的文件体积较小,有音频)
    nohup ffmpeg -f x11grab -video_size "$RESOLUTION_VALUE" -framerate 25 -i "$DISPLAY" -f alsa -i default -c:v libx264 -preset ultrafast -c:a aac "$REAL_VIDEO_FILE" > "$REAL_LOG_FILE" 2>&1 &

    # 方案二 (无损编码,产生的文件体积很大,无音频)
    #nohup ffmpeg -f x11grab -video_size "$RESOLUTION_VALUE" -framerate 25 -i "$DISPLAY" -c:v ffvhuff "$REAL_VIDEO_FILE" > "$REAL_LOG_FILE" 2>&1 &
}

# 结束录屏
end_Action() {
    # 判断是否存在 i3-msg 命令 (存在就手动刷新)
    if command -v i3-msg >/dev/null 2>&1; then
        i3-msg restart
    fi

    # 结束 FFmpeg 进程
    killall ffmpeg >/dev/null 2>&1
    # 删除日志文件
    rm -rf "$REAL_LOG_FILE"
}

# 解析出录屏时间与文件大小
time_And_Size() {
    # 判断日志是否存在 (不存在就退出)
    if [ -f "$REAL_LOG_FILE" ]; then
        # 读取日志文件
        cat "$REAL_LOG_FILE" |

        # 替换 ^M 为回车 (在终端中按下 C-v, C-m 可打出 ^M)
        sed 's/
/\n/g' | 

        # 读取最后一行的内容
        tail -n 1 |

        # 过滤出其中的时间和文件大小数据
        awk '{ print $6$7, $8 }' |

        # 美化时间与文件大小的信息
        sed 's/size\=/\ /' | sed 's/time\=/\ /'

        # 等待 0.1 秒后递归
        sleep 0.1
        time_And_Size
    else
        # 此处表示无可用于解析的日志文件
        :
    fi
}

# 帮助页
manual_Page() {
    echo  -e "
    Usage: _scf [options] [arguments]

    Options:
    -h, --help     Displays this help
    -v, --version  Displays version information

    Arguments:
    s     Start recording screen
    e     End recording screen
    t     Resolve the time and file size
    "
}

# 版本信息
show_Version() {
    echo -e "
    _scf v_0.0.2

    It is written in the scripting language Bash.
    "
}

# 参数判断
case "$1" in
"-h")
    manual_Page
    ;;
"--help")
    manual_Page
    ;;
"-v")
    show_Version
    ;;
"--version")
    show_Version
    ;;
"s")
    start_Action
    ;;
"e")
    end_Action
    ;;
"t")
    time_And_Size
    ;;
*)
    echo -e "
    No options/arguments were used or the wrong options/arguments were used.

    Use the -h/-help option for detailed help.
    "
    ;;
esac

将上面的代码以 _scf 名称保存在 PATH 中, 就可以在 Rofi, dmenu, Krunner 等中方便的开始/结束录屏了。

不过,我比较偏向于键盘流, 所以在 i3wm 中绑定了如下的快捷键。

bindsym $mod+m mode "+Multimedia"
mode "+Multimedia" {
    bindsym l exec --no-startup-id _scf s       ,mode "default"
    bindsym Shift+l exec --no-startup-id _scf e ,mode "default"
    bindsym Escape mode "default"
    bindsym Return mode "default"
    bindsym $mod+m mode "default"
}

先按下 Win + M 键,再按下 L 键,可开始录屏。

先按下 Win + M 键,再按下 Shift + L 键,可停止录屏。

反正运行方法多种多样,看你的喜好。

而运行后,想要在 i3blocks 中显示录屏信息 (录屏时间和文件大小), 将下面的内容添加至 i3blocks 的配置文件中即可。

# Information during screen recording
#
[_scf]
command=_scf t
# The interval value persist (or -3) expects the command to be an infinite loop. Each line of the output will trigger an update of the block.
interval=persist

可还行?

用了几次,感觉还行吧。