DVBLink 6.0.0 Recordings Database Repair Utility

System Requirements:

  • DVBLogic, DVBLink 6.0.0
  • Windows Scripting Host

The Problem:

DVBLink is a good product which works across a large number of platforms, and, considering how complex it is, it does a good job of interfacing between DVB-T/DVB-S terrestrial TV transmissions and the on-demand world of modern media consumption.

I’ve always had a few niggles with the system (‘clear data’ in Kodi anyone?), but have always found it good, save for one area. It’s recording database mechanic is at best flimsy and at worst out-right fragile.

The number of database corruptions, anomalies and times I have had to restore the database form backup in essence amount to every 6 months. It can be caused by a service crash, the PC restarting without a clean shutdown (power cut), loss of visibility of the disk where the recordings folder target sits (e.g. USB drive, iSCSI recording storage on a SAN/NAS or any other ejectable media) or as a result of installing a DVBLink update (I had a v5 update that trashed my recordings database about 2 months after I first started using it).

To provide a simple summary of the issues with the SQLlite database implementation:

  1. If the database is lost, that’s it. DVBLink/Kodi etc cannot ‘see’ your recordings, they are lost to the software even though they are still physically on disk and if you know where to look and how to open them, they remain watchable.
  2. Some failure situations can lead the database to have more in it than the file system does. This leads to the Kodi ‘click of nothing’, where clicking an item in the recordings section does just that, nothing (no error, just nothing)…
  3. … DVBLink has an option in the server settings to perform a consistency check. This is supposed to fix the ‘I have a database record but no file issue’… yet in reality, in my experience, this far too complicated and (I would assume) tries to be cleverer than asking “is there a recordings file on disk for this recording entry in the database?”. If you have ever tried to manually reconstruct the database with this option on, you’ll know that DVBLink simply deletes the entry…
  4. … Some failure situations – and the DVBLink provided consistency checking option – can lead the database to not have entries for recordings that do exist in the file system. Referring back to #1, you’ll recall that this means that DVBLink/Kodi etc does not know that they exist and you cannot watch the recordings. Equally there is no way to delete the orphaned files as they are not reported. Consequently your DVBLink system will slowly leak disk space. This is made worse by the fact that the database appears to track deletions, but doesn’t appear to have a (working) mechanism to restore the records again.
  5. There is no way to automatically recover from these situations.
  6. Once in these situations, there is no way to recover lost meta data on recording files that are orphaned in the recordings directory.

When a family member with a large pre-existing recording catalogue went away on 22nd December, returned on the 29th December to find that

  1. The old catalogue was no longer showing in Kodi
  2. No new programme recorded before 27th December was present

There were plenty of tears before bedtime.

Due to a connectivity problem between the DVBLink service and the recorder disk on the 27th, DVBLink had restarted and decided that as it couldn’t find the recordings folder, it would delete the now missing content form the recordings database.

It started recording from the 27th onwards onto the tiny local SSD that the OS is installed onto as a fail back (fair dues here DVBLink, good move), but come the 29th there were only 6 things (new content from the 28th and 29th) in the database. There should have been around 70 recordings.

There was no database backup available later than 12th December (by luck, I had made one on the 12th). There was no automatic database backup later than October.

More Info

I now needed to merge the 12th December backup and the 27th December+ master database back together. This would leave a data gap from 13th-26th December of missing records, so having done this in a SQLLite GUI editor, I started the DVBLink back up and… it promptly deleted 85% of all the material introduced from the 12th December backup.

The mystery of the database reconciliation option strikes again. By checking that all of the filenames in the database, I confirmed that the files were on the disk, including the thumbnails, but it decided to delete the imported old records anyway. Just not all of them for an unknown reason.

I turned off the reconciliation option and repeated the merging process again, and, it worked. The files played back in Kodi. I just cannot enable the database reconciliation feature. Ever.

At this point I turned my attention to the missing 13th-26th period. The file system revealed that this amounted to some 14 recordings. At this point I noticed one slight problem. I was expecting to be recovering around 70 files into the database, yet there were over 180, large, playable .ts files in the recording folder consuming some 360 GB of disk space. These files covered a period starting in April 2015 through to 29th December 2017.

