Log in

View Full Version : tweaking script to convert matroska to mpeg4 for PS3. Need advice.


beijingjj
1st April 2009, 01:10
I found a pretty good script (for linux) to convert matroska files to mpeg4 playable on the PS3. I have modded it a bit to use tools available on my system and the script is running successfully, however the resultant file is still not supported by the PS3. Let me show you the before and after.

BEFORE:
MPlayer SVN-r28734-4.1.2 (C) 2000-2009 MPlayer Team

Playing file.mkv.
[mkv] Track ID 1: video (V_MPEG4/ISO/AVC), -vid 0
[mkv] Track ID 2: audio (A_AC3), -aid 0, -alang und
[mkv] Will play video track 1.
Matroska file format detected.
VIDEO: [avc1] 1280x720 24bpp 23.976 fps 0.0 kbps ( 0.0 kbyte/s)
==========================================================================
Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family
Selected video codec: [ffh264] vfm: ffmpeg (FFmpeg H.264)
==========================================================================
==========================================================================
Opening audio decoder: [liba52] AC3 decoding with liba52
Using SSE optimized IMDCT transform
Using MMX optimized resampler
AUDIO: 48000 Hz, 2 ch, s16le, 384.0 kbit/25.00% (ratio: 48000->192000)
Selected audio codec: [a52] afm: liba52 (AC3-liba52)
==========================================================================
AO: [alsa] 48000Hz 2ch s16le (2 bytes per sample)
Starting playback...


AFTER:

MPlayer SVN-r28734-4.1.2 (C) 2000-2009 MPlayer Team

Playing testme.mp4.
libavformat file format detected.
[lavf] Video stream found, -vid 0
[lavf] Audio stream found, -aid 1
VIDEO: [avc1] 1280x720 24bpp 23.976 fps 0.0 kbps ( 0.0 kbyte/s)
==========================================================================
Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family
Selected video codec: [ffh264] vfm: ffmpeg (FFmpeg H.264)
==========================================================================
==========================================================================
Opening audio decoder: [faad] AAC (MPEG2/4 Advanced Audio Coding)
FAAD: compressed input bitrate missing, assuming 128kbit/s!
AUDIO: 48000 Hz, 2 ch, s16le, 128.0 kbit/8.33% (ratio: 16000->192000)
Selected audio codec: [faad] afm: faad (FAAD AAC (MPEG-2/MPEG-4 Audio))
==========================================================================
AO: [alsa] 48000Hz 2ch s16le (2 bytes per sample)
Starting playback...

So basically the video is unchanged but the audio has been re-encoded as AAC and then the whole thing remuxed into an mp4 package. It plays fine with mplayer but the PS3 still doesn't like it. According to what I've read online, the PS3 should support H.264 video and AAC audio. Perhaps there is some minor aspect of my mpeg4 container it doesn't like?

I would love to hear any ideas.

Thanks.

Adub
1st April 2009, 03:38
Bahahahaha!!! Sorry, I just like how you post a playback log like you have above and claim that it shows the difference between two different encodes, and then additionally claim that the video is "unchanged".

If you want more help, post your script. We need to actually know what settings you used to encode your sources instead of what settings you used to play it in mplayer.

dat720
1st April 2009, 12:53
Kind of hard to offer advise on a script without first seeing said script!

beijingjj
1st April 2009, 14:17
Hey now, it is the newbie forum after all...

Here's the script. Original author info in the comments at the top, but I replaced some commands to accommodate my gentoo system, commented some extras out (like normalize-audio). At any rate, I stick by my claim that the video is unchanged, but I await further constructive criticism...:)

#!/bin/bash

# Phil Dufault (2008-2009) phil@dufault.info
# http://dufault.info

# TODO:
# add getopts-style arguments? -d|--debug to enable debug, aka not delete the log?
# -r to delete the source file after remuxing?
# add mkv splitting support for files above 4GB

VERSION="0.5.3"

log="$PWD/log.$(date +%T-%F).txt"

cecho() {
echo -e "$1"
echo -e "$1" >>"$log"
tput sgr0;
}

ncecho () {
echo -ne "$1"
echo -ne "$1" >>"$log"
tput sgr0
}

sp="/-\|"
spinny () {
echo -ne "\b${sp:i++%${#sp}:1}"
}

