FLV方式实现网页FFmpeg推流无插件播放

使用FFmpeg将RTSP流转RTMP流,Web播放RTMP流视频需要flash插件的支持,浏览器已不再支持。目前主流的 Web 直播流都为http-flv格式,需要通过服务端将视频流实时转为http-flv流实现网页播放。
需要用到的工具软件:

nginx
nginx-http-flv-module
FFmpeg
flv.js

搭建基于nginx-rtmp-module的流媒体服务器

系统是CentOS7,nginx的版本使用的是nginx-1.8.1.tar.gz。

1.下载nginx和nginx-http-flv-module
nginxnginx-http-flv-module源码下载命令:

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

解压nginx,打开nginx的源代码路径并执行:

./configure --add-module=/usr/local/nginx/nginx-http-flv-module
make&&make install

将nginx-http-flv-module模块编译进NGINX,可以使用--prefix指定安装目录,当前默认。

2.修改nginx的配置文件

打开配置文件

vim /usr/local/nginx/conf/nginx.conf 

删除原内容,复制粘贴 nginx-http-flv-module的官方GitHub README中的配置实例

配置实例

worker_processes  1; #运行在 Windows 上时,设置为 1,因为 Windows 不支持 Unix domain socket
#worker_processes  auto; #1.3.8 和 1.2.5 以及之后的版本

#worker_cpu_affinity  0001 0010 0100 1000; #只能用于 FreeBSD 和 Linux
#worker_cpu_affinity  auto; #1.9.10 以及之后的版本

error_log logs/error.log error;

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

#load_module modules/ngx_http_flv_live_module.so;

events {
    worker_connections  4096;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    keepalive_timeout  65;

    server {
        listen       80;

        location / {
            root   /var/www;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        location /live {
            flv_live on; #打开 HTTP 播放 FLV 直播流功能
            chunked_transfer_encoding on; #支持 'Transfer-Encoding: chunked' 方式回复

            add_header 'Access-Control-Allow-Origin' '*'; #添加额外的 HTTP 头
            add_header 'Access-Control-Allow-Credentials' 'true'; #添加额外的 HTTP 头
        }

        location /hls {
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }

            root /tmp;
            add_header 'Cache-Control' 'no-cache';
        }

        location /dash {
            root /tmp;
            add_header 'Cache-Control' 'no-cache';
        }

        location /stat {
            #推流播放和录制统计数据的配置

            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }

        location /stat.xsl {
            root /var/www/rtmp; #指定 stat.xsl 的位置
        }

        #如果需要 JSON 风格的 stat, 不用指定 stat.xsl
        #但是需要指定一个新的配置项 rtmp_stat_format

        #location /stat {
        #    rtmp_stat all;
        #    rtmp_stat_format json;
        #}

        location /control {
            rtmp_control all; #rtmp 控制模块的配置
        }
    }
}

rtmp_auto_push on;
rtmp_auto_push_reconnect 1s;
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 myapp {
            live on;
            gop_cache on; #打开 GOP 缓存,减少首屏等待时间
        }

        application hls {
            live on;
            hls on;
            hls_path /tmp/hls;
        }

        application dash {
            live on;
            dash on;
            dash_path /tmp/dash;
        }
    }

    server {
        listen 1935;
        server_name *.test.com; #用于虚拟主机名前缀通配

        application myapp {
            live on;
            gop_cache on; #打开 GOP 缓存,减少首屏等待时间
        }
    }

    server {
        listen 1935;
        server_name www.test.com; #用于虚拟主机名完全匹配

        application myapp {
            live on;
            gop_cache on; #打开 GOP 缓存,减少首屏等待时间
        }
    }
}

3.启动 nginx 服务

cd /usr/local/nginx/sbin
./nginx

停止nginx服务

./nginx -s stop

重新加载配置

./nginx -s reload

通过以上配置,即可完成服务端的直播环境配置。

FFmpeg

FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。我们使用ffmpeg需要做的是:

  1. FFmpeg下载,官网地址:http://ffmpeg.org/download.html
  2. 配置环境变量Path;
  3. 使用cmd命令推流,推流命令示例:
ffmpeg -re -i 源视频url -c copy -f flv rtmp://127.0.0.1:1935/myapp/mystream

url根据nginx配置文件的信息修改。

rtmp://example.com[:port]/appname/streamname

flv.js

flv.js是个工程化的前端项目,可以从GitHub下载后,使用工具生成js文件。
flv.js的在线导入代码:

<script src="https://cdn.bootcss.com/flv.js/1.5.0/flv.js"></script>

web页面播放器的代码示例:

<!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;
        }
    </style>
</head>
<body>
<div class="mainContainer">
    <video id="videoElement" class="centeredVideo" controls autoplay width="1024" height="576" muted>Your browser is too old which doesn't support HTML5 video.</video>
</div>
<br>
<div class="controls">
    <!--<button onclick="flv_load()">加载</button>-->
    <button onclick="flv_start()">开始</button>
    <button onclick="flv_pause()">暂停</button>
    <button onclick="flv_destroy()">停止</button>
    <input style="width:100px" type="text" name="seekpoint" />
    <button onclick="flv_seekto()">跳转</button>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/flv.js/1.5.0/flv.min.js"></script>

<script>
    var player = document.getElementById('videoElement');
    if (flvjs.isSupported()) {
        var flvPlayer = flvjs.createPlayer({
            type: 'flv',
            url: 'http://127.0.0.1/live?port=1935&app=myapp&stream=mystream',
            "isLive": true,
            hasAudio: false,
            hasVideo: true,
            //withCredentials: false,
            //cors: true
        }, {
            enableWorker: true,	// 开启多线程
            enableStashBuffer: false,
            lazyLoad: false,
            lazyLoadMaxDuration: 0,
            lazyLoadRecoverDuration: 0,
            deferLoadAfterSourceOpen: false,
            fixAudioTimestampGap: true,
            autoCleanupSourceBuffer: true,
        });
        flvPlayer.attachMediaElement(videoElement);
        flvPlayer.load(); //加载
        flv_start();
    }

    function flv_start() {
        player.play();
    }

    function flv_pause() {
        player.pause();
    }

    function flv_destroy() {
        player.pause();
        player.unload();
        player.detachMediaElement();
        player.destroy();
        player = null;
    }

    function flv_seekto() {
        player.currentTime = parseFloat(document.getElementsByName('seekpoint')[0].value);
    }
</script>
</body>
</html>

参考网上资料进行播放器调优,可以根据实际使用情况调整player的创建参数:

var flvPlayer = flvjs.createPlayer({
                type: 'flv',
                enableWorker: true,     //浏览器端开启flv.js的worker,多进程运行flv.js
                isLive: true,           //直播模式
                hasAudio: false,        //关闭音频             
                hasVideo: true,
                stashInitialSize: 128,  
                enableStashBuffer: false, //播放flv时,设置是否启用播放缓存,只在直播起作用。
                url: 'http://127.0.0.1/live?port=1935&app=myapp&stream=mystream'
            });

此处的url地址就是经过FFmpeg推流的地址,由nginx配置文件决定,格式示例:

http://127.0.0.1/live?port=1935&app=myapp&stream=mystream

至此,整个解决方案已完成搭建,使用浏览器打开播放器地址能够实现无插件播放。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Qt和FFmpeg推流flv的示例代码: ```cpp #include <QCoreApplication> #include <QDebug> #include <QThread> #include <QTimer> #include <QDateTime> #include <QProcess> class FFmpegPusher : public QObject { Q_OBJECT public: explicit FFmpegPusher(QObject *parent = nullptr) : QObject(parent) {} void start(QString ipAddress, QString pushAddress) { QString command = QString("ffmpeg -i %1 -f flv %2").arg(ipAddress).arg(pushAddress); qDebug() << "Command:" << command; m_process = new QProcess(this); connect(m_process, &QProcess::readyReadStandardOutput, this, &FFmpegPusher::onReadyReadStandardOutput); connect(m_process, &QProcess::readyReadStandardError, this, &FFmpegPusher::onReadyReadStandardError); connect(m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &FFmpegPusher::onFinished); m_process->start(command); } private slots: void onReadyReadStandardOutput() { qDebug() << "Standard Output:" << m_process->readAllStandardOutput(); } void onReadyReadStandardError() { qDebug() << "Standard Error:" << m_process->readAllStandardError(); } void onFinished(int exitCode, QProcess::ExitStatus exitStatus) { qDebug() << "Process Finished with Exit Code:" << exitCode << "Exit Status:" << exitStatus; } private: QProcess *m_process = nullptr; }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); FFmpegPusher pusher; pusher.start("rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov", "rtmp://live.hkstv.hk.lxdns.com/live/hks"); return a.exec(); } ``` 该示例代码使用Qt的QProcess类来启动FFmpeg进程,并将其输出重定向到标准输出和标准错误流。您可以根据需要修改IP地址和推送地址。请确保已正确安装FFmpeg并将其添加到系统路径中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值