微型卡片计算机上的推流开播工具

987 阅读3分钟

背景

前一段时间花了点时间研究无人直播,也简单了解几个相关工具,最后结合自己的需要基于 ffmpeg 撸了个脚本在各个平台上玩了玩。刚好最近空窗了,趁着有时间把这部分经历记录下来。

目前各平台上有不少点歌追剧的直播间,虽然因为各种各样的原因陆陆续续关停了很多,而当前播剧的也基本被几个地方电视台承包了,不过由于前一段时间充分的自由竞争,市场上出现了不少针对此场景的解决方案:OBS-StudioKPlayer、各路英雄基于FFmpeg开发的DIY推流工具、以及地方融媒体中心的流媒体广播系统。

各方案都有其市场和优势,但综合下来考虑到能耗,笔者利用身边的树莓派 4B 设备,基于 FFmpeg+Bash也撸了一个小工具live-pusher,本文主要介绍该工具特性和用法。

设计思路

考虑到传统主机的能耗过高(最少有200w+通常是500w左右),直播 24h 大概率会入不敷出,所以节能本方案的首要考虑因素:(1)基于 Raspbian 系统开箱即用,(2)媒体流直接转发尽量不做编解码处理。本工具的核心是支持批量循环推流出错重试断点续播、推流进程多开功能;另外就是考虑到卡片计算机存储空间有限,配套了磁盘挂载管理小工具;为方便持续运行将推流任务挂到后台,并提供了便捷的后台进程管理工具;

Live-Pusher 使用方法

  1. 烧录Raspbian系统
  2. 克隆工具库到本地
  3. 修改live-local.sh配置资源路径
  4. 准备rtmp://xxx推流地址,开启直播
# 在路由管理页面中查看树莓派IP地址用于SSH登录(或者用显示器在命令终端ifconfig查看)
ssh liver@192.168.1.100
# 查看默认的target
sudo systemctl get-default
# 开机以命令模式(图形模式启动:graphical.target)
sudo systemctl set-default multi-user.target
# 关机
sudo poweroff

# 安装live-pusher
cd ~ && git clone https://github.com/Chavin-Chen/live-pusher.git
chmod -R 755 ~/live-pusher/
echo '[ -s "$HOME/live-pusher/live-config.sh" ] && source /$HOME/live-pusher/live-config.sh' >>~/.bashrc
. .bashrc
live --version

# 使用文本编辑器修改 ~/live-pusher/live-local.sh 中的 main 函数配置
vi ~/live-pusher/live-local.sh
main() {
    case $1 in
    # ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ media#1 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    'video'*) # if there is no audio, you can try add 4th param: 'AAC'
        _play 'video' '/sdcard/video/' "$2"    
        ;;
    *)
        echo "Error:no media configuration for $1"
        ;;
    esac
}

# 在直播平台开播,并拷贝推流地址(注意拼接平台 token )开始推流
live -u 'rtmp://xxx' -m video

FFmpeg 硬件加速

由于要在推流端尽量降低功耗,而各平台的流接收通常只对h264 + AAC编码比较友好,再加上可能有一些水印、字幕、片头片尾需要处理和优化,而且实践中发现切换资源的时候一些平台上会存在黑屏卡顿甚至掉线的问题,为降低出错的可能最好对多个资源预先进行合并处理。这些处理 FFmpeg 都能胜任,但软解软编太费设备,为了减少时间消耗通常需要用上 GPU 硬件加速。以下是在 Unbuntu 上支持 FFmpeg 硬件加速的过程记录。

安装 CUDA

统一计算设备架构(Compute Unified Device Architecture, CUDA),是由 NVIDIA 推出的通用并行计算架构,暴露了英伟达开发的 GPU 的编程接口。

# 查看CPU架构
uname -a
# 查看GCC版本和Ubuntu版本
cat /proc/version
# 查看Ubuntu发行版本详细信息
lsb_release -a

# 选择合适的UCDA版本下载安装(注意勾选驱动)
wget https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda_11.8.0_520.61.05_linux.run
sudo sh cuda_11.8.0_520.61.05_linux.run

