【rtmp】搭建流媒体服务器+obs推流直播

本文采用nginx+rtmp方式搭建流媒体服务器,使用obs推流,rtmp+flv拉流的方式实现

服务端配置

nginx+nginx-http-flv-module介绍

nginx-http-flv-module介绍

nginx-http-flv-module是在nginx-rtmp-module基础上开发的一个直播模块。
感谢Arut创造了nginx-rtmp-module,它是Nginx的一个优秀的第三方模块,可以用来直播,支持RTMP,HLS和DASH方式直播,还支持调用第三方软件进行转码,录制视频等功能,由于依托Nginx,性能也比较高。但是美中不足的地方也不少,例如首屏时间长,不支持HTTP-FLV方式直播,不支持虚拟主机(vhost)功能,省略listen配置无法接受连接,有很多很明显的bug等问题。
nginx-http-flv-module解决了上述的问题。

为什么选择Nginx作为支持HTTP-FLV方式直播的服务器呢?

因为Nginx的Web服务器功能对HTTP协议的支持非常完善,Nginx的性能优秀,经过了很多场景的检验。另外,Nginx本身对第三方软件的依赖较少,非常易于部署。这些都使得它成为HTTP-FLV方式直播服务器不可多得的选择。

nginx-http-flv-module功能

  • 兼容nginx-rtmp-module所有功能,基于nginx-rtmp-module的流媒体服务器。
  • 支持HTTP-FLV方式的直播
  • 支持GOP缓存,以减少首屏时间
  • 支持虚拟主机功能
  • 可以省略listen配置项而不影响基本功能
  • 修复nginx-rtmp-module已知的bug

nginx-http-flv-module 安装配置

  1. 下载nginx包
    下载地址:https://nginx.org/download/nginx-1.14.2.tar.gz
  2. 下载nginx-http-flv-module 模块包
    下载地址:https://github.com/winshining/nginx-http-flv-module

与nginx-rtmp-module功能对比

功能 nginx-http-flv-module nginx-rtmp-module 备注
HTTP-FLV (播放) x 支持HTTPS-FLV和chunked回复
GOP缓存 x
虚拟主机 x
省略listen配置 见备注 配置中必须有一个listen
纯音频支持 见备注 wait_videowait_key开启后无法工作
定时打印访问记录 x
JSON风格的stat x
  • NGINX的版本应该大于1.2.6,与其他版本的兼容性未知。
  • Linux(推荐)/FreeBSD/MacOS/Windows(受限)
  • 支持的播放器 VLC (RTMP & HTTP-FLV)/OBS (RTMP & HTTP-FLV)/JW Player (RTMP)/flv.js (HTTP-FLV).
  • flv.js只能运行在支持Media Source Extensions的浏览器上

nginx+nginx-http-flv-module安装

安装依赖项

yum -y install unzip
yum -y install gcc-c++ 
yum -y install pcre pcre-devel  
yum -y install zlib zlib-devel 
yum -y install openssl openssl-devel

将nginx-http-flv-module.zip 解压到/usr/local/nginx下面

unzip nginx-http-flv-module-1.2.6.zip //解压文件
//解压文件复制到/usr/local/nginx 目录下
cp /opt/toos/nginx-http-flv-module-1.2.6.zip  /usr/local/nginx/nginx-http-flv-module

将nginx-http-flv-module模板添加到nginx中,生成make文件 并安装nginx

/opt/tools
tar -zxvf nginx-1.18.1.tar.gz
cd nginx-1.18.1
./configure --prefix=/usr/local/nginx  --add-module=/usr/local/nginx/nginx-http-flv-module
make && make install

修改配置文件

cd /usr/local/nginx/conf
vim nginx.conf
-------------------------------------------------------------------------------
worker_processes  10;

error_log logs/error.log error;

