海康视频设备onvif 快照数据获取

当前因为一些历史原因,不少onvif 的包都比较老,同时不少设备因为安全问题对于部分数据的处理进行了调整,造成实际处理上不太兼容, 或者不能使用

onvif 快照问题

默认支持的路径类似如下onvif-http/snapshot?Profile_1 实际上还有一个ISAPI 协议的ISAPI/Streaming/channels/1/picture 但是安全处理上并不是简单的basic auth,而是digest 模式的

解决方法

可以自己基于digest 模式进行数据处理,或者就是通过一些不错的三方包解决,比如digest-fetch

参考使用

  • 示例代码
const DigestClient = require("digest-fetch");
const fs = require("fs");

const client = new DigestClient("xxxx", "xxxxxxx");

client
  .fetch("http://xxxxxx/onvif-http/snapshot?Profile_1")
  .then((res) => res.buffer())
  .then((buffer) =>
    fs.writeFile("./demo.jpg", buffer, (err) => {
      if (err) throw err;
      console.log("File saved!");
    })
  );

  • onvif 包装

如果使用的node-onvif ,一个简单的在ptz 之后然后进行快照获取

const onvif = require('node-onvif');
const DigestClient = require("digest-fetch");
const fs = require("fs");
// Create an OnvifDevice object
let device = new onvif.OnvifDevice({
 xaddr: 'http://xxxxxx/onvif/device_service',
  user : 'xxxxxx',
  pass : 'xxxxxxxx'
});
 
device.init().then(() => {
  return device.ptzMove({
    'speed': {
      x: 0, // Speed of pan (in the range of -1.0 to 1.0)
      y: 0, // Speed of tilt (in the range of -1.0 to 1.0)
      z: 0.0 // Speed of zoom (in the range of -1.0 to 1.0)
    },
    'timeout': 3 // seconds
  });
}).then(() => {
  console.log('Done!');
  // 获取profile 的snapshot 地址,然后使用DigestClient
  let snapshot_url = device.getCurrentProfile().snapshot;
  console.log("snapshot_url",snapshot_url);
  const client = new DigestClient("fengshuo", "111...aaa");
  client
  .fetch(snapshot_url)
  .then((res) => res.buffer())
  .then((buffer) =>
    fs.writeFile("./demov1.jpg", buffer, (err) => {
      if (err) throw err;
      console.log("File saved!");
    })
  ).catch((error) => {
    console.error(error);
  });
}).catch((error) => {
  console.error(error);
});

说明

当前onvif 的不少协议版本sdk 都比较老了,对于一些包推荐还是自己处理下,或者自己fork 修复

参考资料

https://github.com/devfans/digest-fetch

https://github.com/sxiii/node-onvif

posted on 2025-10-28 08:00  荣锋亮  阅读(5)  评论(0)    收藏  举报

导航