基于 ffmpeg ,nginx-http-flv, flv.js 组合的网页直播

一. 前言

之前工作中要做网页端html5的无插件直播, 在网上找了很多资料, 最终以此套方案做了网页端无插件直播, 效果还行, 延时控制在了2秒内. 音视频编码支持情况见 flv.js.

二. 实现

FFMPEG 负责 rtmp 推流, 流数据缓存到缓冲区, ffmpeg从缓冲区拿数据解析并封装成flv格式推送到nginx

代码实现: ffmpeg 内存读取数据推流到 rtmp 服务器

nginx-http-flv demo 下载

nginx 配置文件 

worker_processes  1;

#error_log  logs/error.log;

#error_log  logs/error.log  notice;

#error_log  logs/error.log  info;

#error_log  logs/error.log  debug;

#pid        logs/nginx.pid;

events {

    worker_connections  1024;

}

# 添加RTMP服务

rtmp {

    server {

        listen 1935;

       

        #rtmp flv

        application live {  

              live on;

              #gop_cache on; #打开GOP缓存,减少首屏等待时间

        }

        #hls

        application hls {

            live on;

            hls on;  #开启hls

            hls_path hlstmp/hls;

            hls_fragment 2s; #一个ts 文件的时长 2s

        }

    }

}

http {

    include ./mime.types;

    default_type application/octet-stream;

    server {

        listen       8080;

        listen       [::]:8080 ipv6only=on; #支持ipv6

        server_name  localhost;

        location / {

            root html;

            index index.html;

        }

        location = /index.html {

            root   html;

        }

   

        location /live {

            flv_live on; #http-flv直播

            chunked_transfer_encoding  on; #open 'Transfer-Encoding: chunked' response

            add_header 'Access-Control-Allow-Credentials' 'true'; #add additional HTTP header

            add_header 'Access-Control-Allow-Origin' '*'; #add additional HTTP header

            add_header Access-Control-Allow-Headers X-Requested-With;

            add_header Access-Control-Allow-Methods GET,POST,OPTIONS;

            add_header 'Cache-Control' 'no-cache';

        }

        location /hls {

            types {

                 application/vnd.apple.mpegurl m3u8;

                 video/mp2t ts;

            }

            root hlstmp; #hls直播

           

            add_header 'Access-Control-Allow-Credentials' 'true'; #add additional HTTP header

            add_header 'Access-Control-Allow-Origin' '*'; #add additional HTTP header

            add_header Access-Control-Allow-Headers X-Requested-With;

            add_header Access-Control-Allow-Methods GET,POST,OPTIONS;

            add_header 'Cache-Control' 'no-cache';

        }

        location /stat {

            #configuration of push & pull status

            rtmp_stat all;

            rtmp_stat_format json;   #json风格, 后端可获取推流状态来进行每一路流的管理

            #rtmp_stat_stylesheet stat.xsl;

        }

       

        #location /stat.xsl {

        #    root html/nginxclient;

        #}

        location /control {

            rtmp_control all; #configuration of control module of rtmp

        }

  }

  server {

    listen  8088 ssl; #支持https直播

    listen  [::]:8088 ssl ipv6only=on; #支持ipv6

    server_name localhost;

   

    ssl_certificate  ../ssl/server.crt; #自己可用openssl生成

    ssl_certificate_key ../ssl/server.key; #自己可用openssl生成

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;

    ssl_session_timeout 5m;

    ssl_prefer_server_ciphers on;

    location / {

        root html;

        index index.html;

    }

    location = /index.html {

      root   html;

    }

    location /live {

      flv_live on;

      chunked_transfer_encoding  on; #open 'Transfer-Encoding: chunked' response

      add_header 'Access-Control-Allow-Credentials' 'true'; #add additional HTTP header

      add_header 'Access-Control-Allow-Origin' '*'; #add additional HTTP header

      add_header Access-Control-Allow-Headers X-Requested-With;

      add_header Access-Control-Allow-Methods GET,POST,OPTIONS;

      add_header 'Cache-Control' 'no-cache';

    } 

    

    location /hls {

            types {

                 application/vnd.apple.mpegurl m3u8;

                 video/mp2t ts;

            }

            root hlstmp;

           

            add_header 'Access-Control-Allow-Credentials' 'true'; #add additional HTTP header

            add_header 'Access-Control-Allow-Origin' '*'; #add additional HTTP header

            add_header Access-Control-Allow-Headers X-Requested-With;

            add_header Access-Control-Allow-Methods GET,POST,OPTIONS;

            add_header 'Cache-Control' 'no-cache';

     }

  }

}

flv.js demo, 包含延时追赶, 最大限度减小延时

<!DOCTYPE html>
<html>