#如果此模块被编译为动态模块并且要使用与RTMP相关的功
#能时,必须指定下面的配置项并且它必须位于events配置
#项之前,否则NGINX启动时不会加载此模块或者加载失败

#load_module modules/ngx_http_flv_live_module.so;

events {
    worker_connections  10240;  #Nginx处理的最大连接数
}

#因为Nginx可能开启多个子进程,这个选项表示推流时,媒体流会发布到多个子进程
rtmp_auto_push on;
rtmp_auto_push_reconnect 1s;
#多个子进程情况下,推流时,最开始只有一个子进程在竞争中接收到数据,然后它再relay给其他子进程,他们之间通过unix domain socket传输数据,这个选项表示unix domain socket的路径
rtmp_socket_dir /tmp;
rtmp{
    out_queue 4096;
    out_cork 8;
    max_streams 128;
    timeout 15s;
    drop_idle_publisher 15s;
    log_interval 5s; #log模块在access.log中记录日志的间隔时间,对调试非常有用
        log_size     1m; #log模块用来记录日志的缓冲区大小
    server{
     listen 1935;
     # server_name www.test.*; #用于虚拟主机名后缀通配
     application live{
         live on;
                 record off;
         gop_cache on;  #打开GOP缓存,减少首屏等待时间
                 #notify_method get;
                 #publish_notify on;
                 #on_publish http://192.168.0.103:8087/autho/rtmp; #这里进行权限控制
                 #on_publish_done http://127.0.0.1:8087/autho/rtmpOver;#直播结束回调
                 #pull rtmp://live.hkstv.hk.lxdns.com/live/hks; #如果懒得推流,那可以用这个,香港卫视的直播推流
      }
     application hls{
      live on;
      hls on;
      hls_path /home/soap/rtmp/hls;#视频流存放地址
          hls_fragment 5s;
          hls_playlist_length 15s;
          hls_continuous on; #连续模式。
          hls_cleanup on;    #对多余的切片进行删除。
          hls_nested on;     #嵌套模式。
    }
     application dash{
       live on;
       dash on;
       dash_path /usr/local/nginx/html/dash;
     }
    
    }
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    add_header Access-Control-Allow-Origin $http_origin always;  # '*' 
    add_header Access-Control-Allow-Credentials true always;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS' always;
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' always;

    server {
        listen       8002;
    server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
    location /live {
            flv_live on; #打开HTTP播放FLV直播流功能
            chunked_transfer_encoding on; #支持'Transfer-Encoding: chunked'方式回复
        }

    location /hls{
        types {
        application/vnd.apple.mpegurl m3u8;
        video/mp2t ts;
         }
         root /usr/local/nginx/html/hls;
         add_header 'Cache-Control' 'no-cache';
    }
     location /dash {
            root /usr/local/nginx/html/dash;
            add_header 'Cache-Control' 'no-cache';
        }
    
     location /stat {
            #configuration of push & pull status
              rtmp_stat all;
              rtmp_stat_stylesheet stat.xsl;
         }
    location /stat.xsl {
      root /usr/local/nginx/nginx-http-flv-module;
    }

     location /control {
            rtmp_control all; #configuration of control module of rtmp
        }   
        
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

}

说明:如果采用动态编译nginx-http-flv-module模块的方式,需要将load_module “modules/ngx_http_flv_live_module.so”;前面的#去掉
rtmp测试地址: rtmp://192.168.102.222:1935/live/串流密钥
http-flv测试地址: http://192.168.102.222/live?port=1935&app=live&stream=串流密钥

视频推流

OBS推流

Open Broadcaster Software(OBS)是一个免费的开源的视频录制和视频实时流软件。
下载
obs官网

https://obsproject.com/

  1. 安装后如下:


    image.png
  2. 配置好场景来源才能显示在窗口中


    image.png

    点击新建后可以选择推流的源,可以选择摄像头或者显示器或者某个窗口

点击右下角的设置可以设置推流的流媒体地址

  1. 配置推流地址
    image.png

    如上配置地址为:rtmp://192.168.102.222:1953/live,还有一个串流密钥为xxxx,可以随便写。
    点确定后,再点开始推流即可。
  2. 添加推流token


    image.png

ffmpeg推流

ffmpeg -rtsp_transport tcp -i "rtsp://admin:123456@192.168.10.128.19:554/h264/ch1/sub/av_stream"  -vcodec copy -acodec  aac -f flv  "rtmp://192.168.55.65:1935/myapp/video19"

-g 25:每隔25帧,插入一个关键帧,可提高缓冲速度。而且延迟不会明显增加。
为了实现首屏秒开使用-g设置gop大小,同时使用-b降低网络负载,保证流畅度。

#linux
ffmpeg -r 30  -i /dev/video0 -vcodec h264 -max_delay 100 -f flv -g 5 -b 700000 rtmp://219.216.87.170/live/test1
#window
ffmpeg -r 30  -f vfwcap -i 0 -vcodec h264 -max_delay 100 -f flv -g 5 -b 700000 rtmp://219.216.87.170/live/test1
  • url根据nginx配置文件的不同,而改变。
rtmp://example.com[:port]/appname/streamname
  • 注意这里用flv.js音频配置必须是 aac 否者就会报错(除非你不加入音频)
-vcodec copy -acodec aac -f flv

注意:rtsp协议默认使用udp容易丢数据包,所以rtsp强制使用tcp方式可以一定程度避免丢包。

本地视频推流

把视频推流至rtmp://127.0.0.1:1935/live/123(127.0.0.1:1935为rtmp服务器地址、live为nginx配置节点、123当做密钥)

ffmpeg.exe -re -i demo.wmv -f flv rtmp://127.0.0.1:1935/live/123
ffmpeg -re -i test.h264 -vcodec copy -acodec copy -f flv -y rtmp://ip:port/live/test
循环多次读取文件, -1为无限循环
ffmpeg -re -stream_loop -1 -i 0-0.mp4 -vcodec copy -acodec copy -f flv -y "rtmp://192.168.102.222:1935/live/room"
-re表示重新调整时间戳,这样就能够将各种文件、RTSP源、RTMP源的不均匀时间戳全部进行ffmpeg的重新调整,再进行rtmp推流,保证直播的平滑和hls切片的均匀。
-flvflags no_duration_filesize 这个参数是关键,这个参数告诉ffmpeg不要抛出duration_filesize警告
相关参数:
-re 代表按照帧率发送,否则ffmpeg会一股脑地按最高的效率发送数据
-stream_loop -1循环次数,-1表示自动循环
-i "发送文件路径"指定要发送的源文件
-vcodec copy 表示视频解码使用原有格式,如果报错可以修改类型,如使用-vcodec h264,B站要求不超过1500
-acodec aac 表示视频解码使用AAC格式,如果报错可以修改类型,如使用-vcodec copy,未设定时则使用与输入流相同的编解码器
-b:v 1500k 指定视频码率为1500k,默认为200Kbit/s
-b:a 320k 指定音频码率为320k
-r 60 指定帧率为60帧/s,如果不写这个参数默认为25
-f flv 设定输出格式为flv
-headers "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36"

摄像头推流

摄像头名称为USB2.0 PC CAMERA,而且推流服务器ip为127.0.0.1:1935,关键字为live

ffmpeg -f dshow -i video="USB2.0 PC CAMERA" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/123

麦克风推流

ffmpeg -f dshow -i audio="麦克风 (2- USB2.0 MIC)" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/123

和前面差不多,声音被推流出去了,通过vlc拉流可以听到录制的声音,但很明显不会有画面

摄像头&麦克风推流

这次要实现同时推流摄像头画面与声音,此时我们的语句应该如下

ffmpeg -f dshow -i video="USB2.0 PC CAMERA" -f dshow -i audio="麦克风 (2- USB2.0 MIC)" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/123
或者
ffmpeg -f dshow -i video="USB2.0 PC CAMERA":audio="麦克风 (2- USB2.0 MIC)" -vcodec libx264 -r 25 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/123

画面与声音源源不断的被推流到服务器,接下来我们就应该正式的开发拉流了。

拉流

VLC

vlc官网

https://www.videolan.org/

  1. 安装后启动的样子


    image.png
  2. 点击媒体后可以选择打开网络串流


    image.png
  3. 选择网络在URL里面输入流媒体服务器的IP和串流密钥


    image.png

    点击播放按钮此时就成功了

ckplayer播放器拉流

下载
https://www.ckplayer.com/down/

下载完成后直接打开sample\rtmp.html,并把拉流地址修改为上面的地址,如下:

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <div id="video" style="width: 600px; height: 400px;"></div>
        <script type="text/javascript" src="../ckplayer/ckplayer.js"></script>
        <script type="text/javascript">
            var videoObject = {
                container: '#video', //容器的ID或className
                variable: 'player',//播放函数名称
                autoplay:false,
                live:true,
                video: 'rtmp://192.168.102.222:1935/live/room'  //room是串流密钥
            };
            var player = new ckplayer(videoObject);
        </script>
    </body>

</html>

刷新页面出现如下页面

image.png

注意:此方式只能适用于IE(not edge.)

HTTP-FLV

HTTP-FLV,即将音视频数据封装成 FLV,然后通过 HTTP 协议传输给客户端。
样例如下:

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>播放页面</title>
    </head>
    <body>
        <script src="https://cdn.bootcdn.net/ajax/libs/flv.js/1.5.0/flv.min.js"></script>
        <video style="height: 400px;width: 600px;" id="videoElement" muted autoplay controls></video>
        <script>
            var flvPlayer = null;
            if (flvjs.isSupported()) {
                var videoElement = document.getElementById('videoElement');
                flvPlayer = flvjs.createPlayer({
                    type: 'flv',
                    // 8080 对应Nginx监听的端口
                    // rtmpLive 对应Nginx的路径
                    url: 'http://192.168.102.222/live?port=1935&app=live&stream=room'
                });
                flvPlayer.attachMediaElement(videoElement);
                flvPlayer.load();
            }
        </script>
    </body>
</html>

注意:参数port对应端,app对应application, stream对应串流密钥

与vue整合
引入flv.js

import flvjs from 'flv.js/dist/flv.min.js'

html

<video class="video" #videoElement id="videoElementflv" controls muted>
  播放失败
</video>

具体js代码如下:

  /**
   * @description flv视频播放
   */
  flvVideoPlayer() {
    if (this.httpSrc && flvjs.isSupported()) {
      if (this.flvPlayer) {// 每次播放前先卸载之前组件
        this.flvPlayer.pause()
        this.flvPlayer.unload()
        this.flvPlayer.detachMediaElement()
        this.flvPlayer.destroy()
        this.flvPlayer = null
      }
      let videoElement = this.video.nativeElement
      this.flvPlayer = flvjs.createPlayer({
        type: 'flv',
        enableWorker: true, //浏览器端开启flv.js的worker,多进程运行flv.js
        isLive: true, //直播模式
        hasAudio: true, //开启音频
        hasVideo: true,
        stashInitialSize: 128,
        enableStashBuffer: false, //播放flv时,设置是否启用播放缓存,只在直播起作用。
        url: this.httpSrc,
      })
      this.flvPlayer.attachMediaElement(videoElement)
      this.flvPlayer.load()
      this.flvPlayer.play()

      this.flvPlayer.on('error', (err) => {
        console.log('err-------------------', err)
      })
    }
  }

最后

如果您已经看到这里了,希望您还是点个赞再走吧~

您的点赞是对作者的最大鼓励,也可以让更多人看到本篇文章!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容