Kodi: Multi-client multi-profile configuration

One of the great things about Kodi is its ability to keep track of which videos/movies you have and have not watched and to even keep a note of how much of a particular video or movie you’ve watched. It does this by storing the relevant information in a SQLite database on the device. This is fine if you have just the one device or client. If however you have multiple devices and you watch a video on one of them the other device(s) will not know you have and it’ll remain unwatched on them. You’ll also not be able to pick up where you left off on that other device.

Another problem comes when you have other family members who use the same device to watch the same videos. Stuff they’ve watched will be marked as watched when you come to view it. You can get round this particular issue tho by using Profiles. So, you can set up a Profile for each family member and each can have their own library and thus watched-status database. Again tho, this is on a per device basis.

There’s a simple cure for the above and that is to use centralised databases. So, any family member can have their own library and can watch what they want on any device and they can pick up watching the same video where they left off on a different device. This is cool if for example you’re watching something in the sitting room and want to carry on watching it when you’re in bed.

This sounds pretty complicated to achieve, right? Well, actually it’s not. On previous versions of Kodi it used to be a pain but now it’s really quite trivial. So, here’s how you do it:

Install MySQL

First off you need to install MySQL. So, using Putty or by typing the commands in a Terminal session directly on our server let’s bring the Ubuntu Repository up to date:

sudo apt-get update

Next we’ll install MySQL

sudo apt-get install mysql-server

During the installation you will be prompted several times for a root password for MySQL. Leave it blank and select OK each time by hitting the TAB key on your keyboard to move to the OK button and then press Enter to continue.

Move MySQL Databases to a backed up location

By default MySQL will create the necessary databases in a folder called /var/lib/mysql. This location is not part of my RAID Array meaning it will not be automatically backed up. So I’ll change the location to somewhere that is. If you plan to back up the contents of this folder yourself you can skip this section.

So, first off let’s stop the MySQL service

sudo service mysql stop

Now let’s move everything to a location which does get backed up:

sudo mv /var/lib/mysql /media/WD40EFRX/RAIDMain

where /media/WD40EFRX/RAIDMain is the location which is part of my RAID Array.

Now let’s create a symlink pointing from /var/lib/mysql to this new location

sudo ln -s /media/WD40EFRX/RAIDMain/mysql /var/lib/mysql

As above, change /media/WD40EFRX/RAIDMain as required.

Nearly done. AppArmor is a piece of security software which stops undesirable access so we need to tell it what we’ve done.

sudo vim /etc/apparmor.d/usr.sbin.mysqld

Now press the [Insert] key once (to go into “edit” mode) and scroll down to the lines which read:

