什么是流媒体服务器

流媒体服务器(Streaming Media Server)是一种用于存储和传输音频、视频、直播等媒体内容的服务器软件。它通过网络将媒体文件实时传输给用户,而不需要用户先下载完整文件。流媒体服务器支持按需播放、实时广播等功能,常见的使用场景包括在线视频、音频点播、直播视频等。

视频流媒体数据传输往往对流媒体服务器编解码能力和协议转换有要求,因为不同的编码格式和不同的协议适用的场景不同。例如,RTMP协议延迟低,但是web浏览器不支持,需要将其转为HLS或者是FLV才能进行播放。

Nginx如何实现流媒体服务器

Nginx作为web服务器的一种,本身关注点在静态资源代理、正反向代理方面,实现作为流媒体服务器使用是依赖“插件”来扩展。例如:nginx-rtmp-module插件和nginx-http-flv-module插件。

为Nginx安装nginx-http-flv-module

概述

nginx中的模块虽然就是类似插件的概念,但是它无法像VsCode那样轻松的安装扩展。针对像 nginx-http-flv-module 这样的 nginx 模块,仅能通过重新编译 nginx 源码的方式完成“插件的安装”。

nginx-http-flv-module 基于 nginx-rtmp-module 二次开发,拥有 nginx-rtmp-module 全部的功能,同时具备HTTP-FLV播放,这个功能就很Nice,有了这个就可以实现在浏览器中观看直播,针对推送端无需额外的配置,一个直播流推送到流媒体服务器,直接可以输出多种流,包括:rtmp、hls、flv,rtmp用于在桌面应用程序中播放,hls和flv用于在浏览器中播放,当然hls也可以在桌面应用程序中播放,在浏览器播放方式中flv的画面延迟明显由于hls。

需要注意的是 nginx-http-flv-module 要求nginx的版本大于等于1.2.6。由于nginx-http-flv-module包含了 nginx-rtmp-module 模块,所以不可将 nginx-http-flv-module 和 nginx-rtmp-module 同时编译,当我们编译完 nginx-http-flv-module 之后,其实就已经拥有了 nginx-rtmp-module 的完整功能。

流程

  • 查看当前nginx 的版本(假设安装位置为:/usr/local/nginx)
  • 下载当前版本nginx的源代码
  • 下载 nginx-http-flv-module 模块源代码
  • 重新编译nginx并追加nginx-http-flv-module
  • 将新编译好的 nginx 可执行文件拷贝到当前nginx安装目录(/usr/local/nginx/sbin)

操作步骤

使用如下命令查看当前已经安装的nginx的版本


[root@bogon sbin]# ./nginx -V nginx version: nginx/1.18.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) built with OpenSSL 1.0.2k-fips 26 Jan 2017 TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --with-http_dav_module --with-http_stub_status_module --with-http_addition_module --with-http_sub_module --with-http_flv_module --with-http_mp4_module --with-pcre --with-http_ssl_module --with-http_gzip_static_module
  • V:小v仅打印版本号,大V既打印版本号,也打印扩展信息,这里要使用大V

  • 拿到版本号的目的是待会要下载该版本的源代码

  • 注意保存打印内容中的 arguments 后面的内容,后面编译会用到

下载 nginx 源码和 nginx-http-flv-module 的源码,示例代码如下:


wget http://nginx.org/download/nginx-1.18.0.tar.gz tar -zxvf nginx-1.18.0.tar.gz git clone https://github.com/winshining/nginx-http-flv-module.git

进入nginx源码目录,使用如下命令重新编译nginx:


./configure --prefix=/usr/local/nginx --with-http_dav_module --with-http_stub_status_module --with-http_addition_module --with-http_sub_module --with-http_flv_module --with-http_mp4_module --with-pcre --with-http_ssl_module --with-http_gzip_static_module --add-module=/home/cml/nginx-http-flv-module make
  • 使用configure 配置编译环境
  • 将上面 保存的“arguments 后面的内容”作为configure 的第一个参数
  • 第二个参数为 --add-module=/home/cml/nginx-http-flv-module ,即添加一个模块,模块源代码位置是 /home/cml/nginx-http-flv-module
  • 使用make命令执行编译编译

