GuilhermeC18 / node-onvif

The node-onvif is a Node.js module which allows you to communicate with the network camera which supports the ONVIF specifications.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

name space handling (xmlns:)

peebles opened this issue · comments

I think this library suffers from the same problem that onvif had; namely that when the camera is sending xmlns: name spaces with all of its elements, the xml to json parser is not doing the right thing. My camera outputs something like this:

<tt:Uri xmlns:tt="http://www.onvif.org/ver10/schema">http://169.254.72.162:8081/web/snapshot.jpg</tt:Uri>

Which produces json that looks like this:

    "snapshot": {
      "_": "http://169.254.72.162:8081/web/snapshot.jpg",
      "$": {
        "xmlns:tt": "http://www.onvif.org/ver10/schema"
      }
    },

If I apply the same "fix" as described in the linked ticket, namely:

soap = soap.replace(/xmlns(.*?)=(".*?")/g,'');
mXml2Js.parseString(soap, opts, (error, result) => {
...
});

in lib/modules/soap.js::parse(), then the problem goes away and I get this json:

    "snapshot": "http://169.254.72.162:8081/web/snapshot.jpg",

I realize this is just how xml2js works, but higher level apps (like samples/manager) break when the camera is sending xmlns:

In soap.js, the current code looks like:

OnvifSoap.prototype.parse = function(soap) {
        let promise = new Promise((resolve, reject) => {
                let opts = {
                        'explicitRoot'     : false,
                        'explicitArray'    : false,
                        //'ignoreAttrs'      : true,
                        'ignoreAttrs'      : false,
                        'tagNameProcessors': [function(name) {
                                let m = name.match(/^([^\:]+)\:([^\:]+)$/);
                                return (m ? m[2] : name);
                        }]
                };
          mXml2Js.parseString(soap, opts, (error, result) => {

If you change 'ignoreAttrs' back to true, then this problem with $ and _ goes away. I wonder why the value was changed ...

Thank you for your feedback.

I've suspected the explicitArray parameter for now though I'm not sure. Anyway, I think that the parameter causes some issues.

I'm planning to change the explicitArray from false to true. But changing the value has a much greater impact on other codes. That will take a little bit long time.

Unfortunately, I don't have enough time for this project now. Give me some time.

I misunderstood this issue. Now I understand what is problem.

As you advised, it seems that the xml2js returns different results depends on where a namespace (xmlns) are described in a XML. The node-onvif does not handle the behavior of the xml2js for now.

If you don't mind my asking, could you give me the manufacturer name and the model name of the network camera you have? If it is affordable and available in Japan (where I live), I will buy and try it.

I built it myself, using: https://github.com/BreeeZe/rpos

I should note that Open Device Manager Windows and Linux as well as a commercial vendor onvif client can see this camera and manipulate it.

Wow, you built it by yourself! Great! I'll try it soon.

I installed the rpos on my Raspberry Pi 3 Model B+ with a camera module v2. It worked fine though I don't have the PiMoroni PanTiltHAT.

You advised a solution:

soap = soap.replace(/xmlns(.*?)=(".*?")/g,'');
mXml2Js.parseString(soap, opts, (error, result) => {
...
});

This solution would solve this issue comprehensively, but all namespace information would be removed from responses of the low-level methods. Some users might expect that namespace information is included in a response. So I focused only on the high-level methods.

I improved the OnvifDevice.getUdpStreamUrl() and the OnvifDevice.fetchSnapshot() method. Now these methods work well with the rpos.

Thank you.