Captions with HD-PVR alternate

From MythTV Official Wiki
Jump to: navigation, search

The page Captions with HD-PVR nicely describes how to get captions for HD-PVR recordings. You definitely should read that first. If you find that ccextractor can not record the captions you can try using zvbi2raw in addition to ccextractor.

Setup

Compile zvbi2raw from the site above. You likely will want to create udev rules for the card/cards that will record the captions so the scripts can find them reliably. For example, for a setup of 2 HD-PVRs (cardid 1 and 2) and 1 PVR-500, rules could be:

SUBSYSTEM=="video4linux",ATTR{name}=="ivtv0 encoder MPG",SYMLINK+="video-pvr1"
SUBSYSTEM=="video4linux",ATTR{name}=="ivtv0 encoder VBI",SYMLINK+="vbi-pvr1"
SUBSYSTEM=="video4linux",ATTR{name}=="ivtv1 encoder MPG",SYMLINK+="video-pvr2"
SUBSYSTEM=="video4linux",ATTR{name}=="ivtv1 encoder VBI",SYMLINK+="vbi-pvr2"

hd-captions-common.sh

This script sets up the variables used by the two other scripts. You almost certainly will need to change this to match your specific setup.

#! /bin/bash
#

# Variables used by the hd-captions scripts

#########################################
#
# VERIFY THESE PATHS FOR YOUR SYSTEM
#
#########################################

VBI2RAW=/usr/local/bin/zvbi2raw
CCEXTRACTOR=/usr/local/bin/ccextractor
IVTV_TUNE=/usr/bin/ivtv-tune
V4L2_CTL=/usr/bin/v4l2-ctl
GREP=/bin/grep
AWK=/usr/bin/awk
SED=/bin/sed
FUSER=/bin/fuser
EXPR=/usr/bin/expr
DATE=/bin/date
CP=/bin/cp
RM=/bin/rm
TOUCH=/usr/bin/touch
MKDIR=/bin/mkdir
CHMOD=/bin/chmod
SLEEP=/bin/sleep
MV=/bin/mv
TRUE=/bin/true

#########################################
#
#  EDIT THESE PARAMETERS IF NECESSARY
#
#########################################
#
# PVR500 Inputs:
#  0: Tuner 1
#  1: S-Video 1
#  2: Composite 1
#  3: S-Video 2
#  4: Composite 2
#

HD_PVR_CARDID=2
VIDEO_DEVICE=/dev/video-pvr${cardid}
VBI_DEVICE=/dev/vbi-pvr${cardid}
if [ ${cardid} = 1 ]; then
  CAPTION_INPUT_NUM=2           # Composite input
  TUNE="${TRUE}"
else
  CAPTION_INPUT_NUM=0           # Tuner
  TUNE="${IVTV_TUNE} -d ${VIDEO_DEVICE} -c3"
fi

# set the following variable to "=1" if the command:
# 	v4l2-ctl -d ${VBI_DEVICE} --set-fmt-sliced-vbi=cc
# generates an error message:
#       "No value given to suboption <cc>"
# otherwise, leave it blank.
#
# This is a known command-line parsing bug that will be fixed.
#
V4L2_CTL_PARSE_BUG="=1"

workdir_prefix=$HOME/tmp/captions_
logfile_prefix=$HOME/mythbox_logs/captions_

delay_bias_ms=800     # set this to any consistent value, a number of
		      # milliseconds earlier that you want to see all
		      # captions appearing

hd-captions-start.sh

This script should be run when the REC_STARTED_WRITING event is generated. Note it is important to use REC_STARTED_WRITING and not REC_STARTED since it can take several seconds between these two events. I found that the timing was pretty good this way and didn't need the extra calculations in the original scripts. Your mileage may vary.

#!/bin/bash
#
# Invoke with CARDID CHANID STARTTIMEISO

cardid="$1"
chanid="$2"
starttimeiso="$3"

. `dirname $0`/hd-captions-common.sh

# Only do this for the HD-PVR inputs
if [ $cardid -gt ${HD_PVR_CARDID} ]; then
  exit 0
fi

workdir=${workdir_prefix}${cardid}_${chanid}_${starttimeiso}
logfile=${workdir}/log.txt

if [ -e $workdir ]; then
  echo "Working directory name collision, exiting" >> $logfile
  exit 1
fi

${MKDIR} -p $workdir