编译成功后,在 objs中会有一个 名为nginx的可执行文件,这个就是编译好的nginx了, 里面包含已经安装的功能和新增加的nginx-rtmp-module,将这个可执行文件拷贝到当前安装目录(/usr/local/nginx/sbin)中就可以了。

注意拷贝之前需要停止nginx,否则会报当前文件繁忙,无法覆盖的错误。

通过如下命令验证安装是否正常:


nginx -V

若打印的信息中包含nginx-http-flv-module,说明安装好了。

配置流媒体服务器

当安装好了 nginx-http-flv-module 之后,就可以创建流媒体应用了。所谓的创建流媒体应用其实就是编写 nginx 的配置文件,如果需要创建一个名为 live 的流媒体应用,那么可以在 nginx.conf 中做如下配置



#以下内容放可在 nginx.conf 的最后,rtmp 配置块为顶级配置块
rtmp_auto_push on ; rtmp {
server {
listen 1935; #监听的端口
notify_method get;
chunk_size 4000;
application live { #rtmp推流请求路径
live on;
# 添加 hls 支持
hls on;
hls_path /usr/local/nginx/html/hls;
hls_fragment 3;
hls_playlist_length 60; # 允许从任何源push 流
allow publish all ;
# 允许从任何地方来播放流
allow play all;
# 20s内没有push,就断开连接
drop_idle_publisher 20s ;
}
}
}
  • listen 1935:指定流媒体服务器的运行端口
  • live :为流媒体应用的应用的名称,也即流媒体应用的唯一标识
  • live on : 添加直播的支持
  • hls_path:指定生成的m3u8文件的位置

之后就是创建http-flv端点和hls端点了,目的是让直播流可以在http协议上面传输直播画面。

若不创建,将仅可以使用rtmp协议拉流,即rtmp://ip:1935/live/stream_no;若创建了就可以使用hls或者flvjs来拉流播放了。

创建http-flv端点和hls端点同样是编辑nginx.conf来实现,如下示例配置:



 server {
listen 82;
server_name rtmpserver; # 创建hls端点
location /hls {
add_header 'Access-Control-Allow-Origin' '*' ;
add_header 'Access-Control-Allow-Credentials' 'true' ;
types {
application/vnd.apple.mpegurl m3u8 ;
video/mp2t ts;
}
alias /usr/local/nginx/html/hls;
expires -1 ;
add_header 'Cache-Control' 'no-cache';
} # 创建 flv 端点
location /flv {
flv_live on ;
chunked_transfer_encoding on;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
}
}
  • listen 82 :指定 hls端点和flv端点的监听端口,此端口可以自定义,针对hls端点和flv端点可以分开设置不同的监听端口
  • hls端点的标识为 hls,此标识可以自定义,拉流的时候会用到
  • alias:指定m3u8文件的访问路径,需要和 "创建流媒体应用"中的hls_path配置保持一致
  • flv端点的标识为flv,此标识可以自定义,拉流的时候会用到

使用OBS推流

OBS 是非常成熟的软件了,安装参考官网:https://obsproject.com/

假设约定的推拉流地址为 rtmp://192.168.1.115:1935/live/room-1

设置直播流来源为 视频采集设备 和 浏览器,其中视频采集设备就是笔记本的摄像头,浏览器为OBS内置浏览器并打开 https://time.is/zh/ 这个网址。最终的直播画面就是两个采集终端的画面叠加在一起,底部是一个网址,网页中有一个时钟,顶部是摄像头。

设置直播服务器和推流码:

  • 服务器:即流媒体应用的地址,即 rtmp://192.168.1.115:1935/live
  • 推流码:即当前推流唯一标识,可以随意指定,保证推拉流地址一致即可,示例为: room-1

点击开始直播,OBS就开始向流媒体服务器推流了。

此时就可以使用拉流客户端拉取直播画面了,同时hls_path 下将生成m3u8文件,文件名称为 room-1.m3u8。

使用VLC拉RTMP

VLC是非常成熟的软件了,安装参考官网。

VLC拉流使用rtmp进行,拉流地址为:


rtmp://192.168.1.115:1935/live/room-1

使用flv.js拉流

基于flv.js编写一个视频播放器,新建一个html文件,示例代码如下:

flvjs_player.html


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>FLV.js Example</title>
    <script src="https://cdn.jsdelivr.net/npm/flv.js@1.5.0/dist/flv.min.js"></script>
