Overview
Embedding video from a DW Spectrum system into a browser has many use cases - sharing a live stream of a part of a facility publicly, building an external interface for integrated products and more. Below is a step-by-step guide outlining a method of how to pull video from any DW Spectrum system and embed it in an external website.
Before you Begin...
For this example, we will use our public demo system:
- address: http://100.32.247.140:7001
- username: [email protected] (for demo purpose not active)
- password: DWDemoUser (for demo purpose not active)
- cameraId: ee6a353c-7de3-8c77-5869-1bbc33568a9f (How to find cameraId in your system).
CODE: JavaScript
var username = ' [email protected]';
var password = ' DWDemoUser ';
var cameraId = 'ee6a353c-7de3-8c77-5869-1bbc33568a9f';
var serverAddress = "http://100.32.247.140:7001";
Install the following libraries:
- MD5 generator: https://github.com/blueimp/JavaScript-MD5 (you can use any alternative library)
- HLS player: https://github.com/video-dev/hls.js/
CODE: HTML
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-md5/2.10.0/js/md5.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
Note: Security
- When you embed the video on a website - always create a dedicated user with limited permissions (ideally - only live viewing for specific public cameras)
- It is better to generate the link on server-side (backend) to avoid sending password with source code to the browser
Step 1: Authentication
To embed the video you need to use URL-based authentication. It works like this:
- request special session key from the server
- using that key and password generate an authentication key
- use this key in the URL
You can find detailed documentation here:
- Calculating a hash (demo/demo)
- Using it in URL: URL Authentication (demo/demo)
CODE: JavaScript
$.ajax({
url: serverAddress +"/api/getNonce",
type: "GET",
success: function (response) {
var realm = response.reply.realm;
var nonce = response.reply.nonce;
var digest = md5(username + ":" + realm + ":" + password);
var partial_ha2 = md5("GET" + ":");
var simplified_ha2 = md5(digest + ":" + nonce + ":" + partial_ha2);
var authKey = btoa(username + ":" + nonce + ":" + simplified_ha2);
callback(authKey); // This key can be used in URL now
}
});
In this example, we use the jQuery library to make API request and open source Javascript implementation of MD5.
Important note: The authentication key expires from time to time, so you cannot create a permanent video link. Make sure you generate it every time page opens.
Step 2: Generate a video link (cloud/local)
The recommended video format for embedding video is HLS. It does not require transcoding on the server side but works for h.264 cameras only (most cameras support this codec).
You can find detailed documentation here: (demo/demo)
CODE: JavaScript
var cameraURL = serverAddress + '/hls/' + cameraId + '.m3u8?lo&auth=' + authKey;
Step 3: Use player
HLS videos can be embedded to any modern browser using hls.js library: https://github.com/video-dev/hls.js/
CODE: JavaScript
var video = document.getElementById('video');
if (Hls.isSupported()) {
var hls = new Hls();
hls.loadSource(cameraURL);
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, function() {
video.play();
});
}
Technical limitations & overcoming them using DW Cloud
It is important to understand two limitations:
- The video will work only if the browser can reach the system. If you are using your server’s IP address - the video will not be accessible outside of the local network.
- If you embed the video on the secure website (using https) - requests might not work, because the browser doesn’t trust server’s self-signed certificate
To overcome both limitations you can use DW Cloud.
Detailed instruction can be found here
CODE: HTML
<video id="video" controls></video>
CODE: Javascript
var systemId = '3770508e-569a-423b-a61a-a85abb0ffff2';
var serverAddress = "https://" + systemId + ".relay.vmsproxy.com";
Putting it all together
CODE: HTML
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-md5/2.10.0/js/md5.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<video id="video" controls></video>
CODE: Javascript
var username = '[email protected]';\
var password = 'DWDemoUser';
var cameraId = 'a02d3776-a7eb-faea-97d5-6251c1694151';
var systemId = '3770508e-569a-423b-a61a-a85abb0ffff2';
var serverCloudAddress = "https://" + systemId + ".relay.vmsproxy.com";
var serverLocalAddress = "https://demo.networkoptix.com:7001";
var serverAddress = serverCloudAddress; // serverLocalAddress;
function step1GenerateKey() {
$.ajax({
url: serverAddress + "/api/getNonce",
type: "GET",
success: function(response) {
var realm = response.reply.realm;
var nonce = response.reply.nonce;
var digest = md5(username + ":" + realm + ":" + password);
var partial_ha2 = md5("GET" + ":");
var simplified_ha2 = md5(digest + ":" + nonce + ":" + partial_ha2);
var authKey = btoa(username + ":" + nonce + ":" + simplified_ha2);
step2GenerateVideoUrl(authKey); // This key can be used in URL now
}
});
}
function step2GenerateVideoUrl(authKey) {
var cameraURL = serverAddress + '/hls/' + cameraId + '.m3u8?lo&auth=' + authKey;
console.log(cameraURL); // this URL can be tested with VLC player for verification. VLC should not ask for additional credentials
step3InitPlayer(cameraURL);
}
function step3InitPlayer(cameraURL) {
var video = document.getElementById('video');
if (Hls.isSupported()) {
var hls = new Hls();
hls.loadSource(cameraURL);
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, function() {
video.play();
});
}
}
step1GenerateKey();