【音视频】nginx-hls-多码率测试环境搭建

一、nginx-rtmp开源项目下载

1.1 项目介绍

项⽬地址:https://github.com/winshining/nginx-http-flv-module

nginx-http-flv-module的其他功能与nginx-rtmp-module的对⽐:

功能 nginx-http-flv-module nginx-rtmp-module 备注
HTTP-FLV(播放) × 支持HTTPS-FLV和chunked回复
GOP缓存 ×
虚拟主机 ×
省略 listen 配置 见备注 配置中必须有一个 listen
纯音频支持 见备注 wait_videowait_key 开启后无法工作
reuseport 支持 ×
定时打印访问记录 ×
JSON风格的stat ×
stat中包含录制详情 ×

1.2 环境搭建

在Ubuntu下搭建相应的环境

1.2.1 下载依赖库

shell 复制代码
sudo apt-get update
#安装依赖:gcc、g++依赖库
sudo apt-get install build-essential libtool
#安装 pcre依赖库(http://www.pcre.org/)
sudo apt-get install libpcre3 libpcre3-dev
#安装 zlib依赖库(http://www.zlib.net)
sudo apt-get install zlib1g-dev
#安装ssl依赖库
sudo apt-get install openssl

1.2.2 安装nginx-http-flv-module

shell 复制代码
git clone https://github.com/winshining/nginx-http-flv-module.git

1.2.3 安装ffmpeg

这里不介绍,详细可以看我的博客:

1.2.4 安装nginx

shell 复制代码
wget http://nginx.org/download/nginx-1.19.2.tar.gz
tar xvzf nginx-1.19.2.tar.gz
cd nginx-1.19.2/
./configure --prefix=/usr/local/rtmp-nginx --with-http_ssl_module --add-module=~/nginx-rtmp-master/nginx-http-flv
module

注意这里的--add-module=~/nginx-rtmp/nginx-http-flv路径为对应的开源项目的路径,如果路径不对,有如下报错信息:

配置成功的话,是如下的信息

开始编译

shell 复制代码
make -j8

我这里编译错误了,看了一下编译错误日志,提示我的openssl的版本比较高,有部分函数被弃用了,那么我这里就是使用--with-cc-opt='-Wno-error -Wno-deprecated-declarations'忽略这个报错

shell 复制代码
src/event/ngx_event_openssl.c: In function 'ngx_ssl_load_certificate_key':
src/event/ngx_event_openssl.c:729:9: error: 'ENGINE_by_id' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
  729 |         engine = ENGINE_by_id((char *) p);
      |         ^~~~~~
In file included from src/event/ngx_event_openssl.h:22,
                 from src/core/ngx_core.h:84,
                 from src/event/ngx_event_openssl.c:9:
/usr/include/openssl/engine.h:336:31: note: declared here
  336 | OSSL_DEPRECATEDIN_3_0 ENGINE *ENGINE_by_id(const char *id);
      |                               ^~~~~~~~~~~~
src/event/ngx_event_openssl.c:738:9: error: 'ENGINE_load_private_key' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
  738 |         pkey = ENGINE_load_private_key(engine, (char *) last, 0, 0);
      |         ^~~~
In file included from src/event/ngx_event_openssl.h:22,
                 from src/core/ngx_core.h:84,
                 from src/event/ngx_event_openssl.c:9:
/usr/include/openssl/engine.h:638:11: note: declared here
  638 | EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
      |           ^~~~~~~~~~~~~~~~~~~~~~~
src/event/ngx_event_openssl.c:742:13: error: 'ENGINE_free' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
  742 |             ENGINE_free(engine);
      |             ^~~~~~~~~~~
In file included from src/event/ngx_event_openssl.h:22,
                 from src/core/ngx_core.h:84,
                 from src/event/ngx_event_openssl.c:9:
/usr/include/openssl/engine.h:493:27: note: declared here
  493 | OSSL_DEPRECATEDIN_3_0 int ENGINE_free(ENGINE *e);
      |                           ^~~~~~~~~~~
src/event/ngx_event_openssl.c:746:9: error: 'ENGINE_free' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
  746 |         ENGINE_free(engine);
      |         ^~~~~~~~~~~
In file included from src/event/ngx_event_openssl.h:22,
                 from src/core/ngx_core.h:84,
                 from src/event/ngx_event_openssl.c:9:
/usr/include/openssl/engine.h:493:27: note: declared here
  493 | OSSL_DEPRECATEDIN_3_0 int ENGINE_free(ENGINE *e);
      |                           ^~~~~~~~~~~
src/event/ngx_event_openssl.c: In function 'ngx_ssl_dhparam':
src/event/ngx_event_openssl.c:1345:5: error: 'PEM_read_bio_DHparams' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
 1345 |     dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
      |     ^~
In file included from /usr/include/openssl/ssl.h:36,
                 from src/event/ngx_event_openssl.h:15,
                 from src/core/ngx_core.h:84,
                 from src/event/ngx_event_openssl.c:9:
/usr/include/openssl/pem.h:469:1: note: declared here
  469 | DECLARE_PEM_rw_attr(OSSL_DEPRECATEDIN_3_0, DHparams, DH)
      | ^~~~~~~~~~~~~~~~~~~
src/event/ngx_event_openssl.c:1355:5: error: 'DH_free' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
 1355 |     DH_free(dh);
      |     ^~~~~~~
In file included from /usr/include/openssl/dsa.h:51,
                 from /usr/include/openssl/x509.h:37,
                 from /usr/include/openssl/ssl.h:31,
                 from src/event/ngx_event_openssl.h:15,
                 from src/core/ngx_core.h:84,
                 from src/event/ngx_event_openssl.c:9:
/usr/include/openssl/dh.h:204:28: note: declared here
  204 | OSSL_DEPRECATEDIN_3_0 void DH_free(DH *dh);
      |                            ^~~~~~~
src/event/ngx_event_openssl.c: In function 'ngx_ssl_error':
src/event/ngx_event_openssl.c:3100:13: error: 'ERR_peek_error_line_data' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
 3100 |             n = ERR_peek_error_line_data(NULL, NULL, &data, &flags);
      |             ^
In file included from src/event/ngx_event_openssl.h:16,
                 from src/core/ngx_core.h:84,
                 from src/event/ngx_event_openssl.c:9:
