zoukankan      html  css  js  c++  java
  • rtsp+rtmp多路流媒体播放

    一、前言

      之前博主有写过 一篇博文,讲的是使用videojs在谷歌浏览器网页上播放rtmp流媒体,具体可参考我之前的博客:https://www.cnblogs.com/FHC1994/p/9981440.html

      最近又开始研究了一下网页播放流媒体,在这里我主要补充一些播放rtmp、rtsp流媒体的其他方法

    二、rtsp和rtmp流媒体

    2.1 视频传输原理

      从网络上接收视频时首先需要解协议(RTSP/RTMP/HTTP),然后是解格式(MKV,RMVB),之后才是将视频(H264)和音频(AAC)格式数据分别解码为图像(RGB/YUV)和声音(PCM),再根据时间戳同步播放

    2.2 RTSP和RTMP介绍

      

      RTSP(Real Time Streaming Protocol),RFC2326,实时流传输协议,是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学、网景和RealNetworks公司提交的IETF RFC标准。该协议定义了一对多应用程序如何有效地通过IP网络传送多媒体数据。RTSP在体系结构上位于RTP和RTCP之上,它使用TCP或UDP完成数据传输。目前多数网络摄像机支持RTSP、ONVIF等通用的协议,而支持RTMP比较少

      RTMP是Real Time Messaging Protocol(实时消息传输协议)的首字母缩写。该协议基于TCP,是一个协议族,包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种。RTMP是一种设计用来进行实时数据通信的网络协议,主要用来在Flash/AIR平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信。支持该协议的软件包括Adobe Media Server/Ultrant Media Server/red5等。使用RTMP技术的流媒体系统有一个非常明显的特点:使用 Flash Player 作为播放器客户端,而Flash Player 现在已经安装在了全世界将近99%的PC上,因此一般情况下收看RTMP流媒体系统的视音频是不需要安装插件的。用户只需要打开网页,就可以直接收看流媒体,十分方便。直播服务普遍采用了RTMP作为流媒体协议,FLV作为封装格式,H.264作为视频编码格式,AAC作为音频编码格式。FLV是RTMP使用的封装格式,H.264是当今实际应用中编码效率最高的视频编码标准,AAC则是当今实际应用中编码效率最高的音频编码标准。

      RTSP和RTMP是2种不同的网络传输协议,RTSP(Real Time Streaming Protocol)是实时流传输协议,而RTMP是Real Time Messaging Protocol(实时消息传输协议)。RTSP主要用于IPTV,原因是传输数据使用的是UDP,在网络环境比较稳定的情况下,传输效率是比较高的。RTMP主要用于互联网音视频传输,它使用的是TCP传输,因为互联网环境相对较差,采用RTMP保证了视频的传输质量,但是其传输延迟相对较高,传输效率相对较低

      参考:https://blog.csdn.net/liujiayu2/article/details/80658395

                      https://blog.csdn.net/leixiaohua1020/article/details/18893769 (视音频编解码技术,推荐)

    2.3 补充 

      RTSP直播源地址:

        rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov

    三、rtsp、rtmp播放方法

    3.1 videojs播放rtmp流媒体——videojs不支持rtsp——仅支持在Hbuilder等自带服务器环境下打开才可以播放rtmp

    代码如下:

    <!-- 播放rtmp网络视频 -->
    <!DOCTYPE html>
    <html>
        <head>
            <title>播放器</title>
            <link href="./videolib/css/video-js.min.css" rel="stylesheet" type="text/css">
            <style>
                html,body{
                    height: 100%;
                    width: 100%;
                    padding: 0;
                    margin: 0;
                }
            </style>
        </head>
        <body>
            <div>
                <video id="myvideo1" width="350" height="250" class="video-js vjs-default-skin" muted controls>
                    <!-- rtmp视频流 -->
                    <source src="rtmp://202.69.69.180:443/webcast/bshdlive-pc" type="rtmp/flv">
                </video>
                <br />
                <video id="myvideo2" width="350" height="250" class="video-js vjs-default-skin" muted controls>
                    <!-- rtmp视频流 -->
                    <source src="rtmp://media3.sinovision.net:1935/live/livestream" type="rtmp/flv">
                </video>
            </div>
            <script src="./videolib/js/video.min.js"></script>
            <script src="./videolib/videojs-flash.min.js"> </script>
            <script>
                var player1 = videojs("myvideo1", {}, function() {
                    console.log("videojs播放器初始化成功")
                })
                player1.play()
                var player2 = videojs("myvideo2", {}, function() {
                    console.log("videojs播放器初始化成功")
                })
                player2.play()
            </script>
        </body>
    </html>

    效果:

    3.2 flowplayerjs播放rtmp流媒体——flowplayerjs不支持rtsp——支持在本地直接打开播放rtmp

    代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>rtmp直播</title>
        <link rel="stylesheet" href="./css/video-js.css">
        <link rel="stylesheet" href="./css/h5splayer.css">
        <script src="./js/flowplayer-3.2.13.min.js"></script>
    </head>
    <body>
        <div class="h5video" id="playerDiv1" style="float: left;"></div>    
        <div class="h5video" id="playerDiv2" style="float: left;"></div>
        <div class="h5video" id="playerDiv3" style="float: left;"></div>
        <script>
                
            // 播放地址
            var url_1 = 'rtmp://202.69.69.180:443/webcast/bshdlive-pc';
            var url_2 = 'rtmp://media3.sinovision.net:1935/live/livestream';
            var url_3 = 'rtmp://58.200.131.2:1935/livetv/hunantv';
    
            var oPlayerDiv1 = document.getElementById('playerDiv1');
            var    oPlayerDiv2 = document.getElementById('playerDiv2');
            var    oPlayerDiv3 = document.getElementById('playerDiv3');
    
            oPlayerDiv1.setAttribute("data-rtmp", url_1);
            oPlayerDiv1.setAttribute("href", url_1);
    
            oPlayerDiv2.setAttribute("data-rtmp", url_2);
            oPlayerDiv2.setAttribute("href", url_2);
    
            oPlayerDiv3.setAttribute("data-rtmp", url_3);
            oPlayerDiv3.setAttribute("href", url_3);
    
            var swfStr = "./swf/flowplayer-3.2.18.swf"
            var    obj_1 = {
                    clip: {
                        provider: 'rtmp',
                        bufferLength: 0,
                        bufferTime: 0,
                        autoPlay: true,
                        live: true
                    },
                    plugins: {
                        rtmp: {
                            url: "flowplayer.rtmp-3.2.13.swf",
                            netConnectionUrl: url_1
                        }
                    }
                };
                
            const obj_2 = JSON.parse(JSON.stringify(obj_1))   //js对象的深拷贝   // JSON.stringify() 方法将 JavaScript 对象转换为字符串   JSON.parse() 方法将数据转换为 JavaScript 对象
            obj_2.plugins.rtmp.netConnectionUrl = url_2;
            const obj_3 = JSON.parse(JSON.stringify(obj_1)) 
            obj_3.plugins.rtmp.netConnectionUrl = url_3;
    
            flowplayer('playerDiv1', swfStr, obj_1);
            flowplayer('playerDiv2', swfStr, obj_2);
            flowplayer('playerDiv3', swfStr, obj_3);
        </script>
    </body>
    </html>

    效果:

     注意!!!

      1. 由于RTMP协议是在 Flash 播放器上播放的,所以对于H5的video播放器是不能直接播放的,必须要让所用浏览器支持flash,才可以播放rtmp流媒体。目前来说,谷歌浏览器是支持Flash的,但是在2020年12月后谷歌浏览器将不再支持Flash,所以以上两种方法只能暂时使用,并不是长久之计!  

      

       2. flowplayerjs不支持rtsp流媒体,浏览器原生js只支持http,基于flash的播放器也只能支持到rtmp,如果要支持rtsp需要使用c/c++插件(npapi或者activex)。videojs同样如此,不支持rtsp流媒体

    3.3 python搭建flask服务器播放rtsp、rtmp流媒体

    python代码如下:

    from flask import Flask, render_template, Response
    import cv2
    
    class VideoCamera():
        def __init__(self,vurl):
            # 通过opencv获取实时视频流
            self.video = cv2.VideoCapture(vurl)
    
        def __del__(self):
            self.video.release()
    
        def get_frame(self):
            success, image = self.video.read()
            ret, jpeg = cv2.imencode('.jpg', image)
            #转化为字节流
            return jpeg.tobytes()
    
    # app是Flask的实例,它接收包或者模块的名字作为参数,但一般都是传递__name__
    app = Flask(__name__)
    @app.route('/')  # 主页
    def index():
        return render_template('index.html')
    
    @app.route('/video1_feed')  # 这个地址返回rtsp视频流响应
    def video1_feed():
        return Response(gen1(VideoCamera("rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov")), mimetype='multipart/x-mixed-replace; boundary=frame')
    
    @app.route('/video2_feed')  # 这个地址返回rtmp视频流响应
    def video2_feed():
        return Response(gen2(VideoCamera("rtmp://202.69.69.180:443/webcast/bshdlive-pc")), mimetype='multipart/x-mixed-replace; boundary=frame')
    
    @app.route('/video3_feed')  # 这个地址返回rtmp视频流响应
    def video3_feed():
        return Response(gen3(VideoCamera("rtmp://media3.sinovision.net:1935/live/livestream")), mimetype='multipart/x-mixed-replace; boundary=frame')
    
    @app.route('/video4_feed')  # 这个地址返回rtmp视频流响应
    def video4_feed():
        return Response(gen4(VideoCamera("rtmp://58.200.131.2:1935/livetv/hunantv")), mimetype='multipart/x-mixed-replace; boundary=frame')
    
    def gen1(camera):
        while True:
            frame = camera.get_frame()
            yield (b'--frame
    '
                   b'Content-Type: image/jpeg
    
    ' + frame + b'
    
    ')
    def gen2(camera):
        while True:
            frame = camera.get_frame()
            yield (b'--frame
    '
                   b'Content-Type: image/jpeg
    
    ' + frame + b'
    
    ')
    def gen3(camera):
        while True:
            frame = camera.get_frame()
            yield (b'--frame
    '
                   b'Content-Type: image/jpeg
    
    ' + frame + b'
    
    ')
    def gen4(camera):
        while True:
            frame = camera.get_frame()
            yield (b'--frame
    '
                   b'Content-Type: image/jpeg
    
    ' + frame + b'
    
    ')
    
    if __name__ == '__main__':
        app.run(host='127.0.0.1', debug=True, port = 5000)

    html代码如下:

    <html>
        <head>
            <title>多路视频直播</title>
            <style>
                html, body {
                    height: 100%;
                    width: 100%;
                    padding: 0;
                    margin: 0;
                }
                .divbg{
                    width:300px;
                    height:200px;
                }
                .videostyle{
                    min-height: 100%;
                    min-width: 100%;
                    max-height: 100%;
                    max-width: 100%;
                }
            </style>
        </head>
        <body>
            <h2>rtsp流媒体</h2>
            <!-- 第一个rtsp视频流 -->
            <div class="divbg">
                <img  class="videostyle" src="{{ url_for('video1_feed') }}">
            </div>
            <br>
            <h2>rtmp流媒体</h2>
            <!-- 第一个rtmp视频流 -->
            <div class="divbg" style="float: left; margin-right: 5px;">
                <img class="videostyle" src="{{ url_for('video2_feed') }}">
            </div>
            <!-- 第二个rtmp视频流 -->
            <div class="divbg" style="float: left; margin-right: 5px;">
                <img  class="videostyle" src="{{ url_for('video3_feed') }}">
            </div>
            <!-- 第三个rtmp视频流 -->
            <div class="divbg" style="float: left;">
                <img class="videostyle" src="{{ url_for('video4_feed') }}">
            </div>
        </body>
    </html>

    效果:

    python控制台:

     网页效果:

     注意!!!

       python搭建一个flask服务器后,就可以播放任何格式的流媒体协议,因为flask后端直接将视频流转换为一帧一帧的图片,然后推送到网页上显示即可!但是,python搭建flask服务器播放rtsp、rtmp流媒体的缺点就是没办法播放声音,只有图片!

     源程序可到博主github上下载:https://github.com/HuerFu/h5_rtmp_play

  • 相关阅读:
    Git 游离态的一次问题解决
    idea每次新建项目的默认路径
    springboot 整合 freemarker
    Linux 学习网站
    springtask 基本使用和 cron 表达式
    volatile 关键字 和 i++ 原子性
    python 自动补全
    nagios维护之常见问题
    nagios维护之添加监控
    windows下python文件与文件夹操作
  • 原文地址:https://www.cnblogs.com/FHC1994/p/11724484.html
Copyright © 2011-2022 走看看