Daniel Guerrero Thoughts

Monday, November 28, 2005

Amazing ffmpeg

So, there is a boom for video, you can see on youtube.com the next major on the media, flash streaming as "universal" format for web playing; I have to say that is a really, really good idea.

On the other side, there is a lot of 'funny videos' and 'jackass kind' of videos on a lot of sites, one of these sites I like too much is: ebaumsworld.com, but ok let's go the facts =).

To process info about a video, you need an api to access this; in this case there is a GPL library: ffmpeg (Mplayer use it). I have a mac, so I wanted to test on my mac instead on my linux box, so I download the ffmpeg sources (from cvs since the stable version didn't work) to compile I change it to 3.3 version:

phobos:~/Desktop/downloads/ffmpeg danguer$ sudo gcc_select 3.3
Password:
You are already using gcc version 3.3 as the default compiler.
phobos:~/Desktop/downloads/ffmpeg danguer$ ./configure --prefix=/sw --enable-shared


I use the /sw since I have fink working on my mac, then I compiled and installed: make && sudo make install

Then I downloaded the ffmpeg-php extension to use ffmpeg into my php scripts.
For me only worked if you hack a bit the configure script, follow the steps (phpize if you want as extension to load), and before you make ./configure change the configure file from:

echo "$as_me:$LINENO: checking for ffmpeg libavcodec.so" >&5
echo $ECHO_N "checking for ffmpeg libavcodec.so... $ECHO_C" >&6
for i in $PHP_FFMPEG /usr/local /usr ; do
if test -f $i/lib/libavcodec.so; then
FFMPEG_LIBDIR=$i/lib
fi
done

to:

echo "$as_me:$LINENO: checking for ffmpeg libavcodec.so" >&5
echo $ECHO_N "checking for ffmpeg libavcodec.so... $ECHO_C" >&6
for i in $PHP_FFMPEG /usr/local /usr ; do
if test -f $i/lib/libavcodec.dylib; then
FFMPEG_LIBDIR=$i/lib
fi
done


And of course, the script will only look into /usr/lib & /usr/include ; as my libraries were into /sw I put links to the lib & include dirs.

From there, the configure works fine, and also the compile; you need to create (or copy from /etc/php.ini-default to /usr/lib/php.ini and edit to add the proper extension.

Next, download a mpg & avi file, and put this code to test =):

<?php
print "<h1>Testing mpg</h1>";
$movie = new ffmpeg_movie("tmp.mpg", false);

print "Movie Duration: " . $movie->getDuration() . "<br/>\n";
print "Movie GetFrameCount: " . $movie->getFrameCount() . "<br/>\n";
print "Movie GetFrameWidth: " . $movie->getFrameWidth() . "<br/>\n";
print "Movie GetFrameHeight: " . $movie->getFrameHeight() . "<br/>\n";
$frame = $movie->getFrame(15);
$im = $frame->toGDImage();
imagejpeg($im, "im_mpg.jpg");
print '<img src="im_mpg.jpg"/><br/>';

print "<h1>Testing avi</h1>";
$movie = new ffmpeg_movie("tmp.avi", false);

print "Movie Duration: " . $movie->getDuration() . "<br/>\n";
print "Movie GetFrameCount: " . $movie->getFrameCount() . "<br/>\n";
print "Movie GetFrameWidth: " . $movie->getFrameWidth() . "<br/>\n";
print "Movie GetFrameHeight: " . $movie->getFrameHeight() . "<br/>\n";
$frame = $movie->getFrame(15);
$im = $frame->toGDImage();
imagejpeg($im, "im_avi.jpg");
print '<img src="im_avi.jpg"/><br/>';
?>


The first time I didn't get any; but from another files, I really could get the frames and info about the movie... I can't wait to test if wmv and mov files can be readed and created short clips =).

Regards,

Tuesday, November 08, 2005

Cheap Tip #1

Recently, I was testing wxnet and wxglade; I generated the CS code from a XRC resource through towxnet

The code compiled with no problems, but when I tried to execute it shows an error:

danguer@danguer:~/wxM$ mono app.exe

Unhandled Exception: System.DllNotFoundException: wx-c
in (wrapper managed-to-native) wx.App:wxApp_ctor ()
in <0x00012> wx.App:.ctor ()
in <0x0000a> MyApp:.ctor ()
in <0x00019> MyApp:Main (System.String[] args)


The readme only says that if this error shows, then you have to backtrack the error to one of the libraries which depends wx-c, easy to say, not easy to show =).
Also they show a command which can help you to debug how is loading (in Linux) the shared libraries: LD_DEBUG=files mono app.exe

Of course I use a lot strace for this; so I check the ENOENT, but of course it shows all the dirs where mono try to found the dll, so it's a bit hard to do it this way. I use the command the wxnet says; but like I've never used this I don't know what should appear. The answer is simple; prints the shared library which try to open, if is sucessful (it have found the library) prints something like:

4153: file=libwx-c.so [0]; needed by /usr/lib/libgmodule-2.0.so.0 [0]
4153: file=libwx-c.so [0]; generating link map
4153: dynamic: 0x40cf7f94 base: 0x40bb2000 size: 0x0014995c
4153: entry: 0x40c56cf0 phdr: 0x40bb2034 phnum: 4
4153:


It shows that the shared library was found and we could read it's data, when you don't have the shared library, it will show:

4153: file=libtiff.so.3 [0]; needed by /home/danguer/mono-1.1.9.2/lib/libwx_gtk2u_xrc-2.6.so.0 [0]
4153:


In this case, only prints the shared library, but not show anything more, because it haven't found the library, so I made a link (because I'm using libtiff4) to my libtiff library.

And this make the wxnet works fine under Linux