# 更新 ~/.bashrc
# 关于动态库也可添加 /usr/local/cuda-11.8/lib64 到 /etc/ld.so.conf 文件并执行 sudo ldconfig
export LD_LIBRARY_PATH="/usr/local/cuda-11.8/lib64:$LD_LIBRARY_PATH"
export PATH="/usr/local/cuda-11.8/bin:$PATH"

# 下载cudnn文件,解压后拷贝到目标地址
tar -xvf cudnn-linux-x86_64-8.9.4.25_cuda12-archive.tar.xz
sudo cp cudnn-linux-x86_64-8.9.4.25_cuda12-archive/include/cudnn*.h /usr/local/cuda/include
sudo cp -P cudnn-linux-x86_64-8.9.4.25_cuda12-archive/lib/libcudnn* /usr/local/cuda/lib64
sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*

# 监控GPU状态
watch -n 1 nvidia-smi

# 如果需要卸载重装
sudo /usr/local/cuda-11.8/bin/cuda-uninstaller

源码编译 FFmpeg

  1. 安装nv-codec-headers
  2. 编译安装编码库x264
  3. 编译安装FFmpeg
# 安装nv-codec-hearers 驱动头
git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git
cd nv-codec-headers
# cat README 查看驱动版本,若不匹配可通过git tag -l查看匹配
# 特别的若后续找不到编码器 h264_nvenc 可通过降此版本解决
make
sudo make install
cd ..
# 验证ffnvcodec,如果找不到把ffnvcodec.pc路径添加到PKG_CONFIG_PATH
pkg-config --modversion ffnvcodec


# 安装ffmpeg编码库
git clone https://code.videolan.org/videolan/x264.git
cd x264
# x264.h 文件中的 #define X264_BUILD 164 定义了api版本号和产物名,如遇到
#   ffmpeg: error while loading shared libraries: libx264.so.160
# 可回退代码或将API号修改为目标版本
./configure --disable-asm --enable-shared --enable-pic
make -j8
sudo make install

# 编译安装FFmpeg依赖
sudo apt-get install build-essential yasm cmake libtool libc6 libc6-dev unzip wget libnuma1 libnuma-dev
sudo apt-get install -y autoconf automake build-essential git libass-dev libfreetype6-dev libsdl2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev pkg-config texinfo wget zlib1g-dev
sudo apt install libavformat-dev libavcodec-dev libswresample-dev libswscale-dev libavutil-dev libsdl1.2-dev

git clone https://git.ffmpeg.org/ffmpeg.git
cd ffmpeg
git checkout -b n6.0 n6.0

# 如果有失败可以先 sudo apt install ffmpeg; sudo apt remove ffmpeg 把一些库先装上
./configure --prefix=/usr/local/ffmpeg --disable-static --disable-avdevice --disable-sdl2 --disable-ffplay --disable-zlib --disable-lzma --disable-doc --enable-gpl --enable-nonfree --enable-shared --enable-libx264 --enable-libfreetype --enable-cuda --enable-cuvid --enable-nvenc --enable-cuda-nvcc --enable-libnpp --extra-cflags=-I/usr/local/cuda/include --extra-ldflags=-L/usr/local/cuda/lib64

make clean
make -j8
sudo make install


# 添加 ~/.bashrc
export LD_LIBRARY_PATH="/usr/local/ffmpeg/lib:/usr/local/lib:$LD_LIBRARY_PATH"
export PATH="/usr/local/ffmpeg/bin:$PATH"

# 检查硬件加速
ffmpeg -hwaccels
ffmpeg -codecs | grep cuvid

# 去水印测试硬解硬编(需要根据实际文件名和水印位置修改参数)
ffmpeg -c:v h264_cuvid -i "./test.mp4" \
-c:a copy -c:v h264_nvenc -cq 33 \
-vf "delogo=x=1076:y=22:w=186:h=46,delogo=x=24:y=27+t*0.25:w=116:h=26" \
-y "test.flv" #>/dev/null 2>&1

# 如果出现问题需要重装,清理卸载可执行以下命令
make clean
sudo make uninstall

写在最后

除了本地资源的直播,还有更多的玩法可以探索:摄像头直播、转载转播、弹幕互动(内网穿透免去买服务的成本)。后面有时间再分享~