前端RTSP流自定义页面展示

452 阅读2分钟

2.1RTSP流前端展示

使用天敏面板机进行人脸识别。RTSP(Real Time Streaming Protocal),是一个实时流传输协议,是 TCP/IP 协议体系中的一个应用层协议。RTSP实时性较好,适合视频聊天、视频监控等方向。

2.1.1 RTSP->HTTP

通过下载VLC软件,对RSTP流进行串流成Http协议的格式。VLC本身播放RSTP流就有1.5秒左右的延迟,串流到网页上用<video>标签播放就有15秒左右的延迟了,达不到理想的效果。即使降低分辨率也效果甚微。

需要一个中间层来将RTSP流转成前端可以支持的协议:

2.1.2 RTSP->RTMP

RTMP需要通过flash插件进行推流,但是flash插件逐渐被淘汰,HTML5也没有针对RTMP的实现,所以out。

2.1.3 RTSP->HTTP

通过下载VLC软件,对RSTP流进行串流成Http协议的格式。VLC本身播放RSTP流就有1.5秒左右的延迟,串流到网页上用<video>标签播放就有15秒左右的延迟了,达不到理想的效果。即使降低分辨率也效果甚微。

2.1.4 RTSP->websocket
ffmpeg+jsmpeg-player

通过ffmpeg工具来拉流、转码和推流。前端使用jsmpeg-player第三方库进行实现。有微小的延迟。

2.1.5 webrtc第三方库

使用webrct-streamer包,后端使用docker配置到服务器上。前端使用<iframe>标签进行展示。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!--video用于显示媒体设备的视频流,自动播放-->
    <video id="video" autoplay style="width: 480px;height: 320px"></video>
    <!--拍照按钮-->
    <div>
        <button id="capture">拍照</button>
    </div>
    <!--描绘video截图-->
    <canvas id="canvas" width="480px" height="320px"></canvas>
    
</body>
</html>

<script>
    //dom
    let video = document.getElementById('video');
    let canvas = document.getElementById('canvas');
    let capture = document.getElementById('capture');
    let context = canvas.getContext('2d');


    // getUserMediaToPhoto函数是自己定义的,传入3个参数
    // 第一个参数constraints是一个对象,指定了请求的媒体类型和相对应的参数,针对本项目讲,就是设置视频的宽高
    // 参考MDN:https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedia
    // 第二个参数:success,是成功回调函数
    // 第三个参数:error,是抛出错误函数,具体又分为:没有获取到用户视频权限 和 浏览器不支持,分别在控制台输出提示
    
    function getUserMediaToPhoto(constraints, success, error) {
        if (navigator.mediaDevices.getUserMedia) {
            //最新标准API   参考MDN:https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedia
            // 在绝大多数情况下,会调用这个方法,.then  .catch是Promise的方法
            // 传入第一个参数,constraints,然后执行.then 然后执行success方法 参考MDN:https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedia#%E7%A4%BA%E4%BE%8B
            navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
        } else if (navigator.webkitGetUserMedia) {
            //webkit核心浏览器,针对不同浏览器,调用浏览器的获取用户媒体的方法
            navigator.webkitGetUserMedia(constraints, success, error);
        } else if (navigator.mozGetUserMedia) {
            //firefox浏览器
            navigator.mozGetUserMedia(constraints, success, error);
        } else if (navigator.getUserMedia) {
            //旧版API
            navigator.getUserMedia(constraints, success, error);
        }
    }

    //成功回调函数
    function success(stream) {
        //兼容webkit核心浏览器 window.URL主要作用是读取文件的字符串,在img或video等带有src属性的标签上展示。
        var CompatibleURL = window.URL || window.webkitURL;
        
        //将视频流转化为video的源
        // video.src = CompatibleURL.createObjectURL(stream);
        video.srcObject = stream;
        video.play();//播放视频
        console.log(video.srcObject);
    }
    function error(error) {
        console.log('访问用户媒体失败:', error.name, error.message);
        document.write("访问用户媒体失败!")
    }

    
    if (navigator.mediaDevices.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia) {
        getUserMediaToPhoto({ video: { width: 480, height: 320 } }, success, error);
    } else {
        alert('你的浏览器不支持访问用户媒体设备');
    }

    capture.addEventListener('click', function () {
        // 将video画面描绘在canvas画布上
        context.drawImage(video, 0, 0, 480, 320);
    })
</script>

2.2 人脸识别页面的前端实现

写一个轮询方法:整体用useCallback包裹,依赖项写空数组——即仅在页面初次渲染时调用。如果定时器存在,那么清除定时器,并定义定时器一秒执行一次回调函数。回调函数是发送人脸登录的网络请求。使用localStorage.setItem来存储返回来的token。取消登录的操作:写一个remove函数来去除localStorage中的token,点击取消按钮调用这个函数并关闭定时器,使用window.location.reload()来刷新页面。

画面展示使用,它能将另一个Html页面嵌入到页面中。把后端转码过来的视频数据写成一个HTML网页,可以配置RSTP相关的配置,比如第一次连接,第二次连接,关闭的回调等等。