{"id":13583724,"url":"https://github.com/hawkeye64/onvif-nvt","last_synced_at":"2025-06-13T17:07:20.634Z","repository":{"id":47011589,"uuid":"121017687","full_name":"hawkeye64/onvif-nvt","owner":"hawkeye64","description":"ONVIF library for NVT (Network Video Transmitter) devices.","archived":false,"fork":false,"pushed_at":"2023-04-10T23:43:19.000Z","size":24438,"stargazers_count":76,"open_issues_count":37,"forks_count":23,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-05-22T15:16:18.050Z","etag":null,"topics":["camera","ipcamera","javascript","nvt","onvif"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hawkeye64.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"docs/Security.html","support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"github":["hawkeye64"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2018-02-10T13:29:17.000Z","updated_at":"2024-07-27T20:16:53.000Z","dependencies_parsed_at":"2024-01-24T13:06:45.601Z","dependency_job_id":null,"html_url":"https://github.com/hawkeye64/onvif-nvt","commit_stats":{"total_commits":349,"total_committers":11,"mean_commits":"31.727272727272727","dds":"0.20343839541547282","last_synced_commit":"9026ce08d7b0c73bc519035492e98390b574580c"},"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"purl":"pkg:github/hawkeye64/onvif-nvt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hawkeye64%2Fonvif-nvt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hawkeye64%2Fonvif-nvt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hawkeye64%2Fonvif-nvt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hawkeye64%2Fonvif-nvt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hawkeye64","download_url":"https://codeload.github.com/hawkeye64/onvif-nvt/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hawkeye64%2Fonvif-nvt/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259686088,"owners_count":22896051,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["camera","ipcamera","javascript","nvt","onvif"],"created_at":"2024-08-01T15:03:43.848Z","updated_at":"2025-06-13T17:07:20.589Z","avatar_url":"https://github.com/hawkeye64.png","language":"JavaScript","funding_links":["https://github.com/sponsors/hawkeye64"],"categories":["JavaScript"],"sub_categories":[],"readme":"[![license](https://img.shields.io/github/license/hawkeye64/onvif-nvt.svg)]()\n[![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/hawkeye64/onvif-nvt.svg)]()\n[![GitHub repo size in bytes](https://img.shields.io/github/repo-size/hawkeye64/onvif-nvt.svg)]()\n[![npm](https://img.shields.io/npm/dt/onvif-nvt.svg)](https://www.npmjs.com/package/onvif-nvt)\n\n[![CircleCI](https://img.shields.io/circleci/project/github/hawkeye64/onvif-nvt.svg)](https://circleci.com/gh/hawkeye64/onvif-nvt)\n[![Coveralls github](https://img.shields.io/coveralls/github/hawkeye64/onvif-nvt.svg)](https://coveralls.io/github/hawkeye64/onvif-nvt?branch=master)\n[![David](https://img.shields.io/david/hawkeye64/onvif-nvt.svg)](https://david-dm.org/hawkeye64/onvif-nvt)\n[![David](https://img.shields.io/david/dev/hawkeye64/onvif-nvt.svg)](https://david-dm.org/hawkeye64/onvif-nvt#info=devDependencies)\n\n[![Known Vulnerabilities](https://snyk.io/test/github/hawkeye64/onvif-nvt/badge.svg?targetFile=package.json)](https://snyk.io/test/github/hawkeye64/onvif-nvt?targetFile=package.json)\n[![Greenkeeper badge](https://badges.greenkeeper.io/hawkeye64/onvif-nvt.svg)](https://greenkeeper.io/)\n\n# onvif-nvt\n\nONVIF library for NVT (Network Video Transmitter) devices.\n\nThis package is written with Javascript classes and ES6. Both Promises and Callbacks are supported. _Note_: Even though callbacks are supported, if you pass parameters incorrectly, you might end up getting a Promise back.\n\nThe ultimate goal of the **onvif-nvt** package is to have as much complete coverage of the [ONVIF](https://www.onvif.org/) spec as possible.\n\nThe `onvif-nvt` package will work only with `node` server-side if you want to use the `discovery` module. Ultimately, you would use sockets to communicate between a client and server the desired ONVIF commands. However, if you do not want to use the `discovery` module, you can use the `onvif-nvt` package in either client or server as well as electron (main and renderer processes).\n**Note**: The reason the `discovery` module will not work on the client is that browsers removed UDP support some time ago and the discovery service for ONVIF devices uses this protocol.\n\n## Installation\nNote: This is an active project, and while so, there will be many updates. PRs are welcomed.\n\n```npm install onvif-nvt```\n\n## Sample Application\nYou can find the sample application that uses Vue and Quasar [here](https://github.com/hawkeye64/onvif-nvt-snapshot-vue-sample).\n\n## Contributing\nBefore making a PR please do the following:\n* Make sure you are consistent with style.\n* \u003ci\u003enpm run lint-fix\u003c/i\u003e\n* Make sure you have updated any functionality with JSDoc notations.\n* \u003ci\u003enpm run jsdoc\u003c/i\u003e\n* Make sure you have added to \u003ci\u003erun\u003c/i\u003e tests (live testing).\n* If you have a specific camera not identified, create a folder for it in `test/data/xml/{camera}`. Create configuration data for it in `run.config.js`. Run all \u003ci\u003erun\u003c/i\u003e tests with `saveXml.setWritable(true)` (in `run.js`) and capture all the xml.\n* Make sure you have added to \u003ci\u003ejest\u003c/i\u003e tests (uses the aforementioned xml). Update `test/config.js` with your camera.\n* \u003ci\u003enode run/run.js\u003c/i\u003e\n* \u003ci\u003enpm run test\u003c/i\u003e\nIf all is well, make the PR.\n\n## Available Functionality\n* Core (Device)\n  * Discovery Mode, Device Information, System Date and Time, Scopes, Services, Capabilities, ServiceCapabilities, DNS, Network, Reboot, Backup, Restore, GeoLocation, Certificates, Relay, Remote User and many more.\n* PTZ\n  * Nodes, Configuration, Absolute move, Relative move, Continuous move, Geo move, Stop, Status, Presets, Home Position, and Auxillary Commands.\n* Media\n  * Profiles, Video/Audio/PTZ/Analytics/Metadata Configurations, Video sources, Audio sources, Stream Uri, Snapshot Uri, Multicast, and OSD.\n* Snapshot\n  * Using the **snapshot** module, you can retrieve snapshots from the device.\n* Other modules (not implemented)\n  * Access, Access Rules, Action, Analytics, Credential, DeviceIO, Display, Door, Events, Imaging, Media2, Receiver, Recording, Replay, Schedule, Search, Security, Thermal and Video Analytics.\n\nThe library is made in such a way that only modules that will work with your device are automatically included. For others, you can choose whether or not to bring in the functionality.\n\n## Proxy Support (added 0.2.9)\nProxy support has been added.\n\n## Example (Discovery)\n``` cs\nconst OnvifManager = require('onvif-nvt')\nOnvifManager.add('discovery')\nOnvifManager.discovery.startProbe().then(deviceList =\u003e {\n console.log(deviceList)\n // 'deviceList' contains all ONVIF devices that have responded.\n // If it is empty, then no ONVIF devices\n // responded back to the broadcast.\n})\n```\n\n## Example (Connect and Continuous Move)\n``` cs\nconst OnvifManager = require('onvif-nvt')\n// OnvifManager.connect('localhost/my/proxy/path', null, 'username', 'password') \u003c-- proxy path\nOnvifManager.connect('10.10.1.60', 80, 'username', 'password')\n  .then(results =\u003e {\n    let camera = results\n    if (camera.ptz) { // PTZ is supported on this device\n      let velocity = { x: 1, y: 0 }\n      camera.ptz.continuousMove(null, velocity)\n        .then(() =\u003e {\n          setTimeout(() =\u003e {\n            camera.ptz.stop()\n          }, 5000) // stop the camera after 5 seconds\n        })\n    }\n  })\n```\n\n## Example (Snapshot)\n``` cs\nconst OnvifManager = require('onvif-nvt')\n// OnvifManager.connect('localhost/my/proxy/path', null, 'username', 'password') \u003c-- proxy path\nOnvifManager.connect('10.10.1.60', 80, 'username', 'password')\n  .then(results =\u003e {\n    let camera = results\n    // calling add method will automatically initialize snapshot\n    // with the defaultProfile's snapshotUri\n    camera.add('snapshot')\n    camera.snapshot.getSnapshot()\n      .then(results =\u003e {\n        let mimeType = results.mimeType\n        let rawImage = results.image\n        let prefix = 'data:' + mimeType + ';base64,'\n        let base64Image = Buffer.from(rawImage, 'binary').toString('base64')\n        let image = prefix + base64Image\n        // 'image' is now ready to be displayed on a web page\n        // ...\n      })\n    }\n  })\n```\n\n## Example (Events)\nPullMessages now works with Hikvision, TrendNET and Pelco. They are not working with Axis.\n``` cs\nconst OnvifManager = require('onvif-nvt')\n// OnvifManager.connect('localhost/my/proxy/path', null, 'username', 'password') \u003c-- proxy path\nOnvifManager.connect('10.10.1.60', 80, 'username', 'password')\n  .then(results =\u003e {\n    let camera = results\n    // if the camera supports events, the module will already be loaded.\n    if (camera.events) {\n      camera.events.on('messages', messages =\u003e {\n        console.log('Messages Received:', messages)\n      })\n\n      camera.events.on('messages:error', error =\u003e {\n        console.error('Messages Error:', error)\n      })\n\n      // start a pull event loop using defaults\n      camera.events.startPull()\n\n      // call stopPull() to end the event loop\n      // camera.events.stopPull()\n    }\n  })\n```\n\n## Documentation\n[onvif-nvt documentation](https://hawkeye64.github.io/onvif-nvt/)\n\n## Testing\nNote: The code for testing is not available in the npm package.\n\nAll functionality has been tested with Hikvision (fixed and ptz), Pelco (ptz), TrendNET (fixed) and Axis (ptz).\n\n### Functional Testing\nFunctional testing is intended for 'live' testing with an actual ONVIF device. It is done with the `run.js` in the `run` folder. This will test the actual capabilities of a camera, but just as importantly, it can capture the xml response to file so it can be used in Jest tests. The configuration file for the `run` tests can be found in `run/config.js`.\n\nFor **discovery** testing, just set the `runDiscovery` variable at the top of the file to `true`.\n\nFor **core** testing, set the `runCore` variable at the top of the file.\n\nYou can do this for other modules as well. See file for options.\n\nSet up your local camera by setting the appropriate variables in `run/config.js`, like this:\n```\nconst address = '10.10.1.60'\nconst port = 80\nconst username = 'root'\nconst password = 'root'\nconst folder = 'hikvision'\n```\nRun the `run.js` file via node (personally, I use VS Code - an amazing editor/debugger).\n\nThe tests will only run onvif modules supported by the camera capabilities, so if it doesn't support PTZ, then the PTZ tests won't be run. Same for other modules.\n\nYour mileage may vary as I have found some ONVIF devices don't support very basic functionality, like `GetSystemDateAndTime`. In some cases, you might get a response back of `Action not supported`. If this happens, then the tests will fail. This is nothing to be alarmed about. You may also get other errors. The most common I see is if your camera does not support audio configurations. Also, you may get a `Not Implemented` error, meaning the implementation of that method has not yet been added.\n\n### Automated Testing\n**Jest** is being used to do the automated testing and code coverage. All tests are in the `tests` folder, as well as XML Requests and Responses from various ONVIF devices.\nTo start the tests, run the following:\n```npm run test```\n\nInside the `test` folder is a `config.js` file where you can set options for the tests.\n\n## Request\n`onvif-nvt` uses `request` for device communication. Some people may believe this is too *heavy* of a package and that *http* should be used instead. `request` works quite well with HTTP digest and digest realm scenarios. In a lot of cases, this is needed for `snapshot` access. However, I am finding some ONVIF devices that allow you to turn on HTTP security (besides the ONVIF user token security) which provides a double layer (albeit, with the same username and password). It is these cases where `request` *just works*.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhawkeye64%2Fonvif-nvt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhawkeye64%2Fonvif-nvt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhawkeye64%2Fonvif-nvt/lists"}