View unanswered posts    View active topics

All times are UTC - 6 hours





Post new topic Reply to topic  [ 1 post ] 
Print view Previous topic   Next topic  
Author Message
Search for:
PostPosted: Fri Nov 14, 2008 11:09 pm 
Offline
Joined: Thu Apr 28, 2005 4:00 pm
Posts: 37
I've often wanted to transcode recordings with x264 and have them remain as a recording. Recently I finally wrote a script which seems to work well.

It uses a bitrate of 1000, I don't know if this is optimal, but a 30 minute show once commercials a removed results in a file of ~170mb (for me about 1/5th the size of the original). My original plan had been to use matroska as the container, however the MythTV playback seemed much better using mp4. I find the script requires approximately 1.5x the original runtime for transcoding (X2 4050+ 1gb RAM).

A few things to note:
- I don't believe the script removes commercials based on commercial flagging, a cutlist must be created.
- Temporary files are stored in /myth/tmp/ if a cutlist is present you will need space for the original mpeg too
- I've attempted to incorporate error handling, but I don't know if I've been successful (it hasn't failed, yet)
- Since this is an early version, the script does not remove the old file, it is simply renamed to ${CHAN}_${START}.mpg.old (see above, I didn't want it to fail, and take a recording with it)

I'm curious to know if this works for others, or if anyone has suggestions.

Code:
#!/bin/sh
# Transcode a MythTV recording to
# Usage:  transcode_mp4  %STARTTIME%    %CHANID%   "%DIR%/%FILE%"   %JOBID%

# Constants?
DBUSERNAME="mythtv"
DBPASSWORD="mythtv"
DBHOST="localhost"
TEMP="/myth/tmp/"
TVDIR="/myth/tv/"

starttime="$(date +%s)"

# Variables to improve readability
# Don't change these!
CHAN=$1
START=$2
FILE=$3
JOBID=$4
ERROR=0
BASENAME="${CHAN}_${START}"
STATUSFILE="${TEMP}${BASENAME}_status.log"

sql_command()
# Arg 1 - command to execute
{
   mysql -u $DBUSERNAME --password=$DBPASSWORD -h $DBHOST mythconverg -e "$1"
}

update_comment()
# Arg 1 -comment to set
{
   sql_command "update jobqueue set comment=\"$1\" where id=\"$JOBID\";"
}

set_status()
# Arg 1 - status
{
   sql_command "update jobqueue set status=\"$1\" where id=\"$JOBID\";"
}

# -- Slightly modified from myth2x264 --
check_background_progress()
# check mencoder progress in background
# Arg_1 = PROGRESS CALCULATION
{
   while [ `tail -1 $STATUSFILE | grep -c "^x264 \[info\]: kb/s:"` = 0 ]
   do
       sleep 10
       current_status=`tail -1 $STATUSFILE | grep "([ 0-9]\{1,\}%)"`
       prog_percent=`echo "$current_status" | sed 's_.*(\([ 0-9][ 0-9]\)%).*_\1_'`
       current_FPS=`echo "$current_status" | sed 's_.*\([ 0-9][ 0-9].[ 0-9][ 0-9]\)fps.*_\1_'`
       if [ -n "$prog_percent" ]; then
           prog_percent=`expr $prog_percent / $1`
           update_comment "$prog_percent% Completed @ $current_FPS fps"
       fi
       sleep 10
   done
}

cut_commercials()
{
   update_comment "Removing commercials"
   CUTLIST=`mythcommflag --getcutlist -c $CHAN -s $START | grep 'Cutlist:' | cut -d \  -f 2`

   if [ -n "$CUTLIST" ]; then
      /usr/bin/nice -n19 mythtranscode -c $CHAN -s $START --outfile "${TEMP}${BASENAME}.mpg" --mpeg2 --honorcutlist
   else
      ln -s "${FILE}" "${TEMP}${BASENAME}.mpg"
   fi
}

transcode_video()
{
    (/usr/bin/nice -n19 mencoder "${TEMP}${BASENAME}.mpg" -o /dev/null -vf softskip,harddup -oac mp3lame -lameopts abr:br=92 -ovc x264 -x264encopts pass=1:bitrate=1000:turbo=2:me=umh:me_range=16:nodct_decimate:nointerlaced:8x8dct:nofast_pskip:trellis=1:partitions=p8x8,b8x8,i8x8,i4x4:mixed_refs:bime:keyint=300:keyint_min=30:frameref=3:bframes=14:b_adapt:b_pyramid:weight_b:direct_pred=auto:subq=5:nobrdo:chroma_me:cabac:deblock:nossim:nopsnr:threads=auto -passlogfile "${TEMP}${BASENAME}.log" > $STATUSFILE 2>&1; ERROR=$?) &
   check_background_progress "2"

   cat /dev/null > $STATUSFILE
   
   if [ $ERROR -eq 0 ]; then
      (/usr/bin/nice -n19 mencoder "${TEMP}${BASENAME}.mpg" -o "${TEMP}${BASENAME}.mp4" -vf softskip,harddup -oac mp3lame -lameopts abr:br=92 -ovc x264 -x264encopts pass=2:bitrate=1000:me=umh:me_range=16:nodct_decimate:nointerlaced:8x8dct:nofast_pskip:trellis=1:partitions=p8x8,b8x8,i8x8,i4x4:mixed_refs:keyint=300:keyint_min=30:frameref=3:bframes=14:bime:b_adapt:b_pyramid:weight_b:direct_pred=auto:subq=5:nobrdo:chroma_me:cabac:deblock:nossim:nopsnr:threads=auto -passlogfile "${TEMP}${BASENAME}.log" > $STATUSFILE 2>&1; ERROR=$?) &
      check_background_progress "2 + 50"

   fi
}

switch_files()
{
   FILESIZE="${TEMP}${BASENAME}.mp4"
   mv "${TEMP}${BASENAME}.mp4" "${TVDIR}${BASENAME}.mp4"
   sql_command "UPDATE recorded SET basename='${BASENAME}.mp4', filesize = '${FILESIZE}' WHERE chanid = '${CHAN}' AND starttime = '${START}';"
   mv "${FILE}" "${FILE}.old"
   /usr/bin/nice -n19 mythcommflag --clearcutlist -c $CHAN -s $START
   /usr/bin/nice -n19 mythcommflag --rebuild -c $CHAN -s $START
}

cleanup()
{
   update_comment "Cleanup"

   rm "${TEMP}${BASENAME}.log"
   rm "${TEMP}${BASENAME}.mpg"
   rm "${TEMP}${BASENAME}.mpg.map"
   rm "${STATUSFILE}"
}

#----- Main ------
cut_commercials
transcode_video

# stop timer
endtime="$(date +%s)"
seconds="$(expr $aftertime - $starttime)"

if [ $ERROR -eq 0 ]; then
    hours=$((seconds / 3600))
    seconds=$((seconds % 3600))
    minutes=$((seconds / 60))
    seconds=$((seconds % 60))
   switch_files
   set_status 272
    update_comment "Encode Successful. Encoding Time: $hours hour(s) $minutes minute(s) $seconds second(s)"
else
   set_status 304
   update_comment "Encode Failed.  Exit status: $ERROR"
fi

cleanup


Top
 Profile  
 

Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 


All times are UTC - 6 hours




Who is online

Users browsing this forum: No registered users and 16 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group

Theme Created By ceyhansuyu