<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <title>flv.js demo</title>

    <style>
        .mainContainer {
            display: block;
            width: 1024px;
            margin-left: auto;
            margin-right: auto;
        }

        .urlInput {
            display: block;
            width: 100%;
            margin-left: auto;
            margin-right: auto;
            margin-top: 8px;
            margin-bottom: 8px;
        }

        .centeredVideo {
            display: block;
            width: 100%;
            height: 576px;
            margin-left: auto;
            margin-right: auto;
            margin-bottom: auto;
        }

        .controls {
            display: block;
            width: 100%;
            text-align: left;
            margin-left: auto;
            margin-right: auto;
            margin-top: 8px;
            margin-bottom: 10px;
        }

        .logcatBox {
            border-color: #CCCCCC;
            font-size: 11px;
            font-family: Menlo, Consolas, monospace;
            display: block;
            width: 100%;
            text-align: left;
            margin-left: auto;
            margin-right: auto;
        }
    </style>
</head>

<body>

    <div class="mainContainer">
        <video name="videoElement" class="centeredVideo" id="videoElement" width="1024" height="576" controls muted autoplay>
            Your browser is too old which doesn't support HTML5 video.
        </video>
        <p></p>
        <input type="text" name="ip" value="" id="ip">
        <p></p>
		<input type="button" onclick="pullStream()" value="拉流" />
    </div>

    <script src="flv.min.js"></script>

    <script>
        var flvPlayer = null;

        function pullStream () {
            console.log("pullStream");
            var date = new Date();

            destoryVideo()

            if (flvjs.isSupported()) {
                startVideo(ip.value)
            }
        }
        
        function startVideo(pullUrl) {
            var videoElement = document.getElementById('videoElement');
            flvPlayer = flvjs.createPlayer({
                type: 'flv',
                isLive: true,
                duration: 0,
                url: pullUrl
            },
            {
            	  enableWorker: true,
                enableStashBuffer: false,
                stashInitialSize: 128,
                lazyLoad: false,
                lazyLoadMaxDuration: 0,
                lazyLoadRecoverDuration: 0,
                autoCleanupSourceBuffer: true,
                deferLoadAfterSourceOpen: false,
                fixAudioTimestampGap: false,
            }
            );
            flvPlayer.attachMediaElement(videoElement);
            flvPlayer.load();
            flvPlayer.play();


            //避免时间长时间积累缓冲导致延迟越来越高
            setInterval(function () {
                if (!videoElement.buffered.length) {
                    return;
                }
                let end = flvPlayer.buffered.end(0);
                let currentTime = videoElement.currentTime;
                //console.log("end:" + end);
                //console.log("currentTime:" + currentTime);
                let diff = end - currentTime;
                if (diff >= 1) {
                    videoElement.currentTime = parseFloat(end);
                    console.log("进行时延校正"+videoElement.currentTime);
                }
                //console.log(diff);
            }, 3 * 1000);
        }

        videoElement.addEventListener('click', function(){
            alert( '是否支持点播视频:' + flvjs.getFeatureList().mseFlvPlayback + ' 是否支持httpflv直播流:' + flvjs.getFeatureList().mseLiveFlvPlayback )
        })

        function destoryVideo() {
            if (flvPlayer != null) {
                flvPlayer.pause();
                flvPlayer.unload();
                flvPlayer.detachMediaElement();
                flvPlayer.destroy();
                flvPlayer = null;
            }            
        }

        function reloadVideo(){
            destoryVideo()
            startVideo()
        }
    </script>

</body>

</html>

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Windows下一站式搭建ffmpeg推流、nginx-http-flv-module直播拉流和flv.js播放环境可以按照以下步骤进行操作: 1. 首先,下载并安装FFmpeg。可以在官方网站(https://www.ffmpeg.org/)上找到适合你的操作系统的安装文件,然后按照指示进行安装。 2. 下载nginx服务器,并在安装目录下找到“conf/nginx.conf”文件,使用文本编辑器打开。编辑该文件,配置推流和拉流的相关设置。 3. 在“http”部分添加以下配置信息: ``` rtmp { server { listen 1935; application live { live on; allow publish all; allow play all; push rtmp://127.0.0.1/live/$name; } } } ``` 4. 在“server”部分添加以下配置信息: ``` location /live { flv; chunked_transfer_encoding on; root html; } ``` 5. 打开命令行,并定位到nginx安装目录的文件夹下运行:“start nginx”命令启动nginx服务器。 6. 下载并安装flv.jshttps://github.com/Bilibili/flv.js)。 7. 在项目的HTML文件中引入flv.js库文件,并使用以下JavaScript代码播放视频: ``` if (flvjs.isSupported()) { var videoElement = document.getElementById('videoElement'); var flvPlayer = flvjs.createPlayer({ type: 'flv', url: 'http://localhost/live/stream.flv' }); flvPlayer.attachMediaElement(videoElement); flvPlayer.load(); flvPlayer.play(); } ``` 8. 访问网页并检查视频是否能够正常播放。 通过以上步骤,你可以在Windows系统下一站式搭建起FFmpeg推流、nginx-http-flv-module直播拉流和flv.js播放环境,实现流媒体的推流、拉流和播放功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值