Looking non-exhaustively at very old database backup files, I was able to find several of them, proving that they had at one point existed and had not been deleted by the user, but by the database consistence checked/reconciler. This posed the following chain of problems:

  1. If I import the contents of all of the old database backups that I have, I will be importing a mass of junk data.
  2. If I turn on the automatic (and unreliable) consistency checker to clean that up, I will wind up deleting all of the work thus far and likely only be a couple of steps further forward.
  3. I still have not solved the problem of the completely missing 13th December 2017 – 26th December 2017 database records.

I thus decided to write some code and use programming to help solve the problem. Thus the DVBLink_RecordingsDb Maintenance API was created. The API allows you to view:

  • All files in the file system
  • All records in the database
  • All files in the file system that are not in the database
  • All records in the database for which there is no associated file in the file system

In turn it allows you to:

  • Remove entries in the database where the is no resultant file (using no other logic beyond is the correct .ts file presence e.g. the presence of a valid recording timer entry in the database to test validity is not used).
  • Add entries to the database where there is a file in the file system but no existing database entry. The tool will attempt – i.e. best effort – to populate a new database record with the minimum amount of information necessary to allow DVBLink/Kodi to play the file. This is largely based upon the file name and spoofing channel data.
  • Repair file play length information.
  • Scan for an eliminate any duplicate records found in the database

System Requirements

The computer running the tool must:

  • Windows / Windows Server
  • Have the SQLite ODBC Drivers installed (use x86 or x64 depending on your platform)
    Download: http://www.ch-werner.de/sqliteodbc/
  • Be able to access the dlrecorder.db database file as a file system mount (e.g. a direct drive mount, SMB, NFS etc) – under Windows this is in “C:\Users\Public\Documents\DVBLink\dlrecorder.db” by default.
  • Be able to access the recordings folder (the folder where DVBLink writes .ts recording files) as a system mount – under Windows this is in “C:\Users\Public\Documents\DVBLink\recorded” by default.


To run the code you must be running Windows and ensure that you install the correct SQLite ODBC driver first

  1. Make a manual backup of your dlrecorder.db file. This is found at “C:\Users\Public\Documents\DVBLink\dlrecorder.db”
    Note: If you do not make a backup of the database file and something goes wrong, you will at best lose meta data and at worst lost recordings. Don’t risk it, make a backup!
  2. Download and fully extract the zip file using the link below
    Note: Do not run the programme directly from the zip file
  3. Edit the config.vbs file in notepad or your preferred text editor
  4. Set the DB_PATH variable to the file system path of the dlrecorded.db file used by your DVBLink install. The default is provided
    CONST DB_PATH = “C:\Users\Public\Documents\DVBLink\dlrecorder.db”
  5. Set the RECORDINGS_PATH variable to the file system path of the recorded folder where DVBLink records .ts files. The default is provided
    CONST RECORDINGS_PATH = “T:\DVBLink\recorded”
  6. Save and close the config.vbs file
  7. Double click on the DVBLink_RecordingsUtility.wsf file to start the utility

Repair Utility Screenshot


You can download the DVDLink Recordings Utility below. The code is © C:Amie. Please do not redistribute this file, please link them to this page.

No warranty is offered of implied for using the code, nor loss of data/recordings from your DVBLink database. Please ensure that you make a backup of the DVBLink database before using the tool.

Taking all necessary precautions, use this tool at your own risk.

The tool has been tested on DVBLink 6.0.0 under Windows 10 1709.

If you found this tool useful, please consider donating towards the running costs of this site.

Download: DVBLink_RecordingsTool-1.0.0.zip (8.37KB)

Issues / Ideas

If you have any issues or ideas on how the tool can be made to be more useful, please get in touch.

A thought for the DVBLink team

If anyone from the DVBLink team sees this, I really like what you do – it is a great product, it just has a weak link at the moment. I appreciate fully that you are using SQLlite for search and interrogation performance reasons. You could however fairly easily eradicate these problems by:

  1. Adding granular control to the database consistency checker so that it isn’t so brutal – have whatever mode it currently exists in as an level 2 option and just set a test for the presence of the file in the file system as the level 1 option.
  2. Write an XML/JSON file into the file system with the same name as the recording .ts file or the .jpg thumbnail file. Keep all of the meta data on the recording in here as well as the database. This allows you to implement file portability. With this in place, the consistency checker can be easily re-written to check whether the .ts file has a meta data file too. If it finds a .ts file that it doesn’t know about that does have a meta data XML/JSON file, simply import the file into the database. The database consistency checker algorithm can do this itself on service start/periodically.

If you do that you have several new features:

  1. Portability of recordings without transcoding.
  2. Recording export/import.
  3. An easy, end-user achievable, self-service recovery path from outdated backups with a process that is simple to write up in a knowledge base article.
  4. Significantly less risk / reliance on the integrity of the database. Plus reassurance for you that there is significantly less likelihood that users like me will feel compelled to poke around in the database in the first place.
  5. Support for removable recording targets – when a disk is missing the database is cleared, when it comes back the recordings appear in the database again.
  6. An easy way to report to the user that there are genuinely orphaned files because there is a .ts file with no meta data.
  7. Users can drop in their own .ts file and write their own meta data XML/JSON file for it in a text editor using your schema (also allowing import from competitor products).
  8. A more robust database and file consistency checker / scavenger.
  9. Preservation of disk space use for the user, something that as I have outlined here, seems to leak over time.

Script to split single file multiple contact VCF file into individual VCF files for each included contact (Import Android Contacts Export file into Microsoft Outlook)

System Requirements:

  • Windows Scripting Host 5.6 or higher
  • Windows 95, NT 4, 98, 98SE, ME, 2000, XP, Vista, 7, 8, 8.1, 10
  • Windows Server NT 4, 2000, 2003, 2003 R2, 2008, 2008 R2, 2012, 2012 R2, 2016

The Problem:

I did an export from the People / Contacts on Android which produced a single .VCF vContact file for all of the contacts. On attempting to import it into Outlook, Outlook ignored all but the first entry in the file.

Additionally, you may not want to import all of the contacts in the monolithic VCF.

The Fix

The VB Script file below will take the .VCF file and split it into individual .VCF files, one for each contact.

The script will create a sub-directory in the same folder that the script is executed from and all of the new .vcf files will be placed in here using the name of the user.


  • No warranty is offered or implied for the use of this script. No liability is inferred for damages caused as a result of its use. Use it at your own risk
  • You may use the script for free for personal use
  • You may not redistribute this script. If you want to link to it, please link to this page.

Download: SplitVCard version 1.0.1 (2.57 KB)

Usage Instructions

You can either drag and drop the monolithic VCF file onto the SplitVCard.vbs file in Windows Explorer or use the command line syntax as follows to specify the path of the source file.

cscript.exe SplitVCard.vbs “C:\Bla\Bla\Bla\Contacts.vcf”

Release history

1.0.0 – 21/11/2016. Initial release

1.0.1 – 22/06/2017. Added some additional illegal character protections when writing individual files back to the file system for ?, / and \ characters


As this is a VB Script file, the naming conventions are currently only setup for ASCII. If you wanted to use Unicode or another encoding, you will need to edit the script.

Script to convert from an online bank downloadable CSV file to Microsoft Money to Quicken compatible QIF (Specifically Metro Bank)

System Requirements:

  • Windows 95, 98, 98SE, Millennium, NT 4, 2000, XP, Vista, 7, 8, 8.1, 10
  • Windows NT 4 Server, Windows 2000 Server, Windows Server 2003, 2008, 2008 R2, 2012, 2012 R2, 2016
  • Windows Scripting Host 5.1 or higher

The Problem:

Having just moved banks, my previous provider offered downloadable QFX files which allowed me to import them into Microsoft Money. The new provider – Metro Bank UK – does not offer a QFX or QIF download service to automate the transaction import process. Instead that only offer a very limited snapshot view which downloads in a simplified CSV structure.

