目录

树莓派硬件ffmpeg录制脚本

这篇文章介绍了调用树莓派4b的硬件编码器进行视频录制

注意
注1、本人使用的录制设备为ms2130的uvc视频采集卡,本脚本全部由ai生成,仅作记录。

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) - 默认 YUY2 直通"
echo -e "  2) 软件编码 (libx264)"
read -p "请选择 (1/2, 默认1): " ENC_CHOICE

if [ "$ENC_CHOICE" == "2" ]; then
    V_ENCODER="libx264"
    ENC_OPTS="-preset veryfast"
    PIX_FMT_OPT="-pix_fmt yuv420p"
else
    V_ENCODER="h264_v4l2m2m"
    ENC_OPTS="" # 录制模式下保持原生设置
    PIX_FMT_OPT="" 
fi

# --- 模式选择:录制 vs 直播 ---
echo -e "\n${CYAN}[操作模式]${NC}"
echo -e "  1) 本地录制 (MP4)"
echo -e "  2) 直播推流 (RTMP/RTMPS)"
read -p "请选择 (1/2, 默认1): " MODE_CHOICE

# 初始化额外参数
EXTRA_STREAM_ARGS=""

if [ "$MODE_CHOICE" == "2" ]; then
    read -p "请输入推流地址: " STREAM_URL
    OUTPUT_DEST="$STREAM_URL"
    OUTPUT_FMT="-f flv"
    
    # 仅在直播模式下注入 GOP 和网络优化参数
    # -g: 关键帧间隔 (设为 FPS 的 2 倍,即 2 秒一个关键帧)
    # -maxrate & -bufsize: 防止码率剧烈波动导致丢帧
    EXTRA_STREAM_ARGS="-g $((FPS * 2)) -maxrate $FINAL_BITRATE -bufsize $((BITRATE_VAL * 2))M"
    
    echo -e "${YELLOW}模式:直播推流模式 (已应用 GOP 与网络优化)${NC}"
else
    OUTPUT_DEST="raw_$(date +%H%M%S).mp4"
    OUTPUT_FMT=""
    echo -e "${YELLOW}模式:本地录制模式 (保持最高原生效率)${NC}"
fi

# ----------------------

# 3. 准备开始
echo -e "\n${YELLOW}提示:按 [Enter] 开始,运行中按 'q' 停止。${NC}"
read -p ""

# 4. 执行任务
echo -e "${RED}● 任务运行中...${NC}"

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 $EXTRA_STREAM_ARGS -b:v $FINAL_BITRATE \
-c:a aac -ac 2 -ar 48000 \
$PIX_FMT_OPT -fflags +genpts $OUTPUT_FMT -y "$OUTPUT_DEST"

# ----------------------

# 5. 后续处理 (仅限录制模式)
if [ "$MODE_CHOICE" != "2" ]; then
    echo -e "\n${GREEN}✔ 原始录制已保存: $OUTPUT_DEST${NC}"
    echo "----------------------------------"
    echo -e "${CYAN}[音视频同步校准]${NC}"
    read -p "音频延迟补偿 (秒,无延迟请直接回车): " OFFSET
    if [ -n "$OFFSET" ]; then
        FIXED_FILE="fixed_${OFFSET}s_${OUTPUT_DEST}"
        ffmpeg -i "$OUTPUT_DEST" -itsoffset "$OFFSET" -i "$OUTPUT_DEST" -map 0:v -map 1:a -c copy -y "$FIXED_FILE"
        echo -e "${GREEN}✔ 校准完成: $FIXED_FILE${NC}"
    fi
else
    echo -e "\n${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 直播

选择直播需要输入推流地址,哔哩哔哩直播,建议搭配bilibili_live_stream

3.5 录制

回车开始录制,按下q停止

3.6 偏移

发现音画不同步,输入后可将音频向后移动相应秒,硬件编码器几乎无偏移直接回车跳过即可。

3.7 注意

建议采集卡插入蓝色usb3接口,录制的视频与脚本在同目录下,采集卡插在usb3接口每次关闭录制需要重新插拔才能再次启动录制。如对脚本功能有其他需求,可全部复制脚本让ai修改。