cd $workdir
(
    vbiuser=`${FUSER} ${VBI_DEVICE} |& ${AWK} ' { print $2 } '`
    if [ "$vbiuser" != "" ]; then
      echo "kill -9 $vbiuser" >> $logfile
      kill -9 $vbiuser >> $logfile 2>&1
    fi

    echo "${V4L2_CTL} -i ${CAPTION_INPUT_NUM} -d ${VIDEO_DEVICE}" >> $logfile
    ${V4L2_CTL} -i ${CAPTION_INPUT_NUM} -d ${VIDEO_DEVICE} >> $logfile 2>&1

    echo ${TUNE} >> $logfile
    ${TUNE} >> $logfile 2>&1

    echo "${VBI2RAW} -m -d ${VBI_DEVICE} > pass1.vbiraw" >> $logfile
    ${VBI2RAW} -m -d ${VBI_DEVICE} > pass1.vbiraw 2>> $logfile &

    ccpid=$!
    echo $ccpid > vbi2raw.pid
    echo "vbi2raw.pid = $ccpid" >> $logfile
    wait $ccpid
    ${RM} vbi2raw.pid

) </dev/null > /dev/null 2>&1 &

exit 0

hd-captions-finalize.sh

This script should be run when the REC_FINISHED event is generated. This version also copies the zvbi2raw output and log to the recording directories in case you want to regenerate the .srt file.

#!/bin/bash
#
# Invoke with CARDID CHANID STARTTIMEISO DIR FILE

cardid="$1"
chanid="$2"
starttimeiso="$3"
dir="$4"
file="$5"

. `dirname $0`/hd-captions-common.sh

# Only do this for the HD-PVR inputs
if [ $cardid -gt ${HD_PVR_CARDID} ]; then
  exit 0
fi

workdir=${workdir_prefix}${cardid}_${chanid}_${starttimeiso}
logfile=${workdir}/log.txt

if [ ! -d $workdir ]; then
  exit 1
fi

echo "--finalize--"                 >> $logfile
echo "cardid=$cardid"               >> $logfile
echo "chanid=$chanid"               >> $logfile
echo "starttimeiso=$starttimeiso"   >> $logfile
echo "dir=$dir"                     >> $logfile
echo "file=$file"                   >> $logfile
echo "delay_bias_ms=$delay_bias_ms" >> $logfile

pushd $workdir

# Fork off a subshell to do this work
(
    if [ -f vbi2raw.pid ]; then
      echo "killing vbi2raw during finalize" >> $logfile
      kill `cat vbi2raw.pid` >> $logfile 2>&1
    fi

    echo "${CCEXTRACTOR} -in=raw -delay $delay_bias_ms \
                         -o result.srt pass1.vbiraw" >> $logfile
          ${CCEXTRACTOR} -in=raw -delay $delay_bias_ms \
                         -o result.srt pass1.vbiraw  >> $logfile 2>&1

    ofile=`echo $file | ${SED} -e 's|.mpg$|.srt|'`
    if [ $ofile = $file ]; then
      exit 2
    fi

    # Copy new .srt file to recording directory
    echo "${CP} result.srt $dir/$ofile" >> $logfile
          ${CP} result.srt $dir/$ofile >> $logfile 2>&1

    # Make sure it is can be accessed and deleted
    echo "${CHMOD} a+rw $dir/$ofile" >> $logfile
          ${CHMOD} a+rw $dir/$ofile >> $logfile 2>&1

    # Copy the vbiraw file to the recordings directory
    vofile=`echo $file | ${SED} -e 's|.mpg$|.vbiraw|'`
    ${CP} pass1.vbiraw $dir/$vofile >> $logfile 2>&1
    ${CHMOD} a+rw $dir/$vofile >> $logfile 2>&1

    # Copy the log file to the recordings directory
    lofile=`echo $file | ${SED} -e 's|.mpg$|.caplog|'`
    ${CP} log.txt $dir/$lofile
    ${CHMOD} a+rw $dir/$lofile

    popd
    ${RM} -fr "$workdir"

) </dev/null > /dev/null 2>&1 &

exit 0

recordingDeleted.sh

This script should be run when the REC_DELETED event is generated. It removes the .srt file and other files generated.

#!/bin/bash
#
# Invoke with: %FILE% %DIR%

file="$1"
dir="$2"

LOG=/dev/null

echo "FILE: $file" >> $LOG
echo "DIR:  $dir"  >> $LOG

SRTFILE="$dir/$(basename $file .mpg).srt"
/bin/rm -f "$SRTFILE" >> $LOG 2>&1

RAWFILE="$dir/$(basename $file .mpg).vbiraw"
/bin/rm -f "$RAWFILE" >> $LOG 2>&1

LOGFILE="$dir/$(basename $file .mpg).caplog"
/bin/rm -f "$LOGFILE" >> $LOG 2>&1

exit 0