I guess I'll post mine too. My encodes are not publication quality as they don't include any subtitles or intro etc., but they are quite high on the automation scale. It only works on smv and fm2 for now, though.
After I've downloaded an .smv file, the encoding process looks like this:
Language: bash
$ smvenc2 foo.smv foo.mkv
That produces a lossless yuv444 encode at normal resolution. If I want to use a lua script with that, and perhaps have a double-sized yuv420 encode, I would do
Language: bash
$ smvenc2 -lua script.lua -fmt yuv420 foo.smv foo.mkv
The encode is totally headless. That is, no snes9x window pops up during encoding, and no sound is played (but of course, the output video contains sound and image), so this can be run on a system with no running X server, which is nice for making an automated encoding service as I did before at one time.
The script itself looks like this (
link):
Language: bash
#!/usr/bin/env bash
# Automatic smv encode. Given an smv file and and output filename,
# produces a lossless encode in one pass
player="smv"
popts="-r 5 -mute -dumpstreams"
prefix=".smvenc"
afifo="audiostream0.dat"
vfifo="videostream0.dat"
afile="$prefix.audio.mp3"
vfile="$prefix.video.mkv"
fmt="yuv444"
double="auto"
proginterval=0.5
# My snes9x has problems with complicated file names due to the
# dchshell wrapper, so copy things to simple names in the work dir.
worksmv="$prefix.work.smv"
workmkv="$prefix.work.mkv"
worklua="$prefix.work.lua"
qp=0
function show_help()
{
echo "smvenc2: Encode smv files to mkv
Syntax: smvenc2 [options] in.smv out.mkv
Options:
-lua script.lua: Run with this lua script.
-v: Verbose mode: Show output from subcommands.
-frames: Output video will be this many frames long.
-qp: Encode with this qp. Default is 0 (lossless).
-fmt: Color format to use. Rgb, yuv444 or yuv420.
-2: Double size before encoding. Useful with yuv420.
-1: Do not double size.
-0: Determine doubling automatically based on color format.
-h: Display this help."
}
# Parse arguments
nf=0
args=()
argv=("$@")
for (( i=0; i <argv>&2; exit ;;
*) args[$nf]="${argv[$i]}" ; nf=$(($nf+1)) ;;
esac
done
case "$fmt" in
rgb) fmtcmd="--output-csp rgb" ;;
yuv444) fmtcmd="--output-csp i444" ;;
yuv420) fmtcmd="--output-csp i420"
if [[ "$double" == "auto" ]]; then double="yes"; fi;;
*) echo "Invalid format $fmt" >&2; exit ;;
esac
if [[ $double == yes ]]; then resize="--vf resize:512,448,method=point"; fi
smvfile="${args[0]}"
outfile="${args[1]}"
frames="$(bread "$smvfile" 16 4)"
frames=$((frames+1000))
if [[ $frames_override ]]; then frames=$frames_override; fi
# Prepare work directory
cp "$smvfile" "$worksmv"
if [[ $lua ]]; then cp "$lua" "$worklua"; luacmd="-loadlua $worklua"; fi
rm -f "$afifo"; mkfifo "$afifo"
rm -f "$vfifo"; mkfifo "$vfifo"
popts="$popts $luacmd"
junkdev=/dev/null
if [[ $verbose ]]; then junkdev=/dev/stderr; fi
# Be ready to clean up
trap 'kill $xvfb $ppid $apid $vpid $spid 2>/dev/null
rm -f "$vfile" "$afile" "$worksmv" "$worklua" "$workmkv" "$afifi" "$vfifo" ' EXIT
# Don't display anything
display=":40.1"
Xvfb "$display" -screen 1 800x600x24 >$junkdev 2>&1 &
xvfb=$!
export DISPLAY="$display"
function progreport
{
while true; do
s=$(stat -c %s "$afile" 2>/dev/null)
rsec=$((s/96/1024*8))
h=$((rsec/3600))
m=$((rsec/60-h*60))
s=$((rsec-h*3600-m*60))
if [[ ! $verbose ]]; then
printf "\b\b\b\b\b\b\b\b%2d:%02d:%02d" $h $m $s; fi
sleep $proginterval
done
}
# Start producing output
"$player" "$worksmv" $popts -maxframes $frames >$junkdev 2>&1 &
ppid=$!
# Encode audio
lame -r -s 32 -h "$afifo" "$afile" >$junkdev 2>&1 &
apid=$!
# Encode video
x264 --input-csp bgra --input-res 256x224 --range pc --colormatrix bt470bg $fmtcmd $resize -o "$vfile" "$vfifo" --qp $qp --preset veryslow --fps 60.0375 >$junkdev 2>&1 &
vpid=$!
# Progress report
progreport >&2 2>/dev/null&
spid=$!
wait $ppid $apid $vpid
{ kill $spid $xvfb; wait $spid $xvfb; } 2>/dev/null
# And merge them together
mkvmerge -o "$outfile" "$vfile" "$afile" >$junkdev 2>&1
rm -f "$vfile" "$afile" "$worksmv" "$worklua" "$workmkv" "$afifi" "$vfifo"
printf "\ndone\n"
This depends on a couple of other utilities. The "smv" is a script I use for watching smv files. It handles the automatic lookup of the rom and then runs snes9x (
link):
Language: bash
#!/usr/bin/env bash
index="$HOME/tas/snes/index"
snes=snes9x-1.43
smvfile="$1"
shift
echo n | "$snes" "$index/$(smvcrc "$smvfile")" -autodemo "$smvfile" "$@"
There are some other short utilities that are needed, but the forum mangles them, so I'll just link to them instead:
smvcrc is used to extract a crc from an smv file, for the purpose of looking up the correct rom.
romcrc is used to compute the crc of a snes rom, wihch is used to poulate a directory of crc -> rom symlinks.
bread is used to read the frame count from the smv file.
For fm2 files I use a similar setup
fm2enc,
fm2,
fm2md5,
nesmd5
The md5 stuff is mostly extracted from fceux.