Login

Username

Password



Forgotten your password?
Request a new one here.

MythTV user job script to export videos

I don't tend to keep recordings in MythTV-native format for long. While obviously you can have MythTV transcode them to save space, I just prefer to have them as simple AVI/MP4 files on my server, accessible by all and sundry via simple SMB file shares rather than having to use MythTV's (flakey) uPNP server.

 

To that end, I set up one of the 4 customiseable user jobs to run a script which transcodes the raw recording into a more amenable format, and dumps it locally on the server (my MythTV server is also my file server) in a set archive location. I can then delete the MythTV recording (or leave it to auto expire), safe in the knowledge I have a copy of the video safely stored down on disk - and in a much more compact video format too.

 

If you want to use it, it's pasted below.

 

#!/bin/bash

OUTPUT_DIR=/home/video/archive
LOG=/var/log/mythtv/userjob.log
P_FILE=$1
P_DIR=$2
P_TITLE=$3
P_SUBTITLE=$4

# Prepare target filename, removing unfriendly filename characters as needed...
if [ -z $P_SUBTITLE ]; then # Empty string
    CLIP_NAME=`echo "${P_TITLE}" | tr -d '\000-\037\042-\046\052\057\072-\077\134\140\174\176'`
else
    CLIP_NAME=`echo "${P_TITLE} - ${P_SUBTITLE}" | tr -d '\000-\037\042-\046\052\057\072-\077\134\140\174\176'`
fi

function debug {
  echo "`(date +"%d/%m/%Y %H:%M:%S")` $1" >> ${LOG}
}