</head>
<body>
    <h1>FLV.js Player</h1>
    <video id="videoElement" width="640" height="360" controls></video>
    <button id="playButton">Click to Play Video</button>
    <script>
        // Check if the browser supports FLV.js
        if (flvjs.isSupported()) {
            var videoElement = document.getElementById('videoElement');
            var flvPlayer = flvjs.createPlayer({
                type: 'flv',
                url: 'http://192.168.1.115:82/flv?port=1935&app=live&stream=room-1'  // Replace with your FLV video URL
            });
            flvPlayer.attachMediaElement(videoElement);
            flvPlayer.load();
            // Play video on button click
            document.getElementById('playButton').addEventListener('click', function() {
                flvPlayer.play().catch(function(error) {
                    console.error('Error playing video:', error);
                });
            });
        } else {
            console.error('FLV.js is not supported in this browser.');
        }
    </script>
</body>
</html>

使用jls.js拉m3u8

基于hls.js编写一个视频播放器,新建一个html文件,示例代码如下:

m3u8_play.html


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HLS.js Example</title>
    <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</head>
<body>
    <h1>HLS.js Player</h1>
    <video id="videoElement" width="640" height="360" controls></video>
    <script>
        var video = document.getElementById('videoElement');
       
        // 检查浏览器是否支持 HLS.js
        if (Hls.isSupported()) {
            var hls = new Hls();
            // 加载并播放 .m3u8 文件
            hls.loadSource('http://192.168.1.115:82/hls/room-1.m3u8');  // 替换为你的 .m3u8 URL
            hls.attachMedia(video);
           
            hls.on(Hls.Events.MANIFEST_PARSED, function() {
                video.play();  // 加载后自动播放
            });
            hls.on(Hls.Events.ERROR, function(event, data) {
                if (data.fatal) {
                    switch (data.fatal) {
                        case Hls.ErrorTypes.NETWORK_ERROR:
                            console.error("网络错误");
                            break;
                        case Hls.ErrorTypes.MEDIA_ERROR:
                            console.error("媒体错误");
                            break;
                        case Hls.ErrorTypes.OTHER_ERROR:
                            console.error("其他错误");
                            break;
                        default:
                            console.error("无法播放视频");
                            break;
                    }
                }
            });
        } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
            // 如果浏览器原生支持 HLS(例如 Safari),直接播放
            video.src = 'http://192.168.1.92:82/hls/room-1.m3u8';
            video.play();
        } else {
            console.error('HLS.js 不支持此浏览器');
        }
    </script>
</body>
</html>

总结

本文介绍了流媒体服务器的特性及各种流媒体传输协议的适用场景,并详细阐述了使用 nginx-http-flv-module 扩展Nginx作为流媒体服务器的详细步骤,并提供了在VLC,flv.js,hls.js下的流媒体拉流播放示例。

引用

https://www.cnblogs.com/Naylor/p/18427309

https://www.cnblogs.com/Naylor/p/18070157

https://www.cnblogs.com/Naylor/p/18070047

