录像交互
自己接口的定义
-
点击搜索u盘文件:
明日接口分析
-
点击搜索u盘文件:
-
请求:
- 类型:POST
- URL: http://192.168.1.96/querydata
参数
page: 1 rows: 10 szCmd: {"QueryRecord":{"szStTime":"2024-01-25+00:00:00","szEdTime":"2024-01-25+23:59:59"}}
请求头
Accept: application/json, text/javascript, */*; q=0.01 Accept-Encoding: gzip, deflate Accept-Language: zh-CN Cache-Control: no-cache Connection: Keep-Alive Content-Length: 148 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Cookie: language=cn; -goahead-session-=::webs.session::1932ccd6dbf02b3f268c9f1a970b6cd2 Host: 192.168.1.96 Referer: http://192.168.1.96/pages/playback.asp User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko X-Requested-With: XMLHttpRequest
-
响应:
参数
{ "nRetVal": 0, "total": 150, "rows": [ { "szStTime": "2024-01-25 08:59:13", "dwFileSize": 61468, "szFileName": "2024-01-25-085913.ts", "szDir": "/disk/usb", "szEdTime": "2024-01-25 09:00:16" }, { "szStTime": "2024-01-25 09:00:16", "dwFileSize": 61466, "szFileName": "2024-01-25-090016.ts", "szDir": "/disk/usb", "szEdTime": "2024-01-25 09:01:19" }, { "szStTime": "2024-01-25 09:01:19", "dwFileSize": 61468, "szFileName": "2024-01-25-090119.ts", "szDir": "/disk/usb", "szEdTime": "2024-01-25 09:02:22" }, { "szStTime": "2024-01-25 09:02:22", "dwFileSize": 61469, "szFileName": "2024-01-25-090222.ts", "szDir": "/disk/usb", "szEdTime": "2024-01-25 09:03:25" }, { "szStTime": "2024-01-25 09:03:25", "dwFileSize": 61469, "szFileName": "2024-01-25-090325.ts", "szDir": "/disk/usb", "szEdTime": "2024-01-25 09:04:28" }, { "szStTime": "2024-01-25 09:04:28", "dwFileSize": 61465, "szFileName": "2024-01-25-090428.ts", "szDir": "/disk/usb", "szEdTime": "2024-01-25 09:05:31" }, { "szStTime": "2024-01-25 09:05:31", "dwFileSize": 61468, "szFileName": "2024-01-25-090531.ts", "szDir": "/disk/usb", "szEdTime": "2024-01-25 09:06:34" }, { "szStTime": "2024-01-25 09:06:34", "dwFileSize": 64013, "szFileName": "2024-01-25-090634.ts", "szDir": "/disk/usb", "szEdTime": "2024-01-25 09:07:38" }, ...... ] }
响应头
Connection: keep-alive Content-Type: text/plain Date: Thu, 25 Jan 2024 18:41:57 GMT Transfer-Encoding: chunked X-Frame-Options: SAMEORIGIN
-
分析:
- 请求的时候段不管有多少记录全部一次返回,这样是存在问题的。如果数据量多的时候将:
- 导致页面响应速度变慢,尤其是当网络带宽有限或者用户设备性能较弱的时候
- 导致浏览器内存占用过高。如果数据量很大,一次性加载所有数据会占用大量的浏览器内存,可能导致页面卡顿、浏览器崩溃...
- 延长看到内容的等待时间、页面滚动不流畅
- 对于不需要立即展示的数据,提前加载是一种不必要的资源消耗,包括服务器带宽和客户端存储空间。一般都是采用分页加载、懒加载或者按需加载的方式
- 请求的时候段不管有多少记录全部一次返回,这样是存在问题的。如果数据量多的时候将:
-
-
点击搜索本地文件:
- 请求:
- ?
- 响应:
- ?
- 分析:
- 首先浏览器 js 的权限仅限于Web应用程序自身的沙箱环境 , 所以像查找指定时间范围内的文件、创建文件\文件夹、修改时间信息... 这些就不用想了,如果不使用插件的话必然要web服务器去处理这些东西,然后给我返回成功或失败
- 无论是浏览器抓取网络信息还是wireshark 都没看到有网络交互行为。 我只能猜测是插件在起作用,插件完成了本地文件的搜索。
-
以下代码证实了我的猜测,搜索本地文件、播放视频、等都是插件带来的功能
明日本地搜索代码分析
//1. searchClick() 如果是本地搜索调用 szDataArray = vodPlayOcx.searchfile(fileType, dateStart, dateEnd); // szDataArray 存放搜索的结果 function searchClick(){ var msg, title, szDataArray, rows = [], dateStart, dateEnd; title = getNodeValue('jsTips'); clearGrid(); var fileType = eval($('#type').combobox('getValue')); dateStart = changeDateFormat($("#dateStart").datebox("getValue")); dateEnd = changeDateFormat($("#dateEnd").datebox("getValue")); if(dateStart > dateEnd) { msg = getNodeValue('jsTimeErr'); $.messager.show({ title: title, msg: msg, showType:'show' }); return; } if(eval($('#store').combobox('getValue')) == 0){ bPlayLocal = true; showSdCardGrid(false); $('#delete').linkbutton('disable'); $('#download').linkbutton('disable'); bImage = eval($('#type').combobox('getValue')) == 1 ? true : false; szDataArray = vodPlayOcx.searchfile(fileType, dateStart, dateEnd); if(szDataArray){ szDataArray = JSON.parse(szDataArray); for (var i = 0; i < szDataArray.length; i++) { var temp = szDataArray[i].split('_'), temp1 = temp[1]; rows.push({ "szFileName": temp1, "szDir": szDataArray[i] }) } $("#localFileGrid").datagrid("loadData", rows); } } else{ bPlayLocal = false; showSdCardGrid(true); $('#download').linkbutton('enable'); $('#delete').linkbutton('enable'); $('#sdcardFileGrid').datagrid({url: '/querydata'}); } /*$.messager.show({ title: getNodeValue('jsTips'), msg: getNodeValue('jsSearchFinish'), showType:'show' });*/ } /*2. 果然以下代码证实了 vodPlayOcx 是在网页中嵌入和实例化的一个ActiveX控件 id="vodPlayOcx":为该控件赋予为ID为"vodPlayOcx",这样可以通过document.getElementById('vodPlayOcx')来使用这个控件。 classid="clsid:A1B24620-C83C-46D4-9D08-28A77140B802":这是指定了要加载的ActiveX控件的类标识符,当浏览器遇到这个标签时,会去查找并激活对应GUID的COM组件。这里就是视频播放相关的ActiveX控件。 codebase="../ocxPlugin/MRWebXinstall.exe#version=1.2.8_R_20190328":如果浏览器没有安装这个ActiveX控件,将下载指定路径下的安装程序(MRWebXinstall.exe)进行安装 standby="Waiting...":这是一个过时的属性,用于在对象加载期间需要显示的消息提示。 */ <object id="vodPlayOcx" classid="clsid:A1B24620-C83C-46D4-9D08-28A77140B802" codebase="../ocxPlugin/MRWebXinstall.exe#version=1.2.8_R_20190328" standby="Waiting..." width="100%" height="100%" align="center"> <label id="laBrowserTips" class="paramconfigtitle">只支持IE内核的浏览器回放视频!</label> </object> // 3. 接着初始化了如上的控件: function InitOcx(){ if(getView != null) window.clearTimeout(getView); vodPlayOcx = document.getElementById("vodPlayOcx"); if(vodPlayOcx) { vodPlayOcx.ocxinit(); vodPlayOcx.viewmodeset(2); } } // 4.继续寻找 vodPlayOcx 插件带来的功能都: vodPlayOcx.ocxinit(); // 初始化控件 vodPlayOcx.viewmodeset(2);// 可能是用来设置视频播放画面的展示方式,比如参数2可能代表全屏、窗口模式... vodPlayOcx.downloadstop(s_nDownHandle);// 猜测是停止下载任务。通过传过来的s_nDownHandle来停止指定的文件下载 vodPlayOcx.playstop();// 猜测是停止播放视频 vodPlayOcx.searchfile(fileType, dateStart, dateEnd); // 搜索文件.并返回相应的搜索结果. 本地搜索就用到了,果然是通过插件的方式 vodPlayOcx.playshowimage(szFileName); //显示图像。可能用于在播放器界面上显示指定名称的静态图像,比如缩略图 vodPlayOcx.playfilestart(szFileName); // 播放视频文件。 vodPlayOcx.downloadstate(s_nDownHandle); // 获取下载状态。比如完成、进行中、暂停、取消... ......
- 基于上一步基础去看下它的插件:前几天下载的插件找不到了,但是我记得的使用了 各种 ffmpeg 相关的 dll
-
- 请求:
-
点击本地录像
- 请求:?
- 响应:?
- 分析:
- 还是没看到网络交互,其实分析 "点击搜索本地文件" 的时间已经有预料到了是用插件来实现的。还是跟踪验证一下:
-
以下分析证实了,本地录制功能也是通过插件实现的
代码分析
// 1. 从这里出发 <a id="record" class="toolbar record" href="javascript:void(0)" hidefocus="" title="本地录像"></a> // 2. 在 live.js 里:注意 m_livePlayOcx = document.getElementById("livePlayOcx"); function pageload(){ ... if (isIE()) { $("#laBrowserTips").hide(); s_stDevAttr = window.parent.g_stDevAttr; s_stStreamName = window.parent.g_stStreamName; m_livePlayOcx = document.getElementById("livePlayOcx"); LoginIPC = setTimeout('startView("' + s_stStreamName.stMaster.szStreamName + '")', 100); bStreamType = 0; } ... } // 3. 一段js 注意: m_livePlayOcx.localrecord(1); // 1 是通过插件开始录制, 0 是停止录制 function barControl(pthis){ ... case "record": if (m_livePlayOcx == null) { return; } if(!bLocalRecord){ ret = m_livePlayOcx.localrecord(1); if(ret != 0){ showMessage(getNodeValue('jsRecordFailed')); return; } bLocalRecord = 1; $('#record').addClass("record-enable"); $('#record').attr('title', getNodeValue('jsRecording')); }else{ stopLocalRecord(); } break; ... }
-
- 还是没看到网络交互,其实分析 "点击搜索本地文件" 的时间已经有预料到了是用插件来实现的。还是跟踪验证一下:
- 请求:?
规律总结
-
录像规律:
-
本地:
- 录像:在D:\Av\Video\ts\ 文件夹 里如果没有如 2024-01-25 文件夹就会新建一个,在该文件夹里 保存为168.1.96_20240125104709.mp4文件(前面必须要包含正确的ip 地址,这样搜索的时候才会搜索到如 20240125104709.mp4 文件)
- 搜索:在D:\Av\Video\ts\ 文件夹里搜索所有为 2024-01-25 创建的文件夹里面所有的 .mp4 和 .ts
- 注意:每个用户保存的录像目录如 D:\Av\Video\ts\ (默认为 C:/xxx) & 打包时间 & 打包类型 都不一样,所以应该把这些信息保存在浏览器
-
usb:
-
本文来自博客园,作者:封兴旺,转载请注明原文链接:https://www.cnblogs.com/fxw1/p/17987909