/usr/include/openssl/err.h:425:15: note: declared here
  425 | unsigned long ERR_peek_error_line_data(const char **file, int *line,
      |               ^~~~~~~~~~~~~~~~~~~~~~~~
src/event/ngx_event_openssl.c: In function 'ngx_ssl_session_ticket_key_callback':
src/event/ngx_event_openssl.c:4010:9: error: 'HMAC_Init_ex' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
 4010 |         if (HMAC_Init_ex(hctx, key[0].hmac_key, size, digest, NULL) != 1) {
      |         ^~
In file included from /usr/include/openssl/ssl.h:37,
                 from src/event/ngx_event_openssl.h:15,
                 from src/core/ngx_core.h:84,
                 from src/event/ngx_event_openssl.c:9:
/usr/include/openssl/hmac.h:43:27: note: declared here
   43 | OSSL_DEPRECATEDIN_3_0 int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
      |                           ^~~~~~~~~~~~
src/event/ngx_event_openssl.c:4054:9: error: 'HMAC_Init_ex' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
 4054 |         if (HMAC_Init_ex(hctx, key[i].hmac_key, size, digest, NULL) != 1) {
      |         ^~
In file included from /usr/include/openssl/ssl.h:37,
                 from src/event/ngx_event_openssl.h:15,
                 from src/core/ngx_core.h:84,
                 from src/event/ngx_event_openssl.c:9:
/usr/include/openssl/hmac.h:43:27: note: declared here
   43 | OSSL_DEPRECATEDIN_3_0 int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
      |                           ^~~~~~~~~~~~
src/event/ngx_event_openssl.c: In function 'ngx_openssl_engine':
src/event/ngx_event_openssl.c:5188:5: error: 'ENGINE_by_id' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
 5188 |     engine = ENGINE_by_id((char *) value[1].data);
      |     ^~~~~~
In file included from src/event/ngx_event_openssl.h:22,
                 from src/core/ngx_core.h:84,
                 from src/event/ngx_event_openssl.c:9:
/usr/include/openssl/engine.h:336:31: note: declared here
  336 | OSSL_DEPRECATEDIN_3_0 ENGINE *ENGINE_by_id(const char *id);
      |                               ^~~~~~~~~~~~
src/event/ngx_event_openssl.c:5196:5: error: 'ENGINE_set_default' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
 5196 |     if (ENGINE_set_default(engine, ENGINE_METHOD_ALL) == 0) {
      |     ^~
In file included from src/event/ngx_event_openssl.h:22,
                 from src/core/ngx_core.h:84,
                 from src/event/ngx_event_openssl.c:9:
/usr/include/openssl/engine.h:708:27: note: declared here
  708 | OSSL_DEPRECATEDIN_3_0 int ENGINE_set_default(ENGINE *e, unsigned int flags);
      |                           ^~~~~~~~~~~~~~~~~~
src/event/ngx_event_openssl.c:5201:9: error: 'ENGINE_free' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
 5201 |         ENGINE_free(engine);
      |         ^~~~~~~~~~~
In file included from src/event/ngx_event_openssl.h:22,
                 from src/core/ngx_core.h:84,
                 from src/event/ngx_event_openssl.c:9:
/usr/include/openssl/engine.h:493:27: note: declared here
  493 | OSSL_DEPRECATEDIN_3_0 int ENGINE_free(ENGINE *e);
      |                           ^~~~~~~~~~~
src/event/ngx_event_openssl.c:5206:5: error: 'ENGINE_free' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
 5206 |     ENGINE_free(engine);
      |     ^~~~~~~~~~~
In file included from src/event/ngx_event_openssl.h:22,
                 from src/core/ngx_core.h:84,
                 from src/event/ngx_event_openssl.c:9:
/usr/include/openssl/engine.h:493:27: note: declared here
  493 | OSSL_DEPRECATEDIN_3_0 int ENGINE_free(ENGINE *e);
      |                           ^~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [objs/Makefile:926:objs/src/event/ngx_event_openssl.o] 错误 1
make[1]: 离开目录"/home/liuhang/nginx-rtmp/nginx-1.19.2"
make: *** [Makefile:8:build] 错误 2

删除编译信息

shell 复制代码
make clean

重新配置

shell 复制代码
./configure --prefix=/usr/local/rtmp-nginx  --add-module=/home/liuhang/nginx-rtmp/nginx-http-flv-module-master --with-cc-opt='-Wno-error -Wno-deprecated-declarations'

再次编译

shell 复制代码
make -j8

此时编译成功了,我们把nginx安装到刚才我们设置的prefix路径下

shell 复制代码
sudo make install

1.2.5 配置nginx

进入对应的路径,可以看到rtmp-nginx文件夹已经存在了

进入到配置信息路径,打开nginx.conf配置文件

shell 复制代码
cd /usr/local/rtmp-nginx/conf
sudo gedit nginx.conf

添加如下的配置信息,在HLS转码的时候,需要使用到ffmpeg,这里需要配置ffmpeg的路径,并且需要配置ffmpeg的动态库

shell 复制代码
daemon off;
# 如果开启off对应的ts⽂件不并删除
# master_process off;
user root;

error_log /tmp/error.log debug;
events{
    worker_connections 1024;
}

rtmp{
    server {
        listen 1935;
        chunk_size 4000;

        #live
        application live {
            live on;

            exec /usr/local/bin/ffmpeg -i rtmp://localhost/live/$name \
                  -c:a copy -c:v libx264 -b:v 300K -g 30 -f flv rtmp://localhost/hls/$name_hi \
                  -c:a copy -c:v libx264 -b:v 200K -g 30 -s 462x254 -f flv rtmp://localhost/hls/$name_mid \
                  -c:a copy -c:v libx264 -b:v 100K -g 30 -s 230x128 -f flv rtmp://localhost/hls/$name_low;
        }

        application hls {
            live on;
            hls on;
            hls_path /tmp/hls;
            hls_nested on;
            hls_fragment 2s;
            hls_playlist_length 6s;

            hls_variant _hi BANDWIDTH=350000;
            hls_variant _mid BANDWIDTH=250000;
            hls_variant _low BANDWIDTH=150000;
        }
    }
}

#HTTP
http{
    server {
        listen 8081;

        #welcome
        location / {
            root html;
            index index.html index.htm;
        }

        #hls
        location /hls {
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            #root /tmp;
            alias /tmp/hls;
            add_header Cache-Control no-cache;
        }
    }
}

1.2.6 测试nginx服务

启动nginx服务

shell 复制代码
sudo ./sbin/nginx -c conf/nginx.conf

这里我们使用浏览器访问对应的服务,可以看到确实是跑起来了

推流测试

shell 复制代码
ffmpeg -re -i .\2.mp4 -codec:v h264 -codec:a aac -f flv rtmp://192.168.217.128/live/livestream

RTMP拉流测试

shell 复制代码
ffplay -i rtmp://192.168.217.128/live/livestream

以上都没有问题,可以看到推流和拉流RTMP都正常

HLS拉流测试

shell 复制代码
ffplay -i http://192.168.217.128:8081/hls/livestream.m3u8

这里HTTP返回404,但是我们确实推流上去了,我们进入到对应的HLS切片目录看看

这里权限不够,修改到最大权限

shell 复制代码
sudo chmod 777 hls

输入ls发现什么都没有产生,因此返回了404

结果我的反复查看错误日志,发现是ffmpeg进程没有跑起来,检查发现,我只添加了~/.bashrc的库文件路径,但是nginx跑起来不是基于bash的,因此找不到对应的动态库

使用如下命令也可以看出来,输出都是not found

shell 复制代码
sudo -u root ldd /usr/local/bin/ffmpeg

将对应的动态库添加到etc/ld.so.conf.d/ffmpeg.conf

shell 复制代码
echo "/home/liuhang/ffmpeg6.0/ffmpeg-master-latest-linux64-gpl-shared/lib" | sudo tee /etc/ld.so.conf.d/ffmpeg.conf

刷新一下,再次查看

shell 复制代码
sudo ldconfig
sudo -u root ldd /usr/local/bin/ffmpeg

现在已经可以正确找到动态库了

再次推流,已经可以在/tmp/hls目录下生成对应的.m3u8ts切片了,并且分了多个码率的流,这些都是使用ffmpeg转码的

拉流端ffplay也可以正常拉流HLS了

可以进入到llivestream_hi/目录下拉取高清的流

shell 复制代码
ffplay -i http://192.168.217.128:8081/hls/livestream_hi/index.m3u8

同样的,使用vlc拉流也是没问题的

更多资料:https://github.com/0voice

相关推荐
却道天凉_好个秋1 小时前
音视频学习(三十八):像素与位深
音视频·像素·位深
菜包eo1 小时前
教育行业可以采用Html5全链路对视频进行加密?有什么优势?
前端·音视频·html5
k09331 小时前
vue2中使用xgplayer播放流视频
音视频
慢行的骑兵4 小时前
Android音视频探索之旅 | C++层使用OpenGL ES实现视频渲染
android·音视频·ndk
DogDaoDao6 小时前
Windows下VScode配置FFmpeg开发环境保姆级教程
windows·vscode·ffmpeg·音视频·gcc
菜包eo20 小时前
如何使用数字化动态水印对教育视频进行加密?
音视频·同态加密
ViiTor_AI21 小时前
语音对话秒译 + 视频悬浮字 + 相机即拍即译:ViiTor 如何破局跨语言场景?
音视频·机器翻译·视频翻译工具
安特尼1 天前
Datawhale AI夏令营:基于带货视频评论的用户洞察挑战赛
机器学习·语言模型·音视频
嘉恩督1 天前
视频人脸处理——人脸面部动作提取
python·音视频