使用Nginx搭建流媒体服务器的更多相关文章

  1. nginx搭建流媒体服务器的方法详解

      一.FLV视频发布方式简介 FLV视频有两总发布方式 1.  HTTP方式 这种方式要下载FLV视频文件到本地播放,一旦FLV视频文件下载完成,就不会消耗服务器的资源和带宽,但是拖动功能没有RTM ...

  2. 【Nginx】如何使用Nginx搭建流媒体服务器实现直播?看完这篇我会了!!

    写在前面 最近几年,直播行业比较火,无论是传统行业的直播,还是购物.游戏.教育,都在涉及直播.作为在互联网行业奋斗了多年的小伙伴,你有没有想过如果使用Nginx搭建一套直播环境,那我们该如何搭建呢?别 ...

  3. ubuntu下使用nginx搭建流媒体服务器,实现视频点播

    首先我们看如何实现视频点播,视频点播支持flv文件及H264编码视频,ACC编码音频的mp4文件: 第一步,创建单独的目录(因为软件较多,容易混乱),下载需要的软件: 我们需要下载nginx,pcre ...

  4. centos 7下nginx搭建流媒体服务器【动态添加模块】

    1.安装nginx依赖包 yum install gcc gcc-c++ openssl-devel zlib-devel pcre pcre-devel yamdi 2.下载解压nginx_mod_ ...

  5. nginx搭建流媒体服务器

    1.安装PCRE库 到www.pcre.org 下载pcre-8.37.tar.gz tar -zxvf pcre-8.37.tar.gz cd pcre-8.37 ./configure make ...

  6. Ubuntu下使用nginx和nginx-rtmp-module搭建流媒体服务器的正确姿势

    之前在使用nginx和nginx-rtmp-module搭建流媒体服务器的时候遇到一个很尴尬的问题,就是在把nginx-rtmp-module模块添加到nginx中去的时候,我最开始采取的做法是先卸载 ...

  7. nginx + rtmp 搭建流媒体服务器

    一.安装nginx服务器 1.路径说明: 路径:/usr/local/src 2.下载nginx-rtmp-module (我这里的目录是在/usr/local/src/下面) cd /usr/loc ...

  8. centos7+nginx+rtmp+ffmpeg搭建流媒体服务器(保存流目录与http目录不要随意配置,否则有权限问题)

    搭建nginx-http-flv-module升级代替rtmp模块,详情:https://github.com/winshining/nginx-http-flv-module/blob/master ...

  9. 使用nginx+nginx-rtmp-module+ffmpeg搭建流媒体服务器

    参考: 1,使用nginx+nginx-rtmp-module+ffmpeg搭建流媒体服务器笔记(一)http://blog.csdn.net/xdwyyan/article/details/4319 ...

  10. nginx的rtmp搭建流媒体服务器实现直播流

    最近自己搞了一个用nginx的rtmp来搭建流媒体服务器,从而实现直播的过程,参考了网上很多资料,有些资料对于初学者来说比较难以理解,在此将我搭建的过程记录下来,分享给大家. 1.下载nginx-rt ...

随机推荐

  1. CSS – vw, vh, position fixed and ICB (initial containing block)

    什么是 vw, vh? vh 的 v 指的是 viewport, h 就是 height. 它是 CSS 值的单位就像 px, %. .container { height: 30vh; backgr ...

  2. ASP.NET Core Library – ImageSharp

    前言 2021 年就写过一篇了, Asp.net core 学习笔记 Image processing (ImageSharp), 只是那时还是旧的写法, 这篇作为翻新和以后继续增加新功能的介绍. I ...

  3. EF Core – Custom Migrations (高级篇)

    前言 会写这篇是因为最近开始大量使用 SQL Server Trigger 来维护冗余 (也不清楚这路对不对). EF Core migrations 没有支持 Trigger Github Issu ...

  4. VMware Vsphere 8.0 ESXI 主机部署

    一. VMware vSphere 8.0新特性 VMware vSphere 8.0是一个全新的版本,引入了许多新功能,其中最主要的新功能包括 1.集中式云控制台 使 IT 管理员能够借助 vSph ...

  5. 在 macOS上安装 MongoDB 社区版

    官网教程 https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x/ 使用第三方 brew package manager 在 ...

  6. 使用nnUNet跑BraTS脑肿瘤分割预测TC和ET非常低的原因。

    使用nnUNet跑BraTS脑肿瘤分割预测TC和ET非常低,原来是预测的时候,使用了预处理后的标签.原本标签是:2:WT, 1:TC, 4:ET.但是预处理之后变为:1:WT, 2:TC, 3:ET. ...

  7. 在 Vue 实例中编写生命周期hook 或者其它 option/propertie 时,为什么不适用箭头函数 ?

    首先,箭头函数没有自己的 this 环境变量 会沿用作用域使用父级this : 由Vue 管理的函数 ,如果写成箭头函数 this 就不在是 Vue 实例 了 :

  8. 60 .vue的生命周期和小程序的生命周期区别

    https://blog.csdn.net/weixin_43359799/article/details/123137288

  9. Blazor 调用 Clipboard API 读写剪贴板数据

    目录 简介 使用JS互操作 使用ClipLazor库 创建项目 使用方法 简单测试 参考链接 简介 Clipboard API 是一种允许网页读取剪贴板数据或向其中写入数据的API,主要有两个方法: ...

  10. 在 Kubernetes 中部署并使用 KubeEdge

    作者:马伟,青云科技容器顾问,云原生爱好者,目前专注于云原生技术,云原生领域技术栈涉及 Kubernetes.KubeSphere.KubeKey 等. 边缘计算在广泛制造业.工业.零售和金融等行业, ...