Saturday, November 15, 2008

Playing AVCDH content on Blu-ray Players

I spent a little too much time today fiddling around with technology. Ever since I bought a Sony AVCHD camcorder I've been bugged that I haven't been able to just dump the .MTS files it creates straight onto a DVD and throw it in the Blu-ray player. The video quality on the camera is fantastic and it seems a shame to downcovert it and watch it in typical DVD format. Not only that, downconverting that content takes forever.

So... for all of you who don't want to waste an entire spindle of DVDs and a precious afternoon that could have been put to good use like snowboarding, I'm going to attach a little script that will set you up. All you have to do is burn the image file onto a disc when its done running.

Hardware:
Sony CX-12 AVCHD camcorder (I think every AVCHD camcorder on the market will work with this approach)
Sony BDP-S550 Blu-ray player (The player needs to read DVDs and DVD DLs if you have 8gb flash cards in your camera)

OS:
Mac OS 10.5. Linux with newfs_udf util should work too.

Note:
I would recommend 4gb cards in the camera. 4gb is a good 30 minutes of video. Nobody wants to watch the entire fourth-grade christmas concert anyway.

When you plug the card in, it will show up as a volume. Usually /Volumes/Untitled. From there, run the script ./MakeBluRay.sh. There are some arguments and I didn't do a ton to make this script robust. It covers the bases.

s=size in MB (Default is 4096)
d=image file directory
n=new volume name (default is AVCHD)
f=image file name (default is tmp)
v=source volume (default is /Volumes/Untitled)
h=help

So ./MakeBluRay.sh -s 100 -d ~/VideoBackUp -f 11-13-08 will create a 100mb file called 11-13-08.img in the ~/VideoBackUp directory.

Here is the script:


#!/bin/sh



#Default volume size in MB
base_size="4096"

#Default image location - the current directory
img_file_dir="."

#Default image file name
img_file_name="tmp"

#Target volume name
new_volume_name="AVCHD"

#Destination volume name
new_volume_location=""

#Source Volume location
source_volume="/Volumes/Untitled"

#parse arguments
while getopts "h:s:d:n:f:v:" optionName; do
case "$optionName" in
h) printHelpAndExit 0;;
s) base_size="$OPTARG";;
d) img_file_dir="$OPTARG";;
n) new_volume_name="$OPTARG";;
f) img_file_name="$OPTARG";;
v) source_volume="$OPTARG";;
\?) echo "Valid options are\ns=size in MB (Default is 4096)\nd=image file directory\nn=new volume name (default is AVCHD)\nf=image file name (default is tmp)\nv=source volume (default is /Volumes/Untitled)\nh=help" >&2
exit 1
;;
:) echo "Option -$OPTARG requires an argument" >&2
exit 1
;;
esac
done


#test validity of source and destinations
echo "Source volume is $source_volume"
if [ ! -d $source_volume ]
then
echo "Source Directory of $source_volume does not exist"
exit 1
fi
if [ ! -d $source_volume/AVCHD/BDMV ]
then
echo "Source Directory of $source_volume does not contain a BDMV source"
exit 1
fi

#Create an image file matching the size of arg z
echo "Disc Image size will be $base_size"
echo "Disc Image location will be $img_file_dir/$img_file_name.img"
echo "Creating new image file. This may take a few minutes..."
dd if=/dev/zero of="$img_file_dir/$img_file_name.img" bs=$((1024 * 1024)) count=$base_size

#Create a UDF FS from the image with the volume name of arg n
echo "Creating a UDF FS on $img_file_dir/$img_file_name.img with volume name of $new_volume_name"
newfs_udf -r 2.5 "$img_file_dir/$img_file_name.img" -v $new_volume_name

#Mount the image file
hdiutil mount -nobrowse "$img_file_dir/$img_file_name.img"

#copy files from source volume to the newly mounted image file
echo "Copying source materials to new image file. This may take a several minutes..."
cp -R $source_volume/AVCHD/* /Volumes/$new_volume_name/

#Rename source files
echo "Renaming source files"
for f in /Volumes/$new_volume_name/BDMV/STREAM/*MTS
do
nf=`basename $f MTS`m2ts
echo "$f and $nf"
mv $f /Volumes/$new_volume_name/BDMV/STREAM/$nf
done

#INDEX Files
echo "Renaming clip and index files"
mv /Volumes/$new_volume_name/BDMV/INDEX.BDM /Volumes/$new_volume_name/BDMV/index.bdmv
mv /Volumes/$new_volume_name/BDMV/MOVIEOBJ.BDM /Volumes/$new_volume_name/BDMV/MovieObject.bdmv

#Clip Files
echo "Renaming clip files"
for f in /Volumes/$new_volume_name/BDMV/CLIPINF/*CPI
do
nf=`basename $f CPI`clpi
echo "$f and $nf"
mv $f /Volumes/$new_volume_name/BDMV/CLIPINF/$nf
done

#MPL Files
echo "Renaming mpl files"
for f in /Volumes/$new_volume_name/BDMV/PLAYLIST/*MPL
do
nf=`basename $f MPL`mpls
echo "$f and $nf"
mv $f /Volumes/$new_volume_name/BDMV/PLAYLIST/$nf
done

#Blu Ray Compliance
mkdir /Volumes/$new_volume_name/BDMV/BDJO
mkdir /Volumes/$new_volume_name/BDMV/JAR
mkdir /Volumes/$new_volume_name/BDMV/AUXDATA
mkdir /Volumes/$new_volume_name/BDMV/BACKUP
mkdir /Volumes/$new_volume_name/BDMV/BACKUP/BDJO
mkdir /Volumes/$new_volume_name/CERTIFICATE
mkdir /Volumes/$new_volume_name/CERTIFICATE/BACKUP
cp /Volumes/$new_volume_name/BDMV/*.bdmv /Volumes/$new_volume_name/BDMV/BACKUP/
cp -R /Volumes/$new_volume_name/BDMV/PLAYLIST /Volumes/$new_volume_name/BDMV/BACKUP/
cp -R /Volumes/$new_volume_name/BDMV/CLIPINF /Volumes/$new_volume_name/BDMV/BACKUP/

#Unmount the image
hdiutil unmount /Volumes/$new_volume_name

echo "Success... you can now burn this with Disk Utility"