问题描述
为了压测公司开发的某视频服务,需要配置一个后端推流服务,以flv over http的方式进行推送,可能要承载一千个连接(512码率的视频)。
步骤
安装ffmpeg
默认给我的机子是Cent OS 7.6,系统有点陈旧,内核也有点老,一开始想直接升级成Cent OS 8,但是换了个5.x的内核导致一些依赖出错,索性直接一键DD成Debian 10(运维那边也没有现成的系统)。
# 萌咖大佬的脚本
wget --no-check-certificate -qO InstallNET.sh 'https://moeclub.org/attachment/LinuxShell/InstallNET.sh'
# 华为云镜像站对公司网络友好些
bash InstallNET.sh -d 10 -v 64 -a --mirror 'https://mirrors.huaweicloud.com/debian/'
一键DD后的默认密码是MoeClub.org
让后换源
deb http://mirrors.huaweicloud.com/debian buster main contrib non-free
deb http://mirrors.huaweicloud.com/debian buster-updates main contrib non-free
deb http://mirrors.huaweicloud.com/debian buster-backports main contrib non-free
deb http://mirrors.huaweicloud.com/debian-security/ buster/updates main contrib non-free
换源之后安装ca-certificates
,可以将上面的http换成https
随后安装ffmepg apt install ffmepg
,成功后验证一下,输入ffmpeg
ffmpeg version 4.1.8-0+deb10u1 Copyright (c) 2000-2021 the FFmpeg developers
built with gcc 8 (Debian 8.3.0-6)
configuration: --prefix=/usr --extra-version=0+deb10u1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil 56. 22.100 / 56. 22.100
libavcodec 58. 35.100 / 58. 35.100
libavformat 58. 20.100 / 58. 20.100
libavdevice 58. 5.100 / 58. 5.100
libavfilter 7. 40.101 / 7. 40.101
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 3.100 / 5. 3.100
libswresample 3. 3.100 / 3. 3.100
libpostproc 55. 3.100 / 55. 3.100
Hyper fast Audio and Video encoder
usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...
ffmpeg推流
推流命令是ffmpeg -re -i ./test.flv -c copy -f flv "rtmp://<IP地址>/live/http"
,./test.flv
是flv文件的位置,"rtmp://<IP地址>/live/http"
则是推流的位置。
NGINX + nginx-http-flv-module 编译
下载NGINX 及 nginx-http-flv-module
wget http://nginx.org/download/nginx-1.20.2.tar.gz
wget https://github.com/winshining/nginx-http-flv-module/archive/refs/tags/v1.2.10.zip
tar -zxvf nginx-1.20.2.tar.gz
unzip nginx-http-flv-module-1.2.10.zip
随后编译
./configure
--prefix= /opt/nginx
--with-http_ssl_module \
--with-http_secure_link_module \
--add-module= ../nginx-http-flv-module-1.2.10
make -j$(($(nproc) + 1))
make install
安装成功后,启动nginx,输入命令/opt/nginx/sbin/nginx
,测试一下。
随后修改配置文件/opt/nginx/conf/nginx.conf
worker_processes 4;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name <IP地址>;
location / {
root html;
index index.html index.htm;
}
location /flv {
flv_live on;
chunked_transfer_encoding on;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
rtmp_auto_push on;
rtmp {
server {
listen 1935;
server_name 127.0.0.1;
notify_method get;
access_log /var/log/nginx/access.log;
chunk_size 4096;
application live {
live on;
allow publish all;
allow play all;
}
}
}
上述<IP地址>是希望监听的地址,如可以是localhost
,或者是0.0.0.0
,又或者是局域网IP/公网IP。
出现问题
以上方案进行推流,效果不是很理想,用VLC进行播放也会存在一定程度的卡顿,猜想原因可能是nginx对flv进行了切分,且nginx默认设置的buffer太大,导致buffer满了才发,然而对nginx动手脚也不是啥好办法,且还剩四小时就要验收(接的烂摊子)着实来不及。再网上重新调研后,我认为用srs搭建这个环境可能是比较不错的选择,抱着这种心态开始了进一步的尝试。
编译srs
srs比上面的方案好折腾地多。
# 直接下载最新的v4 beta 10
wget https://github.com/ossrs/srs/releases/download/v4.0-b10/srs-server-4.0-b10.tar.gz
tar -zxvf srs-server-4.0-b10.tar.gz
cd srs-4.0-b10/trunk && ./configure && make && make install
结束后,srs就会安装在/usr/local/srs
下(想换个目录就去修改Makefile中的安装目录)。
写几个小脚本控制启动、关闭和状态查看。
start.sh
#!/bin/bash
./objs/srs -c conf/srs.conf
stop.sh
#!/bin/bash
./etc/init.d/srs stop
status.sh
#!/bin/bash
./etc/init.d/srs status
ffmpeg 推流遇到的问题
如上面所示,我一开始采用的推流,不过是重复播放一个test.flv
文件,这才另一边播放时,就会产生一个问题,会读到flv文件的末尾,导致播放器认为视频中止。
对于这个问题,可以去修改srs的源码,在复制流时去掉flv文件的头和尾,或者用一种更加方便的方案,复制别的rtmp流,推送给srs。
可见以下命令ffmpeg -i "rtmp://<某个RTMP流的IP地址>/live/http.flv" -c copy -f flv "rtmp://<IP地址>/live/http"
需要注意的时,如果ffmpeg推送了一个错误的/有问题的/空的流给srs,可能导致srs崩溃。
总结
直接糊nginx一时爽,糊完火葬场。srs部署简单,承载力也不错,经测试,完全能跑满服务器的带宽,同时对CPU和内存的占用也不大。