浏览器播放RTSP摄像头视频

一、项目需求,需要在chrome浏览器中播放rtsp协议的摄像头视频流

二、思路:
1、chrome已经不支持插件了,所以排除一切插件的思路;
2、浏览器目前停留在支持rtmp协议,hls协议流视频阶段,还没开始支持rtsp协议,所以可以考虑将rtsp转成rtmp和hls。在领导的指导下,选择的是rtmp,至于hls有兴趣的同学可以自己去研究,整体思路与转rtmp是一直的。
3、有了大体方向就开始着手找资料了,网上有很多使用FFmpeg+nginx来将rtsp转rtmp的,当然也有可以花钱去买转码器的,那就更加方便了。(转码器也不是很贵,项目资金充足的,而且不想花时间研究的,可以考虑这个会更好);

三、实现:
3.1、rtsp公网测试例子:rtsp://184.72.239.149/vod/mp4:BigBuckBunny_175k.mov
3.2、FFmpeg:
3.2.1 资源下载:通过官网http://www.ffmpeg.org/download.html或其他途径下载ffmpeg(https://ffmpeg.zeranoe.com/builds),解压到随意目录下,解压之后如下图:
浏览器播放RTSP摄像头视频
3.2.2配置环境变量,浏览器播放RTSP摄像头视频命令窗口输入“ffmpeg -version”出现如下图及说明环境配置正确
浏览器播放RTSP摄像头视频

3.3、nginx:
3.3.1、安装配置nginx,配置已经配置好了,直接下载即可使用。nginx包和配置文件
浏览器播放RTSP摄像头视频
3.3.2、修改conf文件夹下nginx.conf文件,文件内容如下:

worker_processes  1;

error_log  logs/error.log debug;

events {
    worker_connections  1024;
}

rtmp {
    server {
        listen 1935;
        
        chunk_size 4000;
        
        application live {
            live on;
        }
        
        application hls {
            live on;
            hls on;  
            hls_path temp/hls;  
            hls_fragment 8s;  
        }
    }
}

http {
    include        mime.types;
    default_type    application/octet-stream;
    sendfile        on;
    keepalive_timeout    65;
    server {
        listen      20000;
        
        location / {
            root html;
            index    index.html index.htm;
        }
        
        location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }

        location /stat.xsl {
            root html;
        }
        
        location /hls {  
            #server hls fragments  
            types{  
                application/vnd.apple.mpegurl m3u8;  
                video/mp2t ts;  
            }  
            alias temp/hls;  
            expires -1;  
        }
        
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

3.3.3、修改完成后启动nginx,
有多种方式启动nginx,(1)、直接双击nginx.exe,双击后一个黑色的弹框一闪而过,(2)、打开cmd命令窗口,切换到nginx解压目录下,输入命令nginx.exe或者start nginx,回车即可
检查nginx是否启动成功:
直接在浏览器中输入网址http:localhost:post,post为nginx.conf中设置的,此处我设置的是20000,回车出现如下
浏览器播放RTSP摄像头视频
说明启动成功了。

3.3.4、关闭nginx:
如果使用cmd命令窗口启动nginx,关闭cmd窗口是不能结束nginx进程的,可使用两种方法关闭nginx
(1)、输入nginx命令 nginx -s stop(快速停止nginx)或者nginx -s quit(完整有序的停止nginx)
(2)使用taskkill taskkilll /f /t /im nginx.exe
**3.3.5、**nginx还可以做负载均衡,此处没有研究,有需求的同学可自行研究。

3.3.6、开始转码:
在cmd窗口执行如下命令

ffmpeg -re  -rtsp_transport tcp -i "rtsp地址" -f flv -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 "rtmp://本机地址:1935(nginx.conf的rtmp模块下listen)/live(rtmp模块下application设置)/test(随便取名字)"

启动之后如下图:
浏览器播放RTSP摄像头视频
注意:
1、ffmpeg转码与nginx代理可以不在同一台服务器上进行,但这种情况对带宽要求较高
2、如果rtsp视频流断开,可能导致转码程序一直等待,因此加入-stimeout参数(表示超时时间),如果超时未获取到视频流,则报错退出(如需重新获取,可以写个bat脚本,循环执行ffmpeg命令)

3.4、chrome中播放rtmp实时流:
H5的video标签是不支持rtmp的,但是我们有video.js可以解决这一问题。然而在使用video.js的时候遇到了问题,刚开始怎么都播不出来,后来经过一番查找发现,在video.js 6以上的版本是已经没法播放了。原因是video.js播放rtmp的原理还是通过flash。可能是video为了紧跟步伐,去掉了flash。
代码包请点击这里下载
将代码修改如下:
浏览器播放RTSP摄像头视频

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Access-Control-Allow-Origin" content="*">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>测试rtmp直播源</title>
<script src="js/video.js"></script>
<link href="css/video-js.css" rel="stylesheet">
<!-- If you'd like to support IE8 -->
<script src="js/videojs-ie8.min.js"></script>
</head>
<body>
<div class="openFlashTips" style="width:300px;position:absolute;top:20px;left:225px;z-Index:9999;color:white">视频无法正常播放,请点击下方启用flash</div>
<video id="my-video" style="color:black;width:750px;height:350px" class="video-js" autoplay controls preload="auto" width="750" height="350" data-setup="{}">
    <source src='rtmp://172.16.15.240:1935/live/test11' type='rtmp/flv'/>
</video>
<embed width="300" height="70" class="openFlash" style="position:absolute;top:130px;left:225px;z-Index:9999;" type="application/x-shockwave-flash">
<script type="text/javascript" language="JavaScript">
    function flashChecker() {
        var hasFlash = 0;         //是否安装了flash
        var flashVersion = 0; //flash版本
        var isIE = /*@[email protected]*/0;      //是否IE浏览器

        if (isIE) {
            var swf = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
            if (swf) {
                hasFlash = 1;
                VSwf = swf.GetVariable("$version");
                flashVersion = parseInt(VSwf.split(" ")[1].split(",")[0]);
            }
        } else {
            if (navigator.plugins && navigator.plugins.length > 0) {
                var swf = navigator.plugins["Shockwave Flash"];
                if (swf) {
                    hasFlash = 1;
                    var words = swf.description.split(" ");
                    for (var i = 0; i < words.length; ++i) {
                        if (isNaN(parseInt(words[i]))) continue;
                        flashVersion = parseInt(words[i]);
                    }
                }
            }
        }
        return {f: hasFlash, v: flashVersion};
    }

    var fls = flashChecker();
    var s = "";
    if (fls.f) {
        document.getElementsByClassName("openFlash")[0].style.display = "none";
        document.getElementsByClassName("openFlashTips")[0].style.display = "none";
//        document.write("您安装了flash,当前flash版本为: " + fls.v + ".x");
    }
    else {
        document.getElementsByClassName("openFlash")[0].style.display = "block";
        document.getElementsByClassName("openFlashTips")[0].style.display = "block";
//        document.write("您没有安装flash");
    }
</script>
</body>
</html>

启动tomcat,在浏览器中输入网址即可查看实时视频(如下图的测试视频)。
浏览器播放RTSP摄像头视频
正式环境测试效果:转码之后差不多延迟在3-5秒左右。
浏览器播放RTSP摄像头视频
欢迎大家一起交流,如果文章中有错误的地方,也希望指正。