progress () {
ncecho " ";
while [ /bin/true ]; do
kill -0 $pid 2>/dev/null;
if [[ $? = "0" ]]; then
spinny
sleep 0.25
else
ncecho "\b\b";
wait $pid
retcode=$?
echo "$pid's retcode: $retcode" >> "$log"
if [[ $retcode = "0" ]]; then
cecho success
else
cecho failed
echo -e " [i] Showing the last 5 lines from the logfile ($log)...";
tail -n5 "$log"
exit 1;
fi
break 2;
fi
done
}

cecho " [x] reMuxToMP4 script, v$VERSION, written by Phil Dufault\n [x] Contact him at: http://www.dufault.info"

if [[ $# -lt 1 ]];
then
cecho ' [i] Please supply a filename to remux to MP4, and the target filename optionally';
exit 1;
fi

for i in mplayer mencoder mkvinfo mkvextract mp4creator; do
if hash -r "$i" >/dev/null 2>&1; then
ncecho;
else
cecho " [i] The $i command is not available, please install the required packages.";
DIE=1;
fi
done

if [[ $DIE ]]; then
cecho " [i] Needed programs weren't found, exiting...";
exit 1;
fi

SOURCE=$1
if [[ -z $2 ]];
then
DEST="${1%.*}.mp4"
else
DEST=$2
fi
shift 2;

cecho " [x] Source filename: $SOURCE\n [x] Destination filename: $DEST";

if [[ -f $DEST ]];
then
cecho ' [i] Destination filename already exists -- please delete and rerun the script, or select another destination';
exit 1;
fi

identify() {
mplayer -frames 0 -identify -ao null -vo null "$SOURCE" 2>/dev/null > /tmp/info.$$.txt
grep ^ID_VIDEO /tmp/info.$$.txt >/dev/null && VIDEO=1
grep ^ID_AUDIO /tmp/info.$$.txt >/dev/null && AUDIO=1

WIDTH=$(grep ^ID_VIDEO_HEIGHT /tmp/info.$$.txt | sed 's/^ID_VIDEO_HEIGHT=//g')
HEIGHT=$(grep ^ID_VIDEO_WIDTH /tmp/info.$$.txt | sed 's/^ID_VIDEO_WIDTH=//g')
FPS=$(grep ^ID_VIDEO_FPS /tmp/info.$$.txt | sed 's/^ID_VIDEO_FPS=//g')
VIDEO_CODEC=$(grep ^ID_VIDEO_CODEC /tmp/info.$$.txt | awk -F= '{print $2}')
AUDIO_CHANNELS=$(grep ^ID_AUDIO_NCH /tmp/info.$$.txt | sort -r | head -n1 | awk -F= '{print $2}')
AUDIO_CODEC=$(grep ^ID_AUDIO_CODEC /tmp/info.$$.txt | awk -F= '{print $2}')
DEMUXER=$(grep ^ID_DEMUXER /tmp/info.$$.txt | awk -F= '{print $2}')
rm -f /tmp/info.$$.txt

size=$(du -m $SOURCE | awk '{print $1}');
if [[ -z $VIDEO ]];
then
cecho " [-] Missing a video stream -- please check the source file.";
exit 1;
else
cecho " [x] Video stream found, $HEIGHT x $WIDTH @ $FPS fps, using $VIDEO_CODEC";
fi

if [[ -z $AUDIO ]];
then
cecho " [-] Missing a audio stream -- please check the source file.";
exit 1;
else
cecho " [x] Audio stream found, $AUDIO_CHANNELS audio channels, using $AUDIO_CODEC";
fi
cecho " [x] Muxed in $DEMUXER format, source file is ${size}MB";
}

dumpAndReencodeAudio() {
ncecho " [x] Dumping the audio...";

AUDIOTRACKNUM=$(mkvinfo "$SOURCE" | grep -B2 "Track type: audio" |head -n1|awk -F": " '{print $2}')
mkvextract tracks "$SOURCE" $AUDIOTRACKNUM:"$DEST.audio"
if [[ $AUDIO_CODEC = "faad" ]];
then
echo converting faad audio
faad -d -o "$DEST.wav" "$DEST.audio"
else
echo converting non-faad audio
mplayer "$DEST.audio" -vo null -vc null -ao "pcm:fast:file=$DEST.wav" -channels 2 -af volnorm
fi

# mplayer "$SOURCE" -vo null -vc null -ao "pcm:fast:file=$DEST.wav" -channels 2 >>"$log" 2>&1 &
# pid=$!;progress $pid

# ncecho " [x] Normalizing the audio...";
# normalize-audio --peak "$DEST.wav" >>"$log" 2>&1 &
# pid=$!;progress $pid

ncecho " [x] Encoding the audio to low-complexity AAC...";
faac --mpeg-vers 4 $DEST.wav
# neroAacEnc -lc -if "$DEST.wav" -of "$DEST.m4a" >>"$log" 2>&1 &
# pid=$!;progress $pid

rm -f "$DEST.wav"
# ncecho " [x] Extracting audio from MP4 container (silly neroAacEnc)...";
# mp4creator --extract=1 "$DEST.m4a" >>"$log" 2>&1 &
# pid=$!;progress $pid

# mv "${DEST}.m4a.t1" "$DEST.aac"
# rm -f "$DEST.m4a"
AUDIO_FILE="$DEST.aac"
}

dumpVideo() {
if [[ $DEMUXER = "mkv" ]]; then
ncecho " [x] Extracting the video from the mkv...";
TRACKNUM=$(mkvinfo "$SOURCE" | grep -B2 "Track type: video"|head -n1|awk -F": " '{print $2}')
mkvextract tracks "$SOURCE" "$TRACKNUM":"$DEST.264" >>"$log" 2>&1 &
else
cecho " [x] Dumping the video...failed\n [i] This aspect of the script is still broken, dying.";
exit 1;
fi
pid=$!;progress $pid
VIDEO_FILE="$DEST.264"
# ncecho " [x] Changing the h264 video stream profile from 5.1 to 4.1...";
# bbe -e "r 7 \41" --output="$VIDEO_FILE.new" "$VIDEO_FILE" >>"$log" 2>&1 &
# pid=$!;progress $pid
# ncecho " [x] Deleting the old video source...";
# rm -f "$VIDEO_FILE" >>"$log" 2>&1 &
# pid=$!;progress $pid
# ncecho " [x] Moving new video stream to proper filename...";
# mv "$VIDEO_FILE.new" "$VIDEO_FILE" >>"$log" 2>&1 &
# pid=$!;progress $pid
}

mux() {
ncecho " [x] Muxing video stream at $FPS fps...";
mp4creator --create="$VIDEO_FILE" "$DEST" -r "$FPS" >>"$log" 2>&1 &
pid=$!;progress $pid

ncecho " [x] Muxing the audio stream in...";
mp4creator --create="$AUDIO_FILE" "$DEST" >>"$log" 2>&1 &
pid=$!;progress $pid

ncecho " [x] Deleting audio and video tempfiles...";
rm -f "$VIDEO_FILE" "$AUDIO_FILE" >>"$log" 2>&1 &
pid=$!;progress $pid
}

finish() {
cecho " [o] All done!";
}

identify;
if [[ $VIDEO_CODEC = "ffh264" ]]; then
dumpAndReencodeAudio;
dumpVideo;
mux;
else
cecho " [i] Video is not in h264 stream!";
exit 0;
fi
finish;

rm -f "$log"

RunningSkittle
1st April 2009, 14:24
serving to ps3 over network?

beijingjj
1st April 2009, 15:33
Yes, although I also tried it directly through usb.

Anyhow, I need to use the fire extinguisher before I get flamed too much more. I noticed I commented out one command which could turn out to be vital. It is the bbe command which is replacing (from what I can tell) the 7th byte in the video stream. I remember reading somewhere before that this is important. I'm trying to find bbe (or equivalent) to install on my machine and try again with this missing step.

beijingjj
2nd April 2009, 00:32
Well, I tried again with the bbe command to change the byte in the video stream and same result. To make it a little more likely that someone may help, I have extracted just the meaty commands from the script above and pasted them here:

mplayer -frames 0 -identify -ao null -vo null "$SOURCE" 2>/dev/null > /tmp/info.$$.txt
grep ^ID_VIDEO /tmp/info.$$.txt >/dev/null && VIDEO=1
grep ^ID_AUDIO /tmp/info.$$.txt >/dev/null && AUDIO=1

WIDTH=$(grep ^ID_VIDEO_HEIGHT /tmp/info.$$.txt | sed 's/^ID_VIDEO_HEIGHT=//g')
HEIGHT=$(grep ^ID_VIDEO_WIDTH /tmp/info.$$.txt | sed 's/^ID_VIDEO_WIDTH=//g')
FPS=$(grep ^ID_VIDEO_FPS /tmp/info.$$.txt | sed 's/^ID_VIDEO_FPS=//g')
VIDEO_CODEC=$(grep ^ID_VIDEO_CODEC /tmp/info.$$.txt | awk -F= '{print $2}')
AUDIO_CHANNELS=$(grep ^ID_AUDIO_NCH /tmp/info.$$.txt | sort -r | head -n1 | awk -F= '{print $2}')
AUDIO_CODEC=$(grep ^ID_AUDIO_CODEC /tmp/info.$$.txt | awk -F= '{print $2}')
DEMUXER=$(grep ^ID_DEMUXER /tmp/info.$$.txt | awk -F= '{print $2}')

AUDIOTRACKNUM=$(mkvinfo "$SOURCE" | grep -B2 "Track type: audio" |head -n1|awk -F": " '{print $2}')
mkvextract tracks "$SOURCE" $AUDIOTRACKNUM:"$DEST.audio"
if [[ $AUDIO_CODEC = "faad" ]];
then
echo converting faad audio
faad -d -o "$DEST.wav" "$DEST.audio"
else
echo converting non-faad audio
mplayer "$DEST.audio" -vo null -vc null -ao "pcm:fast:file=$DEST.wav" -channels 2 -af volnorm
fi
ncecho " [x] Encoding the audio to low-complexity AAC...";
faac --mpeg-vers 4 $DEST.wav
AUDIO_FILE="$DEST.aac"

TRACKNUM=$(mkvinfo "$SOURCE" | grep -B2 "Track type: video"|head -n1|awk -F": " '{print $2}')
mkvextract tracks "$SOURCE" "$TRACKNUM":"$DEST.264" >>"$log" 2>&1 &
VIDEO_FILE="$DEST.264"
ncecho " [x] Changing the h264 video stream profile from 5.1 to 4.1...";
bbe -e "r 7 \41" --output="$VIDEO_FILE.new" "$VIDEO_FILE" >>"$log" 2>&1 &

mp4creator --create="$VIDEO_FILE" "$DEST" -r "$FPS" >>"$log" 2>&1 &
mp4creator --create="$AUDIO_FILE" "$DEST" >>"$log" 2>&1 &

dat720
2nd April 2009, 09:08
So from what i can see this script demuxes a mkv and remuxes it to mp4 with aac audio, the probabolity is that your mkv does not have a PS3 compatible h264 stream in it....

I'd be running your video through a speciffic PS3 encoding script then comparing the streams...

I also notice that you have modded the script, try with a unmodded script and install the required packages, authors usually choose to use certain packages for a reason!

But the next question is why are you remuxing mkv's why don't you just recode your original disc?

beijingjj
2nd April 2009, 14:11
So from what i can see this script demuxes a mkv and remuxes it to mp4 with aac audio, the probabolity is that your mkv does not have a PS3 compatible h264 stream in it....

Would you happen to know what makes an H.264 stream compatible with the PS3?

I'd be running your video through a speciffic PS3 encoding script then comparing the streams...

Do you have such a script to recommend?

But the next question is why are you remuxing mkv's why don't you just recode your original disc?
Indeed, why not just play the discs directly on the PS3, eh? Good idea.

beijingjj
2nd April 2009, 16:00
To all those who found this thread looking for a good solution: This media server (http://code.google.com/p/ps3mediaserver/downloads/list), mentioned in another thread in this forum, works wonderfully and transcodes mkv files on the fly so that you can watch them on your PS3.

I still wish I could learn the intricacies of what makes one file work on the PS3 and another not, but it doesn't seem as though I will find that information easily.

Happy encode, decoding, archiving, and viewing everyone.

dat720
3rd April 2009, 07:57
Unfortunetly i can not provide you with a bash script, i do know there is one i think it maybe called PS3convert or somethign similar....

Here is my mencoder command that spits out perfectly compatible h264 streams:

"%menpath%\mencoder.exe" %1 -vf harddup -ovc x264 -x264encopts crf=19:frameref=3:bframes=3:b_pyramid:direct_pred=auto:weight_b:partitions=all:8x8dct:me=umh:mixed_refs:brdo:bime:trellis=1:nopsnr:nossim:subq=6:level_idc=41:threads=auto -oac copy -of rawvideo -o "%~dpn1.crf.264"

beijingjj
4th April 2009, 08:12
Does this write the audio to a separate file? What do you use to remux them, or why not let mencoder do it?

dat720
4th April 2009, 22:19
because mencoder can't write m2ts files......
I use m2ts for BD and HD as it allows the use of ac3 audio, rather than having to convert to aac audio which my logitech z5500's can't decode