/var/lib/mysql/ r,
/var/lib/mysql/** rwk,

and add a # character to the beginning of each to mask these two lines out.

Next add these two lines below them:

/media/WD40EFRX/RAIDMain/mysql/ r,
/media/WD40EFRX/RAIDMain/mysql/** rwk,

obviously replacing /media/WD40EFRX/RAIDMain/mysql with your own location.

So, once you’ve finished your edits they should look like this:

#/var/lib/mysql/ r,
#/var/lib/mysql/** rwk,
/media/WD40EFRX/RAIDMain/mysql/ r,
/media/WD40EFRX/RAIDMain/mysql/** rwk,

Once you’ve made the change press the [Esc] key once and type the following:

:wq

This should save your changes and bring you back to the command line. If you make a mistake editing the file then issue :q! instead of :wq to abort your changes.

Next we’ll restart AppArmor:

sudo service apparmor restart

And lastly MySQL:

sudo service mysql restart

Configure MySQL for network access

By default MySQL will only listen for connections from the host itself. We need to be able to access MySQL from within our network. So, we need to make a simple change to a configuration file:

sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf

Now press the [Insert] key once (to go into “edit” mode) and scroll down to the line which starts bind-address. Change the address from 127.0.0.1 to be the IP address of your server. In my case it’s 192.168.1.200. So for me the line would be changed to read:

bind-address = 192.168.1.200

If you are using MySQL version 8.0 or later you also need to add the following line to the end of the file:

default_authentication_plugin=mysql_native_password

Once you’ve made the change press the [Esc] key once and type the following:

:wq

This should save your changes and bring you back to the command line. If you make a mistake editing the file then issue :q! instead of :wq to abort your changes.

You now need to restart MySQL to activate this change:

sudo service mysql restart

How to check MySQL has been configured for remote access

To check MySQL has been configured for remote access issue the following command:

sudo lsof -i -P | grep :3306

It should come back with something like the following:

mysqld 5431 mysql 10u IPv4 21218 0t0 TCP MyMediaServer.home:3306 (LISTEN)

How to access MySQL from the Command Line

Now we’ve installed MySQL and configured it for network access we need to create a User for our Kodi clients to use so it can store theses databases. So, let’s first launch MySQL:

mysql -u root -p

when you’re prompted for a password just press Enter (since we didn’t create a password). Next type the following:

CREATE USER 'kodi' IDENTIFIED WITH mysql_native_password BY 'kodi';

Now we’ve created the User call kodi we need to give it permissions to create and update stuff:

grant all on *.* to 'kodi';

Followed by

flush privileges;

Now let’s check this user has been properly configured:

show grants for 'kodi';

It should come back with something like this:

+--------------------------------------------------------------------------------------------------------------+
| Grants for kodi@% |
+--------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON . TO 'kodi'@'%' IDENTIFIED BY PASSWORD '*91D1AYHH1F88735' |
+--------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

Now we’re done we can quit from MySQL:

quit

How to connect to a Kodi Client from a remote machine

To configure Kodi to use MySQL we need to ssh onto it using Putty, the exact same way we access our server. We just need the IP address and you can determine what this is from the Kodi interface by going into SYSTEM and then System Info and the IP Address is shown on the Summary information screen. Enter this address into the Putty Configuration screen. The first time you connect you’ll see a PuTTY Security Alert dialog box. Just answer Yes to continue.

The username you need to use is root and the password is openelec.

Tell Kodi to use MySQL instead of the internal SQLite database

Now we’ve set up the MySQL side of things we need to configure the client side. If you have several Kodi clients or devices you’ll need to perform this step several times. My preferred method is to create the file on my server and then copy it across to each client.

If you’ve followed my Kodi Installation guide then SSH will already be enabled. If not then you can enable it from the Kodi client as follows: From the menu go into SYSTEM -> OpenELEC, scroll down to Services and check the Enable SSH option.

So, if you’re going to be doing this directly on your server issue the following command:

vim advancedsettings.xml

Alternatively, if you’ve connected to your Kodi client using Putty (see the screenshots here for tips on how to configure Putty) then issue this command instead:

vi /storage/.kodi/userdata/advancedsettings.xml

Once you’ve issued one of the above commands highlight the following code and then right-click on it and select Copy:

<advancedsettings>
    <videodatabase>
        <type>mysql</type>
        <host>192.168.1.200</host>
        <port>3306</port>
        <user>kodi</user>
        <pass>kodi</pass>
    <name>MasterVideo</name>
    </videodatabase>

    <musicdatabase>
        <type>mysql</type>
        <host>192.168.1.200</host>
        <port>3306</port>
        <user>kodi</user>
        <pass>kodi</pass>
    <name>MasterMusic</name>
    </musicdatabase>
    <videolibrary>
      <importwatchedstate>true</importwatchedstate>
      <importresumepoint>true</importresumepoint>
    </videolibrary>
</advancedsettings>

Now toggle over to the Putty session where you issued the above vi/vim command (which is either on your server or on the Kodi client) and press the [Insert] key once and add a couple of blank lines by pressing the [Enter] key. Next right mouse click and the whole script will be pasted into the screen. Delete any blank lines (although leaving them causes no harm)

Next press the [Esc] key once and type :wq to save and quit out of the file. If you make a mistake then issue :q! instead of :wq to abort your changes.

Copy the file over to the Kodi Client

If you created the above file on your server you now need to copy it across to each client. You can do this by issuing the scp command. Obviously, if you created the file directly on the Kodi client then you can skip this command:

scp advancedsettings.xml root@IPAddressOfKodiClient:/storage/.kodi/userdata/

where IPAddressOfKodiClient is the IP Address of the Kodi client. You’ll probably be asked if you wish to continue connecting. Type yes to continue and type the password for the Kodi client when prompted. The password is openelec

Now the file is on the Kodi client you need to reboot it for the changes to take effect:

reboot -h now

Alternatively you can reboot the Kodi client directly from the gui interface. It will take a little longer than usual to reboot the first time it sees this file. Now you just need to update the video/music libraries for Kodi to create the databases on the central MySQL server instead of creating them locally.

Kodi: Create Profiles for each user

Now we’ve told Kodi to store the media libraries centrally we will create Profiles for each user. This way each user will see only their library and only their watched-status flags. Furthermore they’ll be able to switch devices and continue watching where they left off. Obviously if you are the only user then you can skip this section.

You create new Profiles from the main Kodi menu: SYSTEM -> Profiles -> Add Profile. Give the Profile a name and add a Profile picture if required. Leave the Media info and Media sources options at the defaults (ie. Separate) and click OK to create the Profile. If you want to inherit the settings from the Master Profile then choose “Copy default” from the prompt that comes up. Similarly you can copy the media sources if required too. Note, this step copies the settings but does not actually import the libraries automatically.

Create a unique advancedsettings.xml file for each Profile

If you look at the advancedsettings.xml file above you’ll see we’ve specified a couple of name tags (<name>MasterVideo</name> for the video database and <name>MasterMusic</name> for the music database). Kodi uses these tags as the names of the MySQL video and music databases for the Master profile. So, it will create a video database called MasterVideo and a music database called MasterMusic.

Since we now have another user we need to specify unique names for the two databases for this new user. I tend to use the Profile name for this. So, if I created a Profile called ChildA I’d use the name tags <name>ChildAVideo</name> for the video database and <name>ChildAMusic</name> for the music database. So, my advancedsettings.xml file for ChildA would look like this:

 <advancedsettings>
    <videodatabase>
        <type>mysql</type>
        <host>192.168.1.200</host>
        <port>3306</port>
        <user>kodi</user>
        <pass>kodi</pass>
    <name>ChildAVideo</name>
    </videodatabase>

    <musicdatabase>
        <type>mysql</type>
        <host>192.168.1.200</host>
        <port>3306</port>
        <user>kodi</user>
        <pass>kodi</pass>
    <name>ChildAMusic</name>
    </musicdatabase>
    <videolibrary>
      <importwatchedstate>true</importwatchedstate>
      <importresumepoint>true</importresumepoint>
    </videolibrary>
</advancedsettings>

This advancedsettings.xml file has to be copied into the Profile directory for the user. So, for ChildA it would need to go into the /storage/.kodi/userdata/profiles/ChildA folder. So, you have two ways of achieving this:

1). Edit the file on your main server

  • vi advancedsettings.xml

    Press the [Insert] key once to switch into edit mode and change the name tags as required. Next press the [Esc] key once and type :wq to save and quit out of the file. If you make a mistake then issue :q! instead of :wq to abort your changes.
  • Now copy it across to the Kodi client using the following command:

    scp advancedsettings.xml root@IPAddressOfKodiClient:/storage/.kodi/userdata/profiles/ChildA

    replacing IPAddressOfKodiClient with the IP Address of the Kodi client and ChildA with whatever you’ve called this new user.
  • You can double-check the name using this command:
    ls -al /storage/.kodi/userdata/profiles/

Alternatively

2). Copy the file from one location on the Kodi client to the other and then edit it afterwards:

  • So, from the Kodi Client Putty session issue the following command to copy the file to the new location:

    cp /storage/.kodi/userdata/advancedsettings.xml /storage/.kodi/userdata/profiles/ChildA/

    changing ChildA to the name of the new user.
  • Now we want to edit this file for ChildA by updating the tags:

    vi /storage/.kodi/userdata/profiles/ChildA/advancedsettings.xml

    As above, press the [Insert] key once to switch into edit mode and change the name tags as required. Next press the [Esc] key once and type :wq to save and quit out of the file. If you make a mistake then issue :q! instead of :wq to abort your changes.

Repeat these steps for each additional user.

Once done you need to reboot the Kodi client for these changes to take effect:

reboot -h now

Activate the video/music resume function

By default Kodi will play videos/music from the beginning. You can change it so it plays where it left off. To do this from the Kodi interface go into Settings then Video then File Lists and set the Default select action to from Play to Choose.

Logoff current profile on suspend

When I’ve finished with my Kodi client and I hit the power button on the remote I’ve configured it to Suspend instead of Shutdown/Power Off. I do this for two reasons: firstly, so when I want to use it again it powers up very quickly and secondly because my remote doesn’t work if my NUC is powered off. If you only have one Profile set up then going into Suspend mode is not an issue. If however you have multiple Profiles then Kodi will resume on the menu it was previously on when you power it up again. This is no good if the person using it now is different to the one who was using it previously.

You can get Kodi to switch back to the login menu on resume by adding a simple script:

So, carry these steps out on the Kodi client. Let’s first make a new directory:

mkdir /storage/.config/sleep.d

Now switch into it:

cd /storage/.config/sleep.d

Now let’s create a simple script:

vim 01-reboot.power

Now highlight the following code and then right-click on it and select Copy:

#!/bin/sh
case "$1" in
  pre)
   systemctl restart kodi
   ;;
  post)
   ;;
esac

Now toggle back to your Kodi client and press the [Insert] key once to switch into edit mode and add a couple of blank lines by pressing the [Enter] key. Next right mouse click and the whole script will be pasted into the screen. Delete any blank lines (although leaving them causes no harm) and then press the [Esc] key once and type :wq to save and quit out of the file. If you make a mistake then issue :q! instead of :wq to abort your changes.

Now when you power down the Kodi client it’ll come back on the login menu.

In the above script many people put the systemctl restart kodi in the post) section but I’ve put it in the pre) section. Both achieve the same end result but having it in the post) section causes Kodi to power up where it left off and THEN logoff. I think this behaviour looks a bit naff personally but it’s down to personal preference. Either location works.

Kodi: How to enable suspend instead of Shutdown

From the Kodi client go into SYSTEM then Settings and scroll down to System. Scroll down to the Settings level and keep clicking OK on it until it changes to Advanced or Expert. Now scroll back up to Power saving and change the Shutdown function from Shutdown to Suspend.

Kodi boots before network is ready

Sometimes Kodi will boot before the network is ready meaning it’ll not be able to access the MySQL database and thus your music/video library. You can fix this quite simply by going into SYSTEM then OpenELEC from the menu. On the Network Screen under the Advanced Network Settings section set the Wait for network before starting kodi option to On