Add XMLTV Data To JellyFin From HDHomerun

I have a NAS on which I have installed Jellyfin.  I chose Jellyfin from the usuals, because I didn’t want to pay for another streaming service (if you have to pay to watch tv, it might as well be a streaming service).

Anyway, jellyfin automatically detected the HDHomerun (2 tuner, old) connected to my network.  And while I could watch live tv via the Silicondust/HDHomerun app, the ability to see all of the tv programming on Jellyfin was just too enticing to pass by.

Turned on logging in scheduled tasks.  Errors, added group docker with admin privileges.

synology task scheduler run result interrupted – https://community.synology.com/enu/forum/1/post/150119?reply=467768

sudo chmod 666 /var/run/docker.sock – https://stackoverflow.com/questions/48957195/how-to-fix-docker-got-permission-denied-issue  chmod 666.

changed save directory web folder – issues with writing outside the web folder

then setup user permissions in nas – control panel > shared folder > web > edit > permissions > system internal user (drop down) > jellyfin initial user (during setup) > give it read access

cron job to get tv guide xml data:

<?php

function SaveFile($file, $fileDestination) {
    if (isset($file) && isset($fileDestination)) {
        try {
            $fHandle = fopen($fileDestination, "w");
            if(!$fHandle){
                throw new Exception("Could not open file destination ({$fileDestination}).");
            }
            
            if (fwrite($fHandle, $file) === FALSE) {
                throw new Exception("Cannot write to file ({$fileDestination}).");
            }

            fclose($fHandle);
        }
        catch (Exception $e) {
            throw $e;
        }

        return TRUE;
    }

    return false;
} // end SaveFile

// ip address and hd homerun location on your lan
$hdHomerunUrl = 'http://xxx.xxx.xxx.xxx/discover.json';

$ch = curl_init();
    
curl_setopt($ch, CURLOPT_URL, $hdHomerunUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:52.0) Gecko/20100101 Firefox/52.0');
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);

$hdHomeRunData = curl_exec($ch); // curl hdhomerun for data

curl_close($ch);

$dataDecoded = json_decode($hdHomeRunData, true); // decode data

$authCode =  $dataDecoded['DeviceAuth']; // get device authorization

if(isset($authCode) && $authCode != ''){
    // using device auth, query api.hdhomerun for data
    $xmlTvUrl = 'https://api.hdhomerun.com/api/xmltv?DeviceAuth=' . $authCode;

    try {
        $ch=curl_init();

        curl_setopt($ch, CURLOPT_URL, $xmlTvUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
        // 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:52.0) Gecko/20100101 Firefox/52.0'
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:52.0) Gecko/20100101 Firefox/52.0');
        curl_setopt($ch, CURLOPT_ENCODING, "");
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
        curl_setopt($ch, CURLOPT_TIMEOUT, 120);

        $xmlData = curl_exec($ch);

        curl_close($ch);
    }
    catch (Exception $ex) {
        error_log($ex, 0);
        die();
        exit();
    }

    $fileLoc = '/STORAGE_LOCATION_ON_YOUR_NAS/';
    
    // tried saving to database
    // mariadb error Got a packet bigger than 'max_allowed_packet' bytes tried updating - forget it for now
    
    if (isset($xmlData) && $xmlData) {
        if(file_exists($fileLoc . 'xmltv.xml')){ // if file exists
            try{
                // rename appending date
                $renamed = rename($fileLoc . 'xmltv.xml', $fileLoc . 'xmltv-' . date('Y-m-d') . '.xml');
                if(!$renamed){
                    throw new Exception('Something went wrong. Either file was not found or could not rename');
                }
            } 
            catch (Exception $e) {
                error_log($e, 0);
                die($e);
                exit();
            }
        }        

        try{
            SaveFile($xmlData, $fileLoc . 'xmltv.xml'); // try saving new curled file
        }
        catch (Exception $e){
            error_log($e, 0);
            die($e);
            exit();
        }
    }
}

Set up above script as a cron job.  Point jellyfin to storage location for tv guide xml data and you’re done!  Sorry for the scarce details, as I did this quite a while ago.  Personally, I have gone back to using hdhomerun’s recording control, but it’s still nice to see the tv guide data in Jellyfin.

This entry was posted in Computer Stuff, MySQL, PHP and tagged , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *