Friday, July 30, 2010

Creating text images via CLI on linux

Today I needed some text images. I could go to gimp and created it there, but I needed several and I really don't like repetitive work. The wonderful web is always your friend for these things.

So I found this blog that described creating a postscript page with enscript and converting this to a image format with convert. It boils down to the following command
$ echo "Some text" | enscript -B -f "Times-Roman36" -o - | convert -trim +repage -negate \
-border 2x2 -bordercolor gray - text.png

Enscript makes the postscript page. You can specify the font and the font size. (Enscript can do much much more then that (like creating tables), so be sure to check the manpage if you are interested in generating postscript files). With convert we trim it (remove whitespace around the text, so only the text remains and not a full page), negate it to make text white, make a 2 pixel border and make it gray. The result looks like this


Now I've used ImageMagick several times (I my opinion this is one hell of a CLI tool) and I think it was capable of generating text images itself (without the need of enscript). So I went throug the manpage and came op with the command
$ convert -background gray -fill white -font Times-Roman -pointsize 36 label:"Some text" \
text2.png

This produces:

Creating text with convert has much more possibilities. Have a look on the examples page for more info.
If you want to know which fonts are available, you can check the type-ghostscript file.
$ locate type-ghostscript.xml |grep ImageMagick
/usr/lib64/ImageMagick-6.5.8/config/type-ghostscript.xml
$ grep "type name=" /usr/lib64/ImageMagick-6.5.8/config/type-ghostscript.xml | sed -e \
's/.*type name=//' | awk '{print $1}'
"AvantGarde-Book"
"AvantGarde-BookOblique"
"AvantGarde-Demi"
"AvantGarde-DemiOblique"
"Bookman-Demi"
"Bookman-DemiItalic"
"Bookman-Light"
"Bookman-LightItalic"
"Courier"
"Courier-Bold"
"Courier-Oblique"
"Courier-BoldOblique"
"fixed"
"Helvetica"
"Helvetica-Bold"
"Helvetica-Oblique"
"Helvetica-BoldOblique"
"Helvetica-Narrow"
"Helvetica-Narrow-Oblique"
"Helvetica-Narrow-Bold"
"Helvetica-Narrow-BoldOblique"
"NewCenturySchlbk-Roman"
"NewCenturySchlbk-Italic"
"NewCenturySchlbk-Bold"
"NewCenturySchlbk-BoldItalic"
"Palatino-Roman"
"Palatino-Italic"
"Palatino-Bold"
"Palatino-BoldItalic"
"Times-Roman"
"Times-Bold"
"Times-Italic"
"Times-BoldItalic"
"Symbol"


You can always use a true type font on your system and use that
$ locate -r "\.ttf$"|grep -i liberation| grep -i mono
/usr/share/fonts/liberation/LiberationMono-Bold.ttf
/usr/share/fonts/liberation/LiberationMono-BoldItalic.ttf
/usr/share/fonts/liberation/LiberationMono-Italic.ttf
/usr/share/fonts/liberation/LiberationMono-Regular.ttf
$ convert -background gray -fill white -font /usr/share/fonts/liberation/LiberationMono-Bold.ttf -pointsize 36 label:"Some text" text3.png

Wednesday, July 28, 2010

transcoding for psp on linux

Now that my 32GB memory stick has arrived, it's time to fill it up. My previous was 4GB and was full with game data and no room left for video. Mpeg4(h264)/aac is the required video/audio codec for psp, so some transcoding has to be done.
So I dug up my mencoder options from my documentation database (a directory with flat txt files on which I use grep) and fire up mencoder. First error: no faac support, so no aac sound. Fixed this with an updated mencoder rpm (see http://haerench.blogspot.com/2010/07/mencoder-from-rpmfusion-with-aac.html).
Next attempt seems to be good. Transcoded a sample of 30 seconds (experience as a sysadmin has taught me to hope for the best, but prepare for the worst; so I test first).
$ mencoder dvd://1 -aid 128 -sws 9 -ss 120 -endpos 30 \
-vf pullup,softskip,dsize=480:272,scale=0:0,harddup,unsharp=l3×3:0.7 \
-ofps 24000/1001 \
-oac faac -faacopts br=128:mpeg=4:object=2:raw -channels 2 -srate 48000 \
-ovc x264 -x264encopts bitrate=500:global_header:partitions=all:trellis=1:level_idc=30 \
-of lavf -lavfopts format=psp -info name="some_movie" -o "psp_some_movie.mp4"

Copied sample to psp and try to play. Not good. Unsupported data says the PSP. The information screen tells me audio codec is ok, video resolution is ok, but video codec isn't recognized. Hmmm... why did a script that worked before produces now bad files? Last time I used it was on my PSP-1000, now I'm using a PSP-3000 after the analog stick broke on the PSP-1000. Is it a PSP-3000 thing? It shouldn't be, but you never know. Or is it a firmware thing that changed the video player behaviour (change is always good, isn't it?). Or is x264 broken in mencoder?
Ok I try other tools like h264enc which has presets for psp, searches the web for newer scripts (I find also some with -ovc lavc, which is also able to do mpge4/h264). But all fail, some with the same unsupported data, others give broken file and again other produce corrupt data.

Just when I was about to give up, I stumbled upon this blog http://blog.yogarine.com/2007/12/converting-video-for-psp-on-linux.html (which has a nice howto on transcoding for the PSP via avidemux (which you can also install with yum if you have rpmfusion enabled)). It's from 2007 but was updated in 2008 with changes to the video format after a PSP firmware update. Although some things are now less strict (like the framerate), some limitations were added: No reference b-frames and no 8x8 transform.
I first gave avidemux a try and after disabling 8x8 and b-franes in the video config, it produced a sample that was recognized by the PSP. Unfortunately avidemux lacked AAC support. I could do an avidemux recompile, but I'm more of a CLI guy anyway and with the found info I should get mencoder working. After some man paging I added x264encopts like bframes=0:partitions=none:no8x8dct. Transcoded a sample which played nice on the PSP. So the final config is now
$ mencoder dvd://1 -aid 128  -o video.mp4 \
-of lavf -lavfopts format=psp -info name="video_title" \
-ovc x264 \
-x264encopts bitrate=500:global_header:trellis=1:level_idc=30:bframes=0:partitions=none:no8x8dct \
-vf pullup,softskip,dsize=480:272,scale=0:0,harddup,unsharp=l3×3:0.7 \
-oac faac -faacopts br=128:mpeg=4:object=2:raw -channels 2 -srate 48000

If you prefer lavc to do the h264 encoding, you can use
$ mencoder dvd://1 -aid 128  -o video.mp4 \
-of lavf -lavfopts format=psp -info name="video_title" \
-ovc lavc -lavcopts vbitrate=500:aglobal=1:vglobal=1 \
-vf dsize=320:240:0:16,scale=0:0 \
-oac faac -faacopts br=128:mpeg=4:object=2:raw -channels 2 -srate 48000


In the second example there is also a different video filter option (-vf). You can also use the -vf options from the first example. Based on the resolution and options you like. Both examples are also 1-pass encodes. For me this is good enough to be viewed on the psp. If you intend to use the TV-out option of the PSP, then I suggest you encode to a larger resolution (720x480), use a higher bitrate (eg. 1000) and do 2 or 3-pass encoding.

mencoder from rpmfusion with aac support (libfaac)

Last night I wanted to do some transcoding for my psp on my fedora 13 box. Since psp video needs aac audio, I needed the option -oac faac. I use the mplayer and mencoder rpms from http://rpmfusion.org. In the old days I compiled mplayer myself, but why bother downloading and compiling tons of dependencies when rpmfusiom did already the fine work... Until now, although it's not rpmfusion to blame.
In 2009, it turned out that faac was not GPL. So to avoid license issues mplayer and mencoder is now compiled without libfaac (since they are part of the rpmfusion free). So I downloaded the src rpm and did a rebuild with faac
$ wget http://download1.rpmfusion.org/free/fedora/updates/13/SRPMS/mplayer-1.0-0.117.20100703svn.fc13.src.rpm
$ rpmbuild --rebuild --with faac ./mplayer-1.0-0.117.20100703svn.fc13.src.rpm


Turned out that a lot of devel pkgs were missing (as expected). So made a quick list of extra pkgs to install.

$ rpmbuild --rebuild --with faac ./mplayer-1.0-0.117.20100703svn.fc13.src.rpm 2>&1 |grep needed|awk '{print $1}' | xargs
a52dec-devel aalib-devel cdparanoia-devel em8300-devel enca-devel fribidi-devel ladspa-devel lame-devel libcaca-devel libdca-devel libdv-devel libdvdnav-devel libmpcdec-devel libmpeg2-devel libtheora-devel libvdpau-devel libvpx-devel lirc-devel live555-devel lzo-devel pulseaudio-lib-devel schroedinger-devel speex-devel twolame-devel x264-devel xvidcore-devel yasm opencore-amr-devel
$ yum install a52dec-devel aalib-devel cdparanoia-devel em8300-devel enca-devel fribidi-devel ladspa-devel lame-devel libcaca-devel libdca-devel libdv-devel libdvdnav-devel libmpcdec-devel libmpeg2-devel libtheora-devel libvdpau-devel libvpx-devel lirc-devel live555-devel lzo-devel pulseaudio-lib-devel schroedinger-devel speex-devel twolame-devel x264-devel xvidcore-devel yasm opencore-amr-devel


After that the rpmbuild command ran fine. Afterwards you can install the new mencoder rpm from the rpmbuild directory. Use --force to overwrite the current one.
$ rpm -ivh --force ~/rpmbuild/RPMS/x86_64/mencoder-1.0-0.117.20100703svn.fc13.x86_64.rpm


Now you have mencoder with faac support....