Thursday, December 22 2011, 07:09 am

Crossing the Streams to the Playstation 3 (part 2)

Lets say you have downloaded some TV shows. I won't ask where you got them, but I will show you how to play them on the PS3 through Mediatomb. This will require the patches mentioned in the part 1 post as video playing is pretty stupid without them.

First off, Mediatomb needs to know what to do with .mkv files on your computer. The PS3 has no idea how to play Matroska containers unfortunately. It would be a simple and free (as in speech) for Sony to implement, but that's too hard for them to do without money or IP rights in their favor. The following settings will tell Mediatomb to stream MKV files as MPEG files and use ffmpeg to transcode.

/etc/mediatomb/config.xml

<extension-mimetype ignore-unknown="no">
    <map from="mkv" to="video/x-matroska"/>
    ... other maps already exist, don't delete them ...
</extension-mimetype>
... skip down to the <profiles> tag and add this block...
<profile name="video-matroska" enabled="yes" type="external">
    <mimetype>video/mpeg</mimetype>
    <accept-url>no</accept-url>
    <first-resource>yes</first-resource>
    <hide-original-resource>yes</hide-original-resource>
    <agent command="ffmpeg-tr" arguments="%in %out %range" />
    <buffer size="10485760" chunk-size="524288" fill-size="0"/>
</profile>

The following are a few "ffmpeg-tr" script file examples. Ffmpeg has a few options as I have come to find out that the PS3 is a bit picky at video encodings. If you do not have a flawlessly encoded file the PS3 will most likely not play the file.

The first example will require a fast machine (at least 4 cores) as it reencodes the video into a fresh H.264 stream and leaves the audio intact. Use this if the video file you have is skipping or not even playing on the PS3.

/usr/local/bin/ffmpeg-tr

#!/bin/bash

START_SECONDS=`echo "$3" | awk '{split($0,a,"-"); print a[1]}'`
MILLISECONDS=`echo "$START_SECONDS" | awk '{split($0,a,"."); print a[2]}'`
START_TIME=`echo $START_SECONDS | awk '{print strftime("%H:%M:%S", $0,1)}'`
START="$START_TIME.$MILLISECONDS"
END_SECONDS=`echo "$3" | awk '{split($0,a,"-"); print a[2]}'`
if [ -z $END_SECONDS ]
then
MILLISECONDS=`echo "$END_SECONDS" | awk '{split($0,a,"."); print a[2]}'`
END_TIME=`echo $END_SECONDS | awk '{print strftime("%H:%M:%S", $0,1)}'`
END="$END_TIME.$MILLISECONDS"
fi

exec /usr/bin/ffmpeg -threads 4 -r 24000/1001 -i "$1" -vcodec libx264 -b 8000k -preset faster -level 41 -r 24000/1001 -vsync 1 -acodec copy -async 1 -f mpegts - > "$2"

If your video file is in good shape, then you can get away without encoding anything. Most .mkv files are already in video formats the PS3 will play (h.264 video, AC3/Dolby audio) so you can get away with a direct copy of the data. This requires very little computing power so any computer can do this.

/usr/local/bin/ffmpeg-tr

#!/bin/bash

START_SECONDS=`echo "$3" | awk '{split($0,a,"-"); print a[1]}'`
MILLISECONDS=`echo "$START_SECONDS" | awk '{split($0,a,"."); print a[2]}'`
START_TIME=`echo $START_SECONDS | awk '{print strftime("%H:%M:%S", $0,1)}'`
START="$START_TIME.$MILLISECONDS"
END_SECONDS=`echo "$3" | awk '{split($0,a,"-"); print a[2]}'`
if [ -z $END_SECONDS ]
then
MILLISECONDS=`echo "$END_SECONDS" | awk '{split($0,a,"."); print a[2]}'`
END_TIME=`echo $END_SECONDS | awk '{print strftime("%H:%M:%S", $0,1)}'`
END="$END_TIME.$MILLISECONDS"
fi

exec /usr/bin/ffmpeg -threads 4 -i "$1" -vcodec copy -vbsf h264_mp4toannexb -acodec copy -copyts -copytb -f mpegts - > "$2"

You can also mix and match between re-encoding audio only or both video and audio.