Kodi: Automatic display of IP cam after doorbell event
Posted: Thursday 15 August 2019 16:47
I've written a script in node.js that can be triggered on a doorbell event to automatically interrupt Kodi and show a live stream from e.g. your driveway IP cam for several seconds, before automatically reverting back to what was playing before the doorbell rang. No Kodi plugin is needed for this - it's all done with JSON RPC calls.
Kodi can play video playlist files which have a .strm file extension, so you can create a one-liner .strm file somewhere in your video library and add the rtsp url/path info for the camera you want to show briefly. For Hikvision, for example, the file can contain:
where the IP address, username, password and port apply to the IP camera in question (port is usually 554 for RTSP protocol). You can in fact just browse to this .strm file any time you like from the regular Kodi UI to 'play' the camera stream - the script here just automates that process.
I have Kodi installed on a dedicated machine (running LibreELEC) which the script quickly pings to decide whether the doorbell-interruption makes sense or not. If you don't want that then strip the pinging code from the script below. If you do want to ping so as to exit if the machine is down, then you will need to install a required npm package via in order to to use it. If your Kodi machine is always up then the ping will succeed anyway and things will still work as designed.
Here's the script:
If you use HTTPS instead of HTTP for Kodi access then change the require to HTTPS (no npm install needed). Note that the 2 second delay before the goto function gets called is needed as Kodi will not respond to Player.Seek immediately after starting a new playlist item. To debug your setup, verify that the .strm file plays normally from the Kodi UI first - if it does not work there then the script can't succeed either. In the example path to the stream file
you will need to use a path similar to the path to your normal video files as accessed by Kodi (in my example, using SMB protocol and on a remote Synology server at 192.168.1.3). Look at your library path in Kodi to see how to build this IPcamStreamFile path.
To trigger this script when the Domoticz-aware doorbell is pressed, add a script:// to the on-action for the switch in question.
Enjoy!
Kodi can play video playlist files which have a .strm file extension, so you can create a one-liner .strm file somewhere in your video library and add the rtsp url/path info for the camera you want to show briefly. For Hikvision, for example, the file can contain:
Code: Select all
rtsp://username:[email protected]:554/Streaming/Channels/101
I have Kodi installed on a dedicated machine (running LibreELEC) which the script quickly pings to decide whether the doorbell-interruption makes sense or not. If you don't want that then strip the pinging code from the script below. If you do want to ping so as to exit if the machine is down, then you will need to install a required npm package via
Code: Select all
npm install ping --save
Here's the script:
Code: Select all
/* eslint-disable func-names */
/* eslint-disable no-console */
// (c) philchillbill, 2019. No rights reserved
// Change the following SEVEN parameters to match your setup
const kodiIP = '192.168.1.5'; // IP address of kodi server on LAN
const kodiPort = '8080'; // port for HTTP control of Kodi
const authneeded = false; // set to true if your Kodi instance has password protection for HTTP access
const username = "kodiusername"; // only if the above is true
const password = "kodipassword"; // only if the above is true
const IPcamStreamFile = "smb://192.168.1.3//video/IPcams/driveway.strm"; // path to .strm file, here on different server
const showfor = 8; // number of seconds to show camera before reverting
//--------------------------------------------------------------------------------------------
// no more changes needed hereafter
const client = require('http');
const ping = require('ping');
if (authneeded) {
global.auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64');
global.reqheaders = { 'Authorization': auth, "Content-Type": "application/json" }
} else {
global.reqheaders = { "Content-Type": "application/json" }
}
const cfg = {
timeout: 1
};
ping.sys.probe(kodiIP, function(isAlive) {
if (!isAlive) {
console.log('Player ping failed, exiting');
process.exit()
}
}, cfg);
const apiKODI = function(query) {
return new Promise((resolve, reject) => {
var jbody = query
console.log('\n' + query)
var auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64');
const options = {
host: kodiIP,
port: kodiPort,
method: 'POST',
json: true,
path: '/jsonrpc?request=',
headers: reqheaders,
body: jbody
}
var req = client.request(options, (res) => {
var rbody = []
var response
res.on('data', (chunk) => {
rbody += chunk
});
res.on('end', () => {
try {
var result = JSON.parse(rbody).result;
response = result
global.responsive = true
} catch (e) {
console.log('apiKODI response body: ', rbody)
console.log('apiKODI error message: ', e)
response = {}
global.responsive = false
}
resolve(response)
})
});
req.on('error', (e) => {
console.error(e);
resolve(false) // e.message
});
req.write(jbody);
req.end()
})
};
const showcamera = async() => {
response = await apiKODI('{"jsonrpc":"2.0","method":"Player.GetProperties","params":{"playerid":1,"properties":["percentage"]},"id":"1"}')
global.percentage = response.percentage
if (responsive) { console.log(response) }
response = await apiKODI(`{"jsonrpc":"2.0","id":"1","method":"Playlist.Add","params":{"playlistid":1, "item":{"file":${IPcamStreamFile}}}}`)
if (responsive) { console.log(response) }
response = await apiKODI(`{"jsonrpc":"2.0","method":"Player.GoTo","params":{"playerid":1,"to": "next"},"id":1}`)
if (responsive) { console.log(response) }
response = await apiKODI(`{"jsonrpc": "2.0", "method": "Playlist.GetItems", "params": { "playlistid": 1}, "id": 1}`)
if (responsive) { console.log(response) }
global.tempitem = response.items.length - 1
}
const resume = async() => {
response = await apiKODI(`{"jsonrpc":"2.0","method":"Player.GoTo","params":{"playerid":1,"to": "previous"},"id":1}`)
if (responsive) { console.log(response) }
response = await apiKODI(`{"jsonrpc":"2.0","id":1, "method":"Playlist.Remove","params":{"playlistid":1,"position": ${tempitem}}}`)
if (responsive) { console.log(response) }
response = await apiKODI(`{"jsonrpc": "2.0", "method": "Playlist.GetItems", "params": { "playlistid": 1}, "id": 1}`)
if (responsive) { console.log(response) }
return setTimeout(goto, 2000);
}
const goto = async() => {
response = await apiKODI(`{"jsonrpc":"2.0","id": 4,"method":"Player.Seek","params":{"playerid":1 ,"value":{"percentage": ${percentage}} } }`)
if (responsive) { console.log(response) }
}
showcamera()
setTimeout(resume, Number(showfor * 1000));
Code: Select all
IPcamStreamFile = "smb://192.168.1.3//video/IPcams/driveway.strm"
To trigger this script when the Domoticz-aware doorbell is pressed, add a script:// to the on-action for the switch in question.
Enjoy!