Captions with HD-PVR alternate
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.
Contents
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