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

  • 相关阅读:
    hdu 3790 最短路径问题
    hdu 2112 HDU Today
    最短路问题 以hdu1874为例
    hdu 1690 Bus System Floyd
    hdu 2066 一个人的旅行
    hdu 2680 Choose the best route
    hdu 1596 find the safest road
    hdu 1869 六度分离
    hdu 3339 In Action
    序列化和反序列化
  • 原文地址:https://www.cnblogs.com/FHC1994/p/11724484.html
Copyright © 2011-2022 走看看