function identify {
 mplayer -endpos .1 -vo null -ao null -frames 1 -identify "${1}" 2>/dev/null |
 sed -ne '/^ID_/ {
  s/[]()|&;,<>`'"'"'\\!$" []/\\&/g;p
 }'
}

#'

# Grab various properties from the video file and set them up as variables
identify "${P_DIR}/${P_FILE}" > "/tmp/${P_FILE}_details.txt"

# Extract the type of video codec that the source file uses (will be either MPEG2 for standard def DVB, or H264 for HD)
ID_VIDEO_CODEC=`grep "ID_VIDEO_CODEC" "/tmp/${P_FILE}_details.txt" | cut -d = -f 2`
debug "Source file codec identified as ${ID_VIDEO_CODEC}"

if [ $ID_VIDEO_CODEC == "ffh264" ]; then
    FILENAME_EXTENSION="mp4"
else
    FILENAME_EXTENSION="avi"
fi

i=1
OUTPUT_FILENAME="${CLIP_NAME}.${FILENAME_EXTENSION}"
while [ -f "${OUTPUT_DIR}/${OUTPUT_FILENAME}" ]; do
    debug "Target file ${OUTPUT_FILENAME} already exists; will use ${CLIP_NAME}_${i}.${FILENAME_EXTENSION} instead"
    OUTPUT_FILENAME="${CLIP_NAME}_${i}.${FILENAME_EXTENSION}"
    i=$((i+1))
done;

debug "Source file is ${P_DIR}/${P_FILE}"
debug "Output filename is ${OUTPUT_FILENAME}"

cd /tmp

if [ $ID_VIDEO_CODEC == "ffh264" ]; then

    # Commands for processing high-def file via avconv (creates an H264 file but resolution reduced down to 480p)
    avconv -i "${P_DIR}/${P_FILE}" -c:v libx264 -f mp4 -preset fast -crf 28 -s hd480 -metadata title="${CLIP_NAME}" "${OUTPUT_DIR}/${OUTPUT_FILENAME}.tmp" &>"/tmp/${P_FILE}_x264.log" </dev/null
    EXITCODE=$?
    if [ $EXITCODE -eq 0 ]; then
        rm -f "/tmp/${P_FILE}*.log"
        mv "${OUTPUT_DIR}/${OUTPUT_FILENAME}.tmp" "${OUTPUT_DIR}/${OUTPUT_FILENAME}"
        debug "Conversion complete - output file is ${OUTPUT_DIR}/${OUTPUT_FILENAME}"
    else
        # Pass failed
        debug "Oh dear - H264 encoding failed. Check /tmp/${P_FILE}_x264.log (last 5 lines appear below)"
        debug `tail -5 /tmp/${P_FILE}_x264.log`
        exit -1
    fi
       
else

    # Commands for processing standard-def file via avconv (creates an XVID MPEG4 file)
    avconv -i "${P_DIR}/${P_FILE}" -y -map 0:0 -map 0:1 -mbd rd -flags +mv4+aic -trellis 2 -cmp 2 -subcmp 2 -async 1 -filter scale=-1:360 -b 800k -ar 44100 -g 300 -vcodec mpeg4 -vtag xvid -acodec libmp3lame -metadata title="${CLIP_NAME}" -pass 1 -passlogfile "/tmp/${P_FILE}.log" -ab 128000 -r 25 -f avi "${OUTPUT_DIR}/${OUTPUT_FILENAME}.tmp" &>"/tmp/${P_FILE}_pass1.log" </dev/null
    EXITCODE=$?
    if [ $EXITCODE -eq 0 ]; then
        avconv -i "${P_DIR}/${P_FILE}" -y -map 0:0 -map 0:1 -mbd rd -flags +mv4+aic -trellis 2 -cmp 2 -subcmp 2 -async 1 -filter scale=-1:360 -b 800k -ar 44100 -g 300 -vcodec mpeg4 -vtag xvid -acodec libmp3lame -metadata title="${CLIP_NAME}" -pass 2 -passlogfile "/tmp/${P_FILE}.log" -ab 128000 -r 25 -f avi -y "${OUTPUT_DIR}/${OUTPUT_FILENAME}.tmp" &>"/tmp/${P_FILE}_pass2.log" </dev/null
   
        EXITCODE=$?
        if [ $EXITCODE -eq 0 ]; then
            rm -f "/tmp/${P_FILE}*.log"
            mv "${OUTPUT_DIR}/${OUTPUT_FILENAME}.tmp" "${OUTPUT_DIR}/${OUTPUT_FILENAME}"
            debug "Conversion complete - output file is ${OUTPUT_DIR}/${OUTPUT_FILENAME}"
        else
            # Pass 2 failed
            debug "Oh dear - pass 2 failed. Check /tmp/${P_FILE}_pass2.log (last 5 lines appear below)"
            debug `tail -5 /tmp/${P_FILE}_pass2.log`
            rm -f "${OUTPUT_DIR}/${OUTPUT_FILENAME}.tmp"
            exit -1
        fi
    else
        # Pass 1 failed
        debug "Oh dear - pass 1 failed. Check /tmp/${P_FILE}_pass1.log (last 5 lines appear below)"
        debug `tail -5 /tmp/${P_FILE}_pass1.log`
        exit -1
    fi

fi

exit 0

 

It has some package dependencies - namely avconv and mplayer. You'll need to edit the first 2 vars to match your destination directory where you want the converted files to be dropped, and the log file location. Usual advice around write permissions to both applies.

 

So what does it do? It examines the codec of the source recording to decide whether it is already H264 (and therefore likely a HD DVB-T recording) or plain MPEG2 (standard def DVB). This is kind of a hark back to days before I had high-def; I transcoded everything into MPEG4 DivX because I had some player devices that couldn't play H264. So the way the script works is it keeps high-def recordings in H264, but standard-def recordings are transcoded into DIVX. If you're happy to go entirely with H264 files, you could hack out the IF logic and just target the one avconv command.

 

Anyway, it derives a filename for you based on the MythTV title (and subtitle, if it exists) - and it will not overwrite existing files, instead adding an incrementing numerical on the end if such a scenario occurs. Useful when the EPG has the same title/subtitle for an entire programme series.

 

On transcoding, the resolution is decreased in order to compress the video files. On standard def recordings, the target vertical resolution is 360 pixels. For high-def, we target 480 vertical pixels. This is achieved with the "-filter scale=-1:360" and "-s hd480" avconv parameters respectively. You could tune this however you see fit. I actually have another script that keeps high quality, set up on one of the other user-configurable jobs. It's just a copy of this script but with different parameters so, when I choose to export from MythTV, I can choose a couple of target video profiles depending upon whether I'm fussed to keep good quality or not.

 

In MythTV, you will want to configure the user job call as follows :-

 

~mythtv/bin/userjob_exportToLQ.sh "%FILE%" "%DIR%" "%TITLE%" "%SUBTITLE%"

 

 

Obviously put the appropriate path to the shell script at the start...

 

Presto, there you go.

Ratings

Rating is available to Members only.

Please login or register to vote.

No Ratings have been Posted.
Render time: 0.05 seconds
231,141 unique visits