Kodi: Automatic display of IP cam after doorbell event

Topics (not sure which fora)
when not sure where to post, post here and mods will move it to right forum.

Moderators: leecollings, remb0

Post Reply
User avatar
philchillbill
Posts: 399
Joined: Monday 12 September 2016 13:47
Target OS: Linux
Domoticz version: beta
Location: Eindhoven. NL
Contact:

Kodi: Automatic display of IP cam after doorbell event

Post by philchillbill »

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:

Code: Select all

rtsp://username:[email protected]:554/Streaming/Channels/101
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

Code: Select all

npm install ping --save
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:

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));
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

Code: Select all

IPcamStreamFile = "smb://192.168.1.3//video/IPcams/driveway.strm"
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!
Alexa skills author: EvoControl, Statereport, MediaServer, LMS-lite
mojso
Posts: 92
Joined: Friday 08 November 2019 23:07
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Kodi: Automatic display of IP cam after doorbell event

Post by mojso »

the script works great, but can it switch from Pvr to camera and back to Pvr. Pvr stalker channel does not appear in the playlist
lastofthejediknights
Posts: 24
Joined: Tuesday 27 March 2018 14:17
Target OS: Raspberry Pi / ODroid
Domoticz version: 2021.1
Location: uk
Contact:

Re: Kodi: Automatic display of IP cam after doorbell event

Post by lastofthejediknights »

Hi,
Dumb question.
Where does the script go? on the domoticz installation device?

regards
mojso
Posts: 92
Joined: Friday 08 November 2019 23:07
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Kodi: Automatic display of IP cam after doorbell event

Post by mojso »

/home/pi/domoticz/scripts
lastofthejediknights wrote: Saturday 13 August 2022 16:34 Hi,
Dumb question.
Where does the script go? on the domoticz installation device?

regards
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest