树莓派硬件ffmpeg录制脚本
目录
这篇文章介绍了调用树莓派4b的硬件编码器进行视频录制
注意
注1、本人使用的录制设备为ms2130的uvc视频采集卡
1 折腾起源
1.1 吃灰的树莓派
1.2 吃灰的采集卡
发现家里吃灰的树莓派和吃灰的采集卡,看看能不能用树莓派来链接采集卡进行视频录制呢,就此开启了折腾之路。最开始想到的是用大名鼎鼎的obs录制,obs在软件源里就有直接安装就行。
sudo apt install obs-studio
安装后发现无法启动,终端运行如下命令即可,或者将图标快捷方式Exec项改为如下
env MESA_GL_VERSION_OVERRIDE=3.3 obs
运行了之后发现调用不了树莓派4b的硬件编码器,折腾失败。树莓派5可以试试,树莓派5没有硬件编码器。
2 ffmpeg录制脚本
2.1 Gemini推荐
折腾失败obs后,Gemini推荐了几个录制软件,都不好用。然后推荐用ffmpeg调用硬件编码器录制,Gemini可以帮忙将命令写成脚本,我也是第一次用命令行脚本直接录制视频,使用需要先安装几个软件。
sudo apt install ffmpeg v4l-utils alsa-utils
编辑脚本
nano auto_record_v2.sh
放入如下内容
#!/bin/bash
# 颜色定义
GREEN='\033[0;32m'
CYAN='\033[0;36m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
echo -e "${CYAN}=== 树莓派录制专家 (专业控温版) ===${NC}"
# 1. 自动定位硬件
VIDEO_DEV=$(v4l2-ctl --list-devices | grep -A 1 "USB" | grep "/dev/video" | head -n 1 | xargs)
[ -z "$VIDEO_DEV" ] && VIDEO_DEV="/dev/video0"
RAW_RES=$(v4l2-ctl --device=$VIDEO_DEV --get-fmt-video | grep "Width/Height" | awk -F': ' '{print $2}' | sed 's/ //g')
WIDTH=$(echo $RAW_RES | cut -d'/' -f1)
HEIGHT=$(echo $RAW_RES | cut -d'/' -f2)
RESOLUTION="${WIDTH}x${HEIGHT}"
CARD_ID=$(arecord -l | grep -i "USB" | head -n 1 | grep -oP 'card \K\d+')
DEV_ID=$(arecord -l | grep -i "USB" | head -n 1 | grep -oP 'device \K\d+')
AUDIO_HW="hw:${CARD_ID:-3},${DEV_ID:-0}"
MAX_FPS=$(v4l2-ctl --device=$VIDEO_DEV --list-formats-ext | grep -A 10 "$WIDTH" | grep "fps" | grep -oP '\(\K\d+\.\d+' | head -n 1 | cut -d. -f1)
[ -z "$MAX_FPS" ] && MAX_FPS=30
echo -e "${GREEN}硬件探测完成:${NC}"
echo -e " [视频] $VIDEO_DEV | 分辨率: $RESOLUTION"
echo -e " [音频] $AUDIO_HW"
echo "----------------------------------"
# 2. 用户输入参数
read -p "请输入录制帧率 (直接回车使用 $MAX_FPS): " FPS
FPS=${FPS:-$MAX_FPS}
SUGGEST_M=$(( WIDTH * HEIGHT * FPS / 6000000 ))
[ $SUGGEST_M -lt 2 ] && SUGGEST_M=2
[ $SUGGEST_M -gt 25 ] && SUGGEST_M=25
read -p "请输入视频码率 (单位:M,直接回车使用 ${SUGGEST_M}M): " BITRATE_VAL
BITRATE_VAL=${BITRATE_VAL:-$SUGGEST_M}
FINAL_BITRATE="${BITRATE_VAL}M"
# --- 编码器及格式选择逻辑 ---
echo -e "\n${CYAN}[编码器选择]${NC}"
echo -e " 1) 硬件编码 (h264_v4l2m2m) - 极低 CPU 占用"
echo -e " 2) 软件编码 (libx264) - 使用 veryfast 预设"
read -p "请选择 (1/2, 默认1): " ENC_CHOICE
PIX_FMT_OPT="-pix_fmt yuv420p" # 默认格式
if [ "$ENC_CHOICE" == "2" ]; then
V_ENCODER="libx264"
ENC_OPTS="-preset veryfast"
echo -e "${YELLOW}已选择软件编码器 (libx264)${NC}"
else
V_ENCODER="h264_v4l2m2m"
ENC_OPTS=""
echo -e "\n${CYAN}[硬件编码输入格式]${NC}"
echo -e " 1) YUV420P (由 CPU 转换,兼容性高)"
echo -e " 2) YUY2 直通 (无转换,CPU 占用最低,但文件为 4:2:2 采样)"
read -p "请选择 (1/2, 默认1): " FMT_CHOICE
if [ "$FMT_CHOICE" == "2" ]; then
PIX_FMT_OPT="" # 移除强制格式参数,触发原生协商直通
echo -e "${GREEN}已开启 YUY2 原生直通模式 (YUV422)${NC}"
else
PIX_FMT_OPT="-pix_fmt yuv420p"
echo -e "${YELLOW}已选择 YUV420P 兼容模式${NC}"
fi
fi
# ----------------------
# 3. 准备录制
RAW_FILE="raw_$(date +%H%M%S).mp4"
echo -e "\n${YELLOW}提示:按回车 [Enter] 开始录制,录制中按 'q' 键停止。${NC}"
read -p ""
# 4. 执行录制
echo -e "${RED}● 正在录制中...${NC}"
# 使用 2048 队列以应对 YUY2 的高带宽压力
ffmpeg -f v4l2 -thread_queue_size 2048 -video_size $RESOLUTION -framerate $FPS -i $VIDEO_DEV \
-f alsa -thread_queue_size 2048 -i $AUDIO_HW \
-c:v $V_ENCODER $ENC_OPTS -b:v $FINAL_BITRATE \
-c:a aac -ac 2 -ar 48000 \
$PIX_FMT_OPT -fflags +genpts -y "$RAW_FILE"
echo -e "\n${GREEN}✔ 原始录制已保存: $RAW_FILE${NC}"
echo "----------------------------------"
# 5. 音视频偏移校准
echo -e "${CYAN}[音视频同步校准]${NC}"
read -p "音频延迟补偿 (秒,无延迟请直接回车): " OFFSET
if [ -n "$OFFSET" ]; then
FIXED_FILE="fixed_${OFFSET}s_${RAW_FILE}"
echo -e "${YELLOW}应用补偿中...${NC}"
ffmpeg -i "$RAW_FILE" -itsoffset "$OFFSET" -i "$RAW_FILE" -map 0:v -map 1:a -c copy -y "$FIXED_FILE"
echo -e "${GREEN}✔ 校准完成: $FIXED_FILE${NC}"
else
echo -e "${GREEN}保持原始文件。${NC}"
fi
授予可执行权限
chmod +x auto_record_v2.sh
运行脚本
./auto_record_v2.sh
3 使用说明
3.1 录制帧率
树莓派4b硬件编码最高支持1080P分辨率30针,使用硬件编码器最高选择30针
3.2 录制码率
1080P分辨率30针建议最高8M码率
3.3 编码器
树莓派4b建议选择硬件编码器,树莓派5无硬件编码器选择软件编码器
3.4 硬件编码格式
兼容其他老手机等旧播放器选YUV420P,采集卡直通硬件编码器无转换选YUY2直通
3.5 录制
回车开始录制,按下q停止
3.6 偏移
发现音画不同步,输入后可将音频向后移动相应秒,硬件编码器几乎无偏移直接回车跳过即可。
3.7 注意
建议采集卡插入蓝色usb3接口,录制的视频与脚本在同目录下,采集卡插在usb3接口每次关闭录制需要重新插拔才能再次启动录制