通过webrtc推流到前端实现视频播放

最近遇到一个这样的需求,希望通过对海康摄像头的画面信息编辑后,视频画面在前端显示,要求视频信息播放不依赖任何第三方插件。

试了很多种办法,其实都没有实现最终的效果。这篇文章是通过webrtc进行的尝试,最后延迟大,不稳定。对于上面的需求不是一种成功的解决方案。姑且认为在通过webrtc实现这种方案的时候,遇到了一些问题,汇总记录一下,供其他场景参考。

对于这个问题,尝试过的集中办法对比如下

1. 依赖flash插件的nginx+rtmp方案:依赖第三方插件,前端延迟大,服务端解码推流不稳定。

2. 利用streamedian这个库进行播放:收费,而且智能直接拉取rtsp视频流,并且运行的时候发现1路摄像头也会有不稳定情况,产生延迟(从摄像头时间可以看出来),而且实际测试播放一段时间视频流需要重新加载,不知道的hi免费版的原因还是哪里配置的问题。这些情况对于无人值守的情况还是有问题。

3. 通过websocket 前端与后台建立连接,后台视频帧推送,会产生解码错误(opencv 编解码有关,原因未知),而且由于视频画面是高清画质,单次推送信息大小至少都是70万字节起,推送很慢(感觉和网络带宽有关);

尝试的三种方法对比如上。接下来着重记录一下通过websocket尝试实现这种方法的过程。

分别在前端后台实现websockett。后台通过一个C++开源项目https://www.codeproject.com/Articles/371188/A-Cplusplus-Websocket-Server-For-realtime-interact。

这个项目是个win32的项目,可以直接编译运行,前后端也成功连接。

由于项目的其他的运行环境都是x64所以需要编译x64的版本。对于win32 与x64的差别,对于本项目主要是由于数据长度导致的类型检查错误,以及由于数据截断导致的运行时错误。系统了解win32 与 x64的差别戳这里https://social.msdn.microsoft.com/Forums/vstudio/en-US/15f7d186-26ee-4f4a-8231-98d67359a90e/having-trouble-porting-directory-watch-program-to-64-bit?forum=vcgeneral。

我们这里把注意力放在如何快速编译并运行项目。具体发生类型转换和数据截断错误的在一下几处调用API的地方,分别是

CreateIoCompletionPort();

GetQueuedCompletionStatus();

GetQueuedCompletionStatus();

主要差别在LPDWORD / DWORD 和 PULONG_PTR / ULONG_PTR这几个参数的转换上。不管win32还是x64 尽量统一使用PULONG_PTR / ULONG_PTR就不会有问题了。

以上是引入这个开源实现遇到的问题。其实在这之前尝试过其他方式实现websocket尝试过通过boost实现的websocket.Windows平台websocket 都是通过完成端口实现的,效率最优。

前端调用就很简单了。H5原生支持websocket.

function connect() {

                var host = "ws://localhost:81/test";

                try {
                    socket = new WebSocket(host);
                    // OutputLog('Socket Status: ' + socket.readyState);
                    socket.onopen = function () {
                        // OutputLog('Socket Status: ' + socket.readyState + ' (open)');
                        // var pseudoName = $('#pseudo').val();
                        socket.send('0zy');
                    }

                    socket.onmessage = function (msg) {
                        var str = "";
                        str = msg.data;
                        var id = str.substr(0, 1);
                        var separator = str.indexOf("|");
                        var arg1 = "";
                        var arg2 = "";
                        if (separator != -1) {
                            arg1 = str.substr(1, separator - 1);
                            arg2 = str.substr(separator + 1);
                        }
                        else
                            arg1 = str.substr(1);

                        if (id == "0") {
                            OutputLog('Server reply : ' + arg1);
                        }
                        if (id == "1") {
                            OutputLog('Server echo msg : ' + arg1);
                        }
                        if (id == "2") {
                            OutputLog(arg1 + ' said : ' + arg2);
                        }
                        if (id == "3") {
                            OutputLog(arg1 + ' broadcasted : ' + arg2);
                        }
                        if (id == "4") {
                            // OutputLog('Server streamed : ' + arg1);
                            $('#target').src = "data:image/png;base64," + arg1;
                        }

                    }

                    socket.onclose = function () {
                        OutputLog('Socket Status: ' + socket.readyState + ' (Closed)');
                    }

                } catch (exception) {
                    // OutputLog('Error' + exception);
                }

            }

 

通过webrtc推流到前端实现视频播放_第1张图片

 

 

你可能感兴趣的:(websocket)