TV Fool

TV Fool (http://forum.tvfool.com/index.php)
-   Enthusiast's Exchange (http://forum.tvfool.com/forumdisplay.php?f=16)
-   -   Personal Video Recorder (PVR) using SiliconDust tuner(s) and scripting on Linux (http://forum.tvfool.com/showthread.php?t=16693)

GroundUrMast 26-Oct-2019 2:06 AM

Personal Video Recorder (PVR) using SiliconDust tuner(s) and scripting on Linux
 
Edited 11/6/2019 - Updated Version of Script Code. Added locking feature to avoid race condition when two or more recordings begin at the same time.

I've tried several different Home Theater DVR/PVR software solutions beginning with Windows Media Center then MythTv and TVHeadend. Each offered valuable features but tended to use a lot of resources and in the event of updates or problems I found trouble shooting support a bit sparse.

I have found that I only used the basic recording functions so I set out to write my own scripts which would enable me to use the command line to schedule a recording. I've been working on making the process as simple as possible... The goal being to simply enter a single command with the necessary arguments for the system to understand what I want to record and when.

I own several SiliconDust tuners which are connected to different antennas so that I can have reliable reception of as many stations as possible. So I needed to include the logic to let the system choose a tuner that is both 'connected to an appropriate antenna' and 'not in use'.

Presently, my PVR system consists of a single script that draws information from a text file that contains the real RF channel and the MPEG2-PID that is associated with the Virtual Channel. There is one text file for each known virtual channel. Each of the virtual channel map files also includes a list of tuner and their sub-tuners ordered by preference. The main script checks for the 'lock' status of a tuner before beginning a recording. If the preferred tuner is locked by another user or recording process, the script will proceed to check the next tuner in the list.

Presently, I schedule the running of the recording script using the built-in Unix/Linux command 'at'.

script: recordTV.sh
Code:

#!/bin/bash
#
#
#
# Set Recording time-stamp to Recording File Name
REC_TS=$(date +%Y%m%d%H%M)
#
LOCKKEY=$(date +%T%N)
#
LOG_FILE=/home/tom/bin/PVR_scripts/logs/PVR_scripts.log
touch -a $LOG_FILE
#
if [ -z $1 ]
  then
    echo $(date +%T%N) Exiting; No Virtual Channel was specified >> $LOG_FILE
    exit
  else
    VC=$1
fi
#
if [ -z $2 ]
  then
    echo $(date +%T%N) Exiting; No File Name was specified >> $LOG_FILE
    exit
  else
    REC_FN=/home/tom/Videos/$2
fi
#
if [ -z $3 ]
  then
    echo $(date +%T%N) Exiting; Recording duration not specified >> $LOG_FILE
    exit
  else
    RecDur=$3
fi
#
#
#Load Virtual Channel configutation to array
declare -a VCarray

  if [ -f /home/tom/bin/PVR_scripts/VirtualChannelMaps/VirtualChan$VC.txt ]
    then
      mapfile -t VCarray < /home/tom/bin/PVR_scripts/VirtualChannelMaps/VirtualChan${VC}.txt
    else
      echo $(date +%T%N) Virtual Channel ${VC} configuration file missing >> $LOG_FILE
      exit
  fi
#
#
arrayindex=2
FT=0
function SetLock () {
  if [ ! -f /home/tom/bin/FindFreeTuner.lock ]
    then
      touch /home/tom/bin/FindFreeTuner.lock
      chmod 666 /home/tom/bin/FindFreeTuner.lock
      echo $(date +%T%N) Lock is set by ${VC} >> $LOG_FILE
      FindFreeTuner
    else
      if [ $FT -gt 9 ]
        then
          echo $(date +%T%N) FindFreeTuner.lock file has not been removed - by ${VC} >> $LOG_FILE
          exit
        else
          let FT=${FT}+1
          echo $(date +%T%N) FT=${FT} by ${VC} >> $LOG_FILE
          sleep 1s
          SetLock
      fi
  fi
}
function FindFreeTuner () {
  if [ $arrayindex -gt 20 ]
    then
      echo $(date +%T%N) "No free tuners available" by ${VC} >> $LOG_FILE
      exit
    else
      LockStatus=$(/usr/local/bin/hdhomerun_config ${VCarray[$arrayindex]} get /${VCarray[$arrayindex+1]}/lockkey)
      if [[ ${LockStatus} = "none" ]]
        then
          ConfigTuner
        else
          echo $(date +%T%N) HDHR ${VCarray[$arrayindex]} ${VCarray[$arrayindex+1]} is locked by $LockStatus - by ${VC} >> $LOG_FILE
          let arrayindex=${arrayindex}+2
          FindFreeTuner
      fi
  fi
}
#
function ConfigTuner () {
/usr/local/bin/hdhomerun_config ${VCarray[$arrayindex]} set /${VCarray[$arrayindex+1]}/lockkey $LOCKKEY
echo $(date +%T%N) tuner ${VCarray[$arrayindex]} sub-tuner ${VCarray[$arrayindex+1]} VC ${VC} TS-PID ${VCarray[1]} lockkey $LOCKKEY >> $LOG_FILE
rm /home/tom/bin/FindFreeTuner.lock
echo $(date +%T%N) Lock has been unset by ${VC} >> $LOG_FILE
/usr/local/bin/hdhomerun_config ${VCarray[$arrayindex]} key $LOCKKEY set /${VCarray[$arrayindex+1]}/channel auto:${VCarray[0]}
/usr/local/bin/hdhomerun_config ${VCarray[$arrayindex]} key $LOCKKEY set /${VCarray[$arrayindex+1]}/program ${VCarray[1]}
echo $(date +%T%N) Normal start of recording CH $VC >> $LOG_FILE
/usr/local/bin/hdhomerun_config ${VCarray[$arrayindex]} key $LOCKKEY save /${VCarray[$arrayindex+1]} ${REC_FN}.mpg &
HDHR_PID=$!
echo $(date +%T%N) $HDHR_PID by ${VC} >> $LOG_FILE
#
sleep ${RecDur}m
#
#Release tuner
/usr/local/bin/hdhomerun_config ${VCarray[$arrayindex]} key ${LOCKKEY} set /${VCarray[$arrayindex+1]}/channel none
/usr/local/bin/hdhomerun_config ${VCarray[$arrayindex]} key ${LOCKKEY} set /${VCarray[$arrayindex+1]}/lockkey none
#
#Send normal termination signal to hdhomerun_config
kill -15 $HDHR_PID
echo $(date +%T%N) Normal end of recording by ${VC} >> $LOG_FILE
#
exit
}
echo $(date +%T%N)  ${VC} Checking for lock file >> $LOG_FILE
SetLock
exit



Sample VirtualChannelMap file 'VirtualChan4.1.txt'
Code:

30
3
1032E7DB
tuner0
1032E7DB
tuner1
1052349B
tuner0
1052349B
tuner1
1019D817
tuner0
1019D817
tuner1
101A5A4B
tuner0
101A5A4B
tuner1
101AE560
tuner0
101AE560
tuner1

Use of the script as shown below will schedule a recording of virtual channel 4.1 to a file named 'RecordingFileName'.mpg and the recording will run for 62 minutes. The recording will begin at 6:59 PM on October 30, 2019.
Code:


commandprompt:~$ at 18:59 10302019
warning: commands will be executed using /bin/sh
at> recordTV.sh 4.1 RecordingFileName 62
at> <EOT>
job 1204 at Wed Oct 30 18:59:00 2019
commandprompt::~$

The <EOT> control character is entered using CTL+d key combination.

GroundUrMast 7-Nov-2019 6:56 AM

Using crontab for recurring recordings
 
I also use crontab to schedule recurring recordings. The following example represents my daily newscast recording schedule. I can watch a news cast until it is overwritten by the next scheduled recording of that newscast.

crontab -e is used to edit the cron-table.
crontab -l is used to list the current cron-table.

Code:

$ crontab -l
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow  command
59 10 * * 1-5 . $HOME/.profile; /bin/bash /home/tom/bin/recordTV.sh 4.1 KOMO-TV4.1NewsAt11AM 32 > /home/tom/tempcron4.1.log 2>&1
59 15 * * 1-5 . $HOME/.profile; /bin/bash /home/tom/bin/recordTV.sh 4.1 KOMO-TV4.1NewsAt4PM 32 > /home/tom/tempcron4.1.log 2>&1
59 22 * * * . $HOME/.profile; /bin/bash /home/tom/bin/recordTV.sh 4.1 KOMO-TV4.1NewsAt11PM 32 > /home/tom/tempcron4.1.log 2>&1
59 11 * * 1-5 . $HOME/.profile; /bin/bash /home/tom/bin/recordTV.sh 5.1 KING-TV5.1NewsAtNoon 32 > /home/tom/tempcron5.1.log 2>&1
59 16 * * 1-6 . $HOME/.profile; /bin/bash /home/tom/bin/recordTV.sh 5.1 KING-TV5.1NewsAt5PM 32 > /home/tom/tempcron5.1.log 2>&1
59 22 * * * . $HOME/.profile; /bin/bash /home/tom/bin/recordTV.sh 5.1 KING-TV5.1NewsAt11PM 32 > /home/tom/tempcron5.1.log 2>&1
59 11 * * 1-5 . $HOME/.profile; /bin/bash /home/tom/bin/recordTV.sh 7.1 KIRO-TV7.1NewsAtNoon 32 > /home/tom/tempcron7.1.log 2>&1
59 17 * * 1-5 . $HOME/.profile; /bin/bash /home/tom/bin/recordTV.sh 7.1 KIRO-TV7.1NewsAt6PM 32 > /home/tom/tempcron7.1.log 2>&1
59 22 * * * . $HOME/.profile; /bin/bash /home/tom/bin/recordTV.sh 7.1 KIRO-TV7.1NewsAt11PM 32 > /home/tom/tempcron7.1.log 2>&1
29 17 * * 1-5 . $HOME/.profile; /bin/bash /home/tom/bin/recordTV.sh 9.1 KCTS-TV9.1NewsAt530PM 92 > /home/tom/tempcron9.1.log 2>&1
59 7 * * 1-5 . $HOME/.profile; /bin/bash /home/tom/bin/recordTV.sh 13.1 KCPQ-TV13.1NewsAt8AM 32 > /home/tom/tempcron13.1.log 2>&1
59 21 * * * . $HOME/.profile; /bin/bash /home/tom/bin/recordTV.sh 13.1 KCPQ-TV13.1NewsAt10PM 32 > /home/tom/tempcron13.1.log 2>&1



All times are GMT. The time now is 12:18 PM.

Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Copyright © TV Fool, LLC