Using the HDHomeRun Command-Line Tool to Find Channels

hdhomerun_config is a HDHomeRun command-line client for HDHomeRun that can be downloaded from the offical website. The tool is somewhat finicky when it comes to automatically discovering HDHomeRun devices. Similarly, referring to the HDHomeRun device by id, as mentioned within the parameters of the command-line tool, does not really work but fortunately the IP address of the HDHomeRun device can be used instead.

Here is an example:

hdhomerun_config 192.168.1.50 scan 2

where:

The scan results will be printed on the terminal, channels being prefixed by ch and then, given DVB-T, the corresponding sub-channels (called programs) will be listed underneath the channel number. That being said, a TV station is identified by the channel number and the sub-channel or program number.

A System to Record TV Automatically

Typically HDHomeRun is used alongside a PVR such as Plex Media Server or Jellyfin that are capable of recording TV shows on a schedule. However, there are situations where the PVRs cannot be relied upon such that a different system has to be used to record TV. For example, in case some show is not marked as re-occurring in the IPTV XML file, then scheduled recordings will not work for Plex Media Server.

This custom system relies on using cron and several scripts in order to record TV shows. Here is the filesystem layout of the recording system:

+---+ etc
    |
    +----------+ cron.daily
    |                +
    |                |
    |                +------------+ record-download-iptv-xml
    |
    +----------+ cron.minutely
                     +
                     |
                     +-------------+ record-show-1
                     |
                     +-------------+ record-show-2
                     |
                     .
                     .
                     .

where:

The record-download-iptv-xml is very basic:

#!/usr/bin/env sh
 
TV_GUIDE=https://.../tvguide.xml
 
curl -s ${TV_GUIDE} \
    -o /scratch/tv/iptv.xml

where:

This is performed only daily in order to not hammer the TV guide website with requests. The show recording scripts record-show-1, record-show-2, and so on, then pick up the /scratch/tv/iptv.xml file downloaded by the record-download-iptv-xml script and check whether it is time to record. If it is time to record, the show recording script uses ffmpeg to record the show from HDHomeRun.

Here is a show recording script:

#!/usr/bin/env bash
###########################################################################
##  Copyright (C) Wizardry and Steamworks 2024 - License: MIT            ##
##  Please see: https://opensource.org/license/mit/ for legal details,   ##
##  rights of fair usage, the disclaimer and warranty conditions.        ##
###########################################################################
 
###########################################################################
#                            CONFIGURATION                                #
###########################################################################
 
# the path to the IPTV XML file
IPTV_XML_FILE="/scratch/tv/iptv.xml"
# the name of the channel as mentioned in the IPTV XML file
IPTV_CHANNEL_NAME="..."
# the show name to record as mentioned in the IPTV XML file 
SHOW_TITLE="..."
# a path to a directory where the shows will be stored
RECORD_DIRECTORY="/mnt/storage/TV/"
# the channel to record from as scanned with hdhomerun_config
CHANNEL=ch400000000
# the subchannel as scanned with hdhomerun_config
SUBCHANNEL=12
# the IP address of the HDHomeRun device
FLEX_IP=192.168.1.50
# the streaming port of the HDHomeRun device
FLEX_PORT=5004
# the tuner to use (ie: for Flex Quatro) when recording
FLEX_TUNER=tuner2
 
###########################################################################
#                             INTERNALS                                   #
###########################################################################
# for debugging
#set -x
 
PROGRAMME_SCHEDULE=`xidel \
    ${IPTV_XML_FILE} \
    -s \
    --extract  \
    "//programme[@channel = '${IPTV_CHANNEL_NAME}'][title = '${SHOW_TITLE}']/concat(@start, ' ', @stop)"`
 
NEXT_SCHEDULE=86400
NOW=$(date +%s)
while read SCHEDULE; do
    # extract start, respectively stop time of the TV show
    read -r A B < <(awk '{ print $1, $3 }' <<< ${SCHEDULE})
 
    # re-format the date strings to rfc 3339
    X=${A:0:4}-${A:4:2}-${A:6:2}T${A:8:2}:${A:10:2}:${A:12:2}
    Y=${B:0:4}-${B:4:2}-${B:6:2}T${B:8:2}:${B:10:2}:${A:12:2}
 
    # to epoch time
    SX=$(date --date=${X} +%s)
    SY=$(date --date=${Y} +%s)
 
    # compute the show duration in seconds
    RECORD_DURATION=$((${SY}-${SX}))
 
    # the difference in seconds between the show start time and the current time
    NEXT=$((${SX}-${NOW}))
    if [ ${NEXT} -ge 0 ] && [ ${NEXT} -le ${NEXT_SCHEDULE} ]; then
        NEXT_SCHEDULE=${NEXT}
    fi
    # if the show is in the past, or more than one minute into the future skip
    if [ ${NEXT} -lt -60 ] || [ ${NEXT} -gt 60 ]; then
        continue
    fi
 
    # start recording...
    ffmpeg \
        -y \
        -thread_queue_size 32768 \
        -i "http://${FLEX_IP}:${FLEX_PORT}/${FLEX_TUNER}/${CHANNEL}-${SUBCHANNEL}?duration=${RECORD_DURATION}" \
        -vf "scale=-2:480" \
        -c:v libx264 \
        -c:a aac \
        -ac 2 \
        -b:a 128k \
        -movflags +faststart \
        -tune zerolatency \
        "${RECORD_DIRECTORY}/${A}.mp4"
 
    # terminate in case of IPTV XML duplicates
    exit 0
done <<< "${PROGRAMME_SCHEDULE}"
 
echo "Next scheduled show will be recorded in: "${NEXT_SCHEDULE}"s"

The script performs the following actions:

In order to determine the channel and the sub-channel (program) numbers, the hdhomerun_config command-line tool can be used.

In case the recording is choppy and with interruptions, the ffmpeg buffer size -thread_queue_size 32768 should be scaled up as much as the resources will allow.