If like me, you are put out by the idea of having to manually enter your transactions into your finance package then this could help.

More Info

The Metro Bank UK CSV structure is extremely simple [as of September 2016]. The header format is as follows:

Date Reference Transaction Type Money In Money Out

The file does not contain sufficient information to permit the use of the QFX format, which is required to track the ledger date range and starting and end totals. While it is possible to track the date range, there is no information on the ledger start and end total to validate the import process against.

This means that the best that we can hope for is to use the far less intelligent QIF format. The principle issue that this causes is that your financial programme will likely attempt to import duplicates off of the file and you will need to be vigilant of controlling or editing the on-line bank export date range to minimise duplication. This is the case with Microsoft Money 2005 anyway.

The Fix

I have created a script that converts from the Metro Bank UK CSV download file and into the QIF format.

  • No warranty is offered or implied for the use of this script. No liability is inferred for damages caused as a result of its use. Use it at your own risk
  • You may use the script for free for personal use
  • You may not redistribute this script. If you want to link to it, please link to this page.

Download: CsvToQif version 1.0.0 (2.57 KB)

Usage Instructions

You can use the script in one of two ways:

  1. Using the mouse, drag and drop the .CSV file onto the script file icon.
  2. Using the command prompt:
    “<PathToFile>\CsvToQif.vbs” “<PathToFile>\Transaction_24.09.2016.csv”
    “C:\Users\MyName\Documents\QiFConverter\CsvToQif.vbs” “C:\Users\MyName\Desktop\Transaction_24.09.2016.csv”

In both cases, after a few moment, a .QIF file of the same name will appear in the same folder. Hit F5 to refresh if you do not see it. Import it either by selecting the import function in your finance program or if applicable double click the QIF file and follow the on-screen instructions.

If you want to use it with a different CSV layout, for example your own file or that of a different online bank provider. You will need to adjust the zero-based array indexes at around line 148 to reflect the correct columns.

For example, arrCsv(0) is the first column in the CSV, arrCsv(4) is the fifth column in the CSV and so on.

Adafruit USB + Serial RGB Backlight Character LCD Backpack VBScript API

System Requirements:

  • Adafruit USB Serial RGB Backlight Character LCD Backpack

The Problem:

I recently needed a fast, cheap and modular way to output small amounts of information from a headless Windows 7 appliance, something that didn’t require a large amount of electrical engineering work or assembly while at the same time working over USB.

I accidentally stumbled upon a product by Adafruit, who seem to be tightly aligned with the Raspberry Pi/Arduino, however USB is USB which means that making it cooperate with Win32 wouldn’t be particularly challenging.

Being the lazy person that I am, I never much care for the idea of having to repeatedly type out control commands through a command line parser to get what I want and quite frankly, getting a NT Command Prompt to reliably pass anything out to a Serial Port is more or less a futile exercise unless you are using Plink or replace the shell entirely with something more robust.

My solution was quite simple, create a O-O VBScript API for running it via CScript that can in turn be called from the NT command line where required.

Buy Adafruit USB Serial RGB Backlight Character LCD Backpack, and other Adafruit components or & help support this site.


More Info

This API does what I require it to do. I have implemented all of the main command syntax from the Adafruit documentation (links below). It is classful and self contained. As long as you can create a FileSystemObject and can find the COM Port, you can make use of it.

[Update 25/04/2019] You can now obtain this code directly from Github.

View: AdafruitUsbSerial on GitHub

' AdafruitUsbSerial Application Programming Interface v1.0.4

' © C:Amie | www.c-amie.co.uk 1996 - 2014

' Not for commercial reproduction without the express permission of the author

' No warranty is offered or implied as a result of downloading or using this APIClass AdafruitUsbSerialprivate m_ForReadingprivate m_SCREEN_OFF

private m_SCREEN_ON

private m_AUTO_SCROLL_ON


private m_CLEAR_SCREEN








private m_SET_BLINK_ON

private m_SET_BLINK_OFF

private m_SET_RGB

private m_SET_CONTRAST

private m_SET_BRIGHTNESSprivate m_iPortNumber

private m_byteCharacterLength

private m_bolDebug

private m_bolAutoScroll

private m_bolUnderlineCursor

private m_bolBlinkCursorprivate m_fso private

sub Class_Initialize
m_ForReading = 1
m_SCREEN_OFF = chr(254) & chr(70)
m_SCREEN_ON = chr(254) & chr(66)
m_AUTO_SCROLL_ON = chr(254) & chr(81)
m_AUTO_SCROLL_OFF = chr(254) & chr(82)
m_CLEAR_SCREEN = chr(254) & chr(88)
m_SET_STARTUP_SPLASH = chr(254) & chr(64)
m_SET_CURSOR_POSITION = chr(254) & chr(71)
m_SET_CURSOR_HOME = chr(254) & chr(72)
m_SET_CURSOR_BACK = chr(254) & chr(76)
m_SET_CURSOR_FORWARD = chr(254) & chr(77)
m_SET_UNDERLINE_ON = chr(254) & chr(74)
m_SET_UNDERLINE_OFF = chr(254) & chr(75)
m_SET_BLINK_ON = chr(254) & chr(83)
m_SET_BLINK_OFF = chr(254) & chr(84)
m_SET_RGB = chr(254) & chr(208)
m_SET_CONTRAST = chr(254) & chr(80)
m_SET_BRIGHTNESS = chr(254) & chr(153)

m_iPortNumber = 1
m_byteCharacterLength = 32
m_bolDebug = false
m_bolAutoScroll = true
m_bolUnderlineCursor = false
m_bolBlinkCursor = false

set m_fso = CreateObject("Scripting.FileSystemObject")
end sub

private sub Class_Terminate
set m_fso = nothing
end sub

public property get PortNumber
PortNumber = m_iPortNumber
end property

public property let PortNumber(ByRef iIn)
m_iPortNumber = iIn
end property

public property get CharacterLength
CharacterLength = m_byteCharacterLength
end property

public property let CharacterLength(ByRef byteIn)
m_byteCharacterLength = byteIn
end property

public property get Debug()
Debug = m_bolDebug
end property

public property let Debug(ByRef bolIn)
m_bolDebug = bolIn
end property

public property get AutoScroll()
AutoScroll = m_bolAutoScroll
end property

public property let AutoScroll(ByRef bolIn)
if (bolIn) then
end if
m_bolAutoScroll = bolIn
end property

public property get Underline()
Underline = m_bolUnderlineCursor
end property

public property let Underline(ByRef bolIn)
if (bolIn) then
end if
m_bolUnderlineCursor = bolIn
end property

public property get Blink()
Blink = m_bolBlinkCursor
end property

public property let Blink(ByRef bolIn)
if (bolIn) then
end if
m_bolBlinkCursor = bolIn
end property

public sub clearScreen()
end sub public sub screenOn()
end sub

public sub screenOff()
end sub

public sub changeSplashScreen(ByVal strIn)
strIn = Left(strIn, m_byteCharacters)
' Force it to be exactly 32 characters by padding
do while (Len(strIn) < m_byteCharacters)
strIn = (strIn & " ")
end sub

public sub backlight(ByRef byteR, ByRef byteG, ByRef byteB)
end sub

' Valid Range 0 - 255. Values between 180 and 220 are suggested
public sub contrast(ByRef byteIn)
end sub

' Valid Range 0 - 255.
public sub brightness(ByRef byteIn)
end sub

public sub setCursorPosition(ByRef iX, ByRef iY)
end sub

public sub home()
end sub

public sub back()
end sub

public sub goBack(ByRef iIn)
Dim i
for i = 1 to iIn
end sub

public sub forward()
end sub

public sub goForward(ByRef iIn)
Dim i
for i = 1 to iIn
end sub

public sub delete()
me.write(" ")
end sub

public sub write(ByRef strIn)
Dim serialWriter
if (me.Debug) then
wscript.echo strIn
end if
set serialWriter = m_fso.CreateTextFile("COM" & m_iPortNumber & ":",True)
set serialWriter = nothing
end sub

public sub teletype(ByRef strIn, ByRef iDelayMs)
Dim i
Dim iLen
iLen = Len(strIn)
for i = 1 to iLen
me.write(Mid(strIn, i, 1))
end sub

public function testComPort(ByRef byteNumber)
Dim serialWriter
if (me.Debug) then
wscript.echo "Attempting communications with COM" & byteNumber
end if
On Error Resume Next
set serialWriter = m_fso.CreateTextFile("COM" & byteNumber & ":",True)
set serialWriter = nothing
if (err.number = 0) then
testComPort = true
testComPort = false
end if
On Error Goto 0
end function

End Class

Copy it into your VBScript project file or into a dedicated class file and include it. Once it is in scope, the example below shows a general usage pattern for the main API.

It is recommended that all projects include and set the first 8 lines shown below, just so that you can ensure that you are tuning your project in the way that you want it. The remainder of the code shows examples of how to use the functions.

As a result of the USB driver allocating COM ports in a fairly dynamic way under Win32, you cannot expect to hard code your COM Port inside the project – particularly if the physical USB port that the backpack is connected to changes. Consequently, you can use testComPort() to attempt to locate the correct port as shown below. The function will terminate on the first port that it finds with an active serial output line available, if you have multiple active serial ports available on your project, the function may find the wrong port.

Finally, Adafruit recommends – at a minimum -adding a 10 millisecond delay between each command, which is not shown below. You should use WScript.Sleep(10) to achieve similar under VBScript. If you don’t, everything shown below with the exception of the executing of the Teletype macro will occur in well under a second.

Dim usbSerial

set usbSerial = new AdafruitUsbSerial

    usbSerial.PortNumber = 3              ' Set to COM3

    usbSerial.Debug = true                ' Inputs will be written back to WScript

    usbSerial.CharacterLength = 32        ' 32 is the default

    usbSerial.AutoScroll = true           ' Enable/Disable Auto Scroll

    usbSerial.Underline = true            ' Enable Cursor Underline

    usbSerial.Blink = true                ' Enable Cursor Blink' Find the first live COM Port if you don't know where it is

Dim iComPort

for iComPort = 1 to 30

    if (usbSerial.testComPort(iComPort)) then

        usbSerial.PortNumber = iComPort

        Exit For

    end if

next' Write Text

usbSerial.write("some text")' Write on both lines

usbSerial.write("line one" & vblf & "line two")' Clear the screen

usbSerial.clearScreen()' Screen Off


' Screen On

' Change the Backlight Colour
call usbSerial.backlight(255, 0, 255) ' Sets the RGB values (Fuchsia in this case)

' Set the screen brightness
usbSerial.brightness(180) ' 0 - 255

' Set the screen contrast
usbSerial.contrast(180) ' 0 - 255

' Set the Cursor Position
usbSerial.home()                  ' Moves to character 1, row 1
usbSerial.back()                  ' Moves the cursor back 1 character
usbSerial.forward()               ' Moves the cursor forward 1 character
usbSerial.goBack(5)               ' Steps the cursor back 5 characters
usbSerial.goForward(6)            ' Progresses the cursor forward 6 characters
usbSerial.setCursorPosition(5,1)  ' Sets the cursor to Character 5 on Row 1
usbSerial.delete()                ' Moves the cursor back 1 and clears the previous character

' Teletype (Macro)
call usbSerial.teletype("this will teletype out", 100) ' Write the text, with a 0.1 second character delay

' Change the Adafruit Splash Screen (Auto truncated/padded to usbSerial.CharacterLength)
usbSerial.changeSplashScreen("This is a splash screen message")

' Clean up and free resources
set usbSerial = nothing

Thanks to a structured API it is as easy as that!

View: Adafruit: Command Reference
View: Adafruit: Sending Text

See Also

View: Adafruit

Buy Adafruit USB Serial RGB Backlight Character LCD Backpack, and other Adafruit components from Amazon & help support this site: