You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Bash中通过按键停止树莓派视频流传输管道?

解决管道中无法检测按键输入的问题

你的问题核心在于管道的标准输入(stdin)继承逻辑:
原脚本里,管道最后一段的{ while ...; }子进程,它的stdin被前一个nc命令的输出接管了,而非你的终端设备。当nc没有输出(比如还没有客户端连接拉流)时,read -rsn1会一直阻塞,导致while循环仅执行一次(输出一次"test")就停住,根本无法捕获你按下的按键。

以下是两种可行的解决思路:

方案一:后台运行推流,前台监听按键

把推流管道放到后台,让前台进程直接处理终端输入,确保read能获取到键盘操作:

#!/bin/bash

WIDTH=1280
HEIGHT=720
FRAMERATE=30
SERVER_PORT=8111
STOP_KEY="p"

# 启动推流管道并后台运行,记录进程PID
libcamera-vid -n -t 0 --inline -o - --width $WIDTH --height $HEIGHT --framerate $FRAMERATE --libav-format h264 | nc -l -p $SERVER_PORT &
STREAM_PID=$!

# 前台循环监听按键
while true; do
    echo "Press '$STOP_KEY' to stop streaming..."
    read -rsn1 keypress

    if [ "$keypress" == "$STOP_KEY" ]; then
        echo "Stopping pipeline"
        # 杀死推流进程,避免残留子进程
        kill -INT $STREAM_PID
        pkill -INT -f "libcamera-vid"
        pkill -INT -f "nc -l -p $SERVER_PORT"
        exit 0
    fi
done

方案二:强制read从终端读取

如果想保留管道结构,可以让read直接从终端设备/dev/tty读取输入,绕过管道的stdin限制:

#!/bin/bash

WIDTH=1280
HEIGHT=720
FRAMERATE=30
SERVER_PORT=8111
STOP_KEY="p"

# 启动推流管道后台运行
libcamera-vid -n -t 0 --inline -o - --width $WIDTH --height $HEIGHT --framerate $FRAMERATE --libav-format h264 | nc -l -p $SERVER_PORT &
STREAM_PID=$!

# 循环监听终端按键
while true; do
    echo "test"
    # 指定从终端读取按键输入
    read -rsn1 keypress < /dev/tty

    if [ "$keypress" == "$STOP_KEY" ]; then
        echo "Stopping pipeline"
        kill -INT $STREAM_PID
        pkill -INT -f "libcamera-vid"
        pkill -INT -f "nc -l -p $SERVER_PORT"
        exit 0
    fi
done &

# 等待推流进程结束,避免脚本直接退出
wait $STREAM_PID

补充说明

  • 使用MobaXterm远程连接时,确保是交互式终端(默认ssh连接均为交互式,无需额外设置),非交互式终端下read无法读取按键。
  • 用kill -INT发送中断信号,和手动按Ctrl+C的效果一致,能让libcamera-vid和nc优雅退出,避免残留进程占用资源。

内容的提问来源于stack exchange,提问作者Pedro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 03:33:17