<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
        <title>Strumenti Resistenti</title>
        <link>http://blog.strumentiresistenti.org/</link>
        <description></description>
        <language>en-US</language>
        <copyright>Copyright 2008</copyright>
        <lastBuildDate>Thu, 13 Mar 2008 16:02:29 +0000</lastBuildDate>
        <generator>http://www.sixapart.com/movabletype/</generator>
        <docs>http://www.rssboard.org/rss-specification</docs>
        
        <item>
            <title>How do you tell Tagsistant that star trek is a show and a novel and a movie and...</title>
            <description><![CDATA[<p>Last night I was thinking about simple concepts we use everyday to communicate. I'm very unpleased to not have a fitting example, but I think I'll be able to let you understand.<br /><br />Sometimes happens to tell someone: &lt;&lt;Have you watched Star Trek?&gt;&gt; and our mate will answer: &lt;&lt;Do you mean the movie or the show?&gt;&gt; This is a very silly example but sometimes things need to be qualified to be exact. </p><p>OK, let's go back to Tagsistant and your full episode collection of star trek tv shows and movies and video games and whatever. It would be very nice to have category tagging in Tagsistant to tell that the first are "tvshow:startrek", the second are "movie:startrek" and the third are "videogames:startrek".</p><p>So we'll be able to find everything about Star Trek with an usual </p><p></p><pre>$ ls tags/startrek/</pre><p> query, but we'll also find all Star Trek tv shows by </p><p></p><pre>$ ls tags/tvshow:startrek/</pre> <p>and also all our tv shows by searching for </p><p></p><pre>$ ls tags/tvshow:/</pre> <p>(note the colon at the end).</p>]]></description>
            <link>http://blog.strumentiresistenti.org/2008/03/how-do-you-tell-tagsistant-tha.html</link>
            <guid>http://blog.strumentiresistenti.org/2008/03/how-do-you-tell-tagsistant-tha.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Tagsistant</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">file system</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">semantic</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">startrek</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">tagsistant</category>
            
            <pubDate>Thu, 13 Mar 2008 16:02:29 +0000</pubDate>
        </item>
        
        <item>
            <title>GNU/Linux vs MacOS X: dynamic loading</title>
            <description><![CDATA[<div class="post-content"><p>One of the coolest feature of POSIX systems is dynamic loading of libraries
and plugins. Everything is managed by <code>dlopen()</code> and its companions.
Loading at runtime means just:</p>
<ol><li>locating the library file</li><li>use dlopen() to get a pointer to the library</li><li>use dlsym() to get a pointer for each function inside the library you
need</li><li>use dlclose() to keep you code clean and help make the world a better place
to live in ;-)</li></ol>
<p>MacOS X and GNU/Linux both provide the same interface and code is straight
portable. So, why I'm writing about that? Because you may have inserted in your
code some check to locate the plugins of your application, dropping other files
present in the same directory.</p>
<p>For example, <a hreflang="en" href="http://www.tagsistant.net/">Tagsistant</a> uses <code>/usr/local/lib/</code>
as default path to store its plugins, which are named
<code>libtagsistant_&lt;mimetype&gt;.so</code> under GNU/Linux. And here enters
the matter: under MacOS X the extension is <code>".dylib"</code> instead of
<code>".so"</code>!</p>
<p>The code which locates the plugins is the following:</p>
<p><code>#define TAGSISTANT_PLUGIN_PREFIX "libtagsistant_"<br />
char *needle = strstr(de-&gt;d_name,&nbsp;TAGSISTANT_PLUGIN_PREFIX);<br />
if&nbsp;((needle&nbsp;==&nbsp;NULL)&nbsp;||&nbsp;(needle&nbsp;!=&nbsp;de-&gt;d_name))<br />

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;</code></p>
<p><code>needle = strstr(de-&gt;d_name, ".so");<br />
if&nbsp;((needle&nbsp;==&nbsp;NULL)&nbsp;||&nbsp;(needle&nbsp;!=&nbsp;de-&gt;d_name&nbsp;+&nbsp;strlen(de-&gt;d_name)&nbsp;-&nbsp;3))<br />

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;</code></p>
<p>This fragment is inserted into a cycle which traverse the whole plugins
list, that's why uses <code>continue</code> in reaction to failure. Number 3 in
last if statement is the length of ".so" string. This code compiles cleanly
under MacOS X but fails. After discovering the extension difference, I've
changed this code as:</p>
<code>#define TAGSISTANT_PLUGIN_PREFIX "libtagsistant_"<br />
char *needle = strstr(de-&gt;d_name, TAGSISTANT_PLUGIN_PREFIX);<br />
if ((needle == NULL) || (needle != de-&gt;d_name))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br />
<br />
#ifdef MACOSX<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; define PLUGIN_EXT ".dylib"<br />
#else<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; define PLUGIN_EXT ".so"<br />
#endif<br />
<br />
needle = strstr(de-&gt;d_name, PLUGIN_EXT);<br />
if&nbsp;((needle&nbsp;==&nbsp;NULL)&nbsp;||&nbsp;(needle&nbsp;!=&nbsp;de-&gt;d_name&nbsp;+&nbsp;strlen(de-&gt;d_name)&nbsp;-&nbsp;strlen(PLUGIN_EXT)))<br />

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;</code><br /><br />
<p>And now, finally, Tagsistant locates and loads its plugins!</p></div> ]]></description>
            <link>http://blog.strumentiresistenti.org/2008/03/gnulinux-vs-macos-x-dynamic-lo.html</link>
            <guid>http://blog.strumentiresistenti.org/2008/03/gnulinux-vs-macos-x-dynamic-lo.html</guid>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">howto</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">libfuse</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">macosx</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">tagsistant</category>
            
            <pubDate>Thu, 06 Mar 2008 22:52:12 +0000</pubDate>
        </item>
        
        <item>
            <title>Porting GNU/Linux code to MacOS X</title>
            <description><![CDATA[<div class="post-content"><p>Recently I've got a MacBook at work. Of course, the temptation of using it
for other purposes than official ones was too high to resist. So I've started
porting <a hreflang="en" href="http://www.tagsistant.net/">Tagsistant</a> to
MacOS X.</p>
<p>Compiling GNU/Linux software on MacOS X needs some fine tuning but not as much
as I thought. After reading some docs on the net, I've learned about
<a hreflang="en" href="http://fuse.sourceforge.net/">FUSE</a> port called
<a hreflang="en" href="http://code.google.com/p/macfuse/">MacFUSE</a>.
Installing MacFUSE is a piece of cake. Using it no. Autoconf script needs some
tweaking to guess the architecture type. But it's quite easy to add it. Insert
a <code>AC_CANONICAL_TARGET</code> macro in <code>configure.ac</code> or
<code>configure.in</code> file to let it figure out the four-field values for
<code>$host</code> variable, like in <code>i686-pc-linux-gnu</code> example.
MacOS X 10.5.1 returns <code>i686-apple-darwin9.1.0</code> on a Core 2 Duo
host.</p>
<p>Using <code>$host</code> value the script will be able to make some
adjustments to compile and link options. Just add some bash scripting like the
following:</p>
<code>echo configure detected host $host<br />
case $host in<br />
&nbsp; *-*-linux*)<br />
&nbsp;&nbsp;&nbsp; echo "Live long and prosper, GNU/Linux"<br />
&nbsp;&nbsp;&nbsp; ;;<br />
&nbsp; *-*-darwin*)<br />
&nbsp;&nbsp;&nbsp;&nbsp;AC_SUBST([CFLAGS],["${CFLAGS}&nbsp;-D__FreeBSD__=10&nbsp;-DMACOSX&nbsp;-DFUSE_USE_VERSION=25"])<br />

&nbsp;&nbsp;&nbsp;&nbsp;AC_SUBST([LDFLAGS],["${LDFLAGS}&nbsp;-flat_namespace&nbsp;-force_flat_namespace"])<br />

&nbsp;&nbsp;&nbsp; ;;<br />
esac</code><br /><br />
<p>As you see, we add <code>-D__FreeBSD__=10 -DMACOSX
-DFUSE_USE_VERSION=25</code> to <code>CFLAGS</code> and <code>-flat_namespace
-force_flat_namespace</code> to <code>LDFLAGS. __FreeBSD__</code> macro appears
in some headers, like in MacFUSE's, to declare some structures dedicated to BSD
hosts. <code>MACOSX</code> is a macro I've declared to include some conditional
compiling inside tagsistant. May be it's not the best name since it can easily
conflict with symbols having the same name but elsewhere declared. But it's
working so we'll keep it. Also, BSD requires FUSE API to be at least version
2.5. After running <code>configure</code> you can check inside Makefiles if
proper <code>CFLAGS</code> and <code>LDFLAGS</code> appeared.</p>
<p>After adding this code, I've run a compilation test which ended good, if we
ignore the small, insignificant side effect due to link failure:
<code>strndup()</code> and <code>getline()</code> were missing! Damn GNU
extensions! So comfortable to use, that you'll forget about portability issues!
Ok, don't worry, we can rewrite it.</p>
<p>I know that rewriting libc functions does not seem to be the right thing,
but just in this case it is, as I can assure after reading on-line the bunch of
documentation talking about that. Especially a paper on Grid Computing on MacOS
X confirmed me that <code>getline()</code> is usually replaced with POSIX
<code>fgets()</code> and that <code>strndup()</code> is rewritten, probably,
using <code>memcpy()</code> as i did. This is the code:</p>
<code>#ifdef MACOSX<br />
ssize_t getline(char **lineptr, size_t *n, FILE *stream)<br />
{<br />
&nbsp; if (*lineptr == NULL)<br />
&nbsp;&nbsp;&nbsp; *lineptr = calloc(sizeof(char), *n + 1);<br />
<br />
&nbsp; if (*lineptr == NULL)<br />
&nbsp;&nbsp;&nbsp; return 0;<br />
<br />
&nbsp; if (fgets(*lineptr, *n, stream) == NULL)<br />
&nbsp;&nbsp;&nbsp; *n = 0;<br />
&nbsp; else<br />
&nbsp;&nbsp;&nbsp; *n = strlen(*lineptr);<br />
<br />
&nbsp; return *n;<br />
}<br />
<br />
char *strndup(const char *s, size_t n)<br />
{<br />
&nbsp; char *result = calloc(sizeof(char), n+1);<br />
&nbsp; if (result == NULL)<br />
&nbsp;&nbsp;&nbsp; return NULL;<br />
<br />
&nbsp; memcpy(result, s, n);<br />
&nbsp; result[n] = '\0';<br />
&nbsp; return result;<br />
}<br />
#endif</code><br /><br />
<p>After adding this code to my project, compilation went good and now I have a
working tagsistant installation on a MacBook. It seemed a complete success, but
something happened to ruin everything. Something I've not yet solved.
<code>mknod()</code> is not working! Why the hell I'm not able to create a file
inside a tagsistant filesystem while everything else works and the same code
works perfectly under GNU/Linux? Files are stored inside the
<code>~/.tagsistant/archive/</code> directory which is created with user's
permissions and ownership. Why it's failing? It's a MacFUSE security
restriction? I don't know so far, so if someone has some clue I would really
appreciate it.</p></div>
    
          
               ]]></description>
            <link>http://blog.strumentiresistenti.org/2008/03/porting-gnulinux-code-to-macos.html</link>
            <guid>http://blog.strumentiresistenti.org/2008/03/porting-gnulinux-code-to-macos.html</guid>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">howto</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">libfuse</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">macosx</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">tagsistant</category>
            
            <pubDate>Thu, 06 Mar 2008 22:50:54 +0000</pubDate>
        </item>
        
        <item>
            <title>How to build a movie player - part 3</title>
            <description><![CDATA[<div class="post-content"><p>Welcome back to "How to build a movie player". In this third howto, we'll
see how GStreamer should be integrated inside our application.</p>
<p>GStreamer is to multimedia like Gtk is to graphic interfaces. Everything is
a module that should be chained with other modules to be useful. Our
application will use a small bunch of all the available modules of GStreamer.
In particular, our working horse will be the <strong>playbin</strong> module
which is a full featured demuxer, decoder, subtitle displayer and much more,
all prepackaged for us.</p>
<p>Firs of all, we include a lot of Gtk, Gstreamer and X11 headers to import
library functions and also declare some global symbols in <code>main.c</code>
which will be visible to all other application files. So, outside everything
else, we write:</p>
<p><code>#include &lt;X11/Xlib.h&gt;<br />
#include &lt;gst/gst.h&gt;<br />
#include &lt;gst/interfaces/xoverlay.h&gt;<br />
#include &lt;gtk/gtk.h&gt;<br />
#include &lt;gdk/gdk.h&gt;<br />
#include &lt;gdk/gdkx.h&gt;<br /></code></p>
<p><code>GMainLoop *loop;<br />
GstElement *playbin, *vsink;</code></p>
<p>The <code>*loop</code> element is a GLib provided event loop.
<code>*playbin</code> is our everything doing engine and <code>*vsink</code> is
our video output, which will be connected to GtkImage
<code>"video_preview"</code> widget to display video output. Then inside the
function we declare those elements.</p>
<p><code>loop = g_main_loop_new (NULL, FALSE);</code></p>
<p>The loop will handle all the events and will be started in the decoding
function.</p>
<p><code>playbin = gst_element_factory_make("playbin", "playbin");<br />
vsink = gst_element_factory_make("ximagesink", "vsink");<br />
g_object_set(G_OBJECT(playbin), "video-sink", vsink, NULL);</code></p>
<p>The playbin is extracted from the factory with the same name, while the
video sink vsink is a "ximagesink" module. The third line connects the playbin
output to video sink using an usual GObject statement on playbin
<code>"video-sink"</code> property.</p>
<p>Then we need some code to start audio/video decoding and playing. This is
the <code>start_decode()</code> function depicted here:</p>
<br />
<code>void<br />
start_decode()<br />
{<br />
&nbsp; /* if paused just resume */<br />
&nbsp; if (paused) {<br />
&nbsp;&nbsp;&nbsp; paused = 0;<br />
&nbsp;&nbsp;&nbsp; gst_element_set_state (playbin, GST_STATE_PLAYING);<br />
&nbsp;&nbsp;&nbsp; return;<br />
&nbsp; }<br />
<br />
&nbsp; if (stream_uri == NULL) return;<br />
<br />
&nbsp; /* tell playbin which URI has to play */<br />
&nbsp; g_object_set(G_OBJECT(playbin), "uri", stream_uri, NULL);<br />
<br />
&nbsp; /*<br />
&nbsp;&nbsp; * getting the drawing area for video preview<br />
&nbsp;&nbsp; * and setting video sink overlay<br />
&nbsp;&nbsp; */<br />
&nbsp; GtkWidget *da = lookup_widget(minitheater, "video_preview");<br />
&nbsp;&nbsp;gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(vsink),GDK_WINDOW_XID(da-&gt;window));<br />

<br />
&nbsp; /* play */<br />
&nbsp; g_timeout_add (500, (GSourceFunc) cb_print_position, playbin);<br />
&nbsp; gst_element_set_state (playbin, GST_STATE_PLAYING);<br />
&nbsp; g_main_loop_run (loop);<br />
}</code><br />
<br />
<p>Not too complex but even not banal. Let's start. First of all, it checks if
the player is paused and should only be continued. <code>paused</code> is a
boolean integer which is defined outside <code>start_decode()</code> function
and is changed by Gtk callbacks.</p>
<p><code>stream_uri</code> is the URI of the resource to be played. A URI? Why
not a plain filename? Because playbin is so cool that it's able even to play
directly from the net! So, to play a local resource like file
<code>/home/myself/movie.avi</code> we need to convert the path into
<code>file:///home/myself/movie.avi</code>. This function expects the URI to be
already formatted into <code>stream_uri</code> variable. URI formatting is done
inside the callback which Gtk calls when a file is chosen from the file chooser
dialog, as we'll see in a future post. To set the URI inside playbin we need
just a GObject call as in <code>g_object_set(G_OBJECT(playbin), "uri",
stream_uri, NULL);</code></p>
<p>Then we need to connect the video sink to Gtk widget devoted to video
output. So we first gather the widget using Gtk <code>lookup_widget()</code>
function and then use a function from the X11 overlay interface of GStreamer.
The lines are:</p>
<p><code>GtkWidget *da = lookup_widget(minitheater, "video_preview");<br />
gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(vsink),GDK_WINDOW_XID(da-&gt;window));</code></p>
<p><code>GDK_WINDOW_XID()</code> is a GDK macro to extract the X11 window id of
a Gtk widget. GStreamer will later use this id to target video output to the
right area.</p>
<p>Then we connect a timeout function which every 500 milliseconds will update
the interface, using <code>g_timeout_add()</code> facility provided by GLib.
The function <code>cb_print_position()</code> will be shown in a later post.
And finally we start playing, with both GStreamer
<code>gst_element_set_state()</code> function, which put playbin pipeline in
<code>GST_STATE_PLAYING</code> state, and <code>g_main_loop_run()</code> which
starts GLib provided event loop.</p>
<p>That's all the setup we need. In next issue we'll see how this code gets
activated by Gtk callbacks in response to user action on the interface. Stay
tuned.</p></div> ]]></description>
            <link>http://blog.strumentiresistenti.org/2008/03/how-to-build-a-movie-player-pa-2.html</link>
            <guid>http://blog.strumentiresistenti.org/2008/03/how-to-build-a-movie-player-pa-2.html</guid>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">GStreamer</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">Gtk</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">howto</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">multimedia</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">player</category>
            
            <pubDate>Thu, 06 Mar 2008 22:48:18 +0000</pubDate>
        </item>
        
        <item>
            <title>How to build a movie player - part 2</title>
            <description><![CDATA[<p>Welcome back to "How to build a movie player". This is second lesson
(lesson?). This time we'll aproach GStreamer to begin understanding how it
works and what need to be done to build the multimedia subsystem of our player.
First of all, some URL. GStreamer site is located at
http://gstreamer.freedesktop.org/. On that site you'll find a lot of
documentation to better focus arguments exposed here.</p>
<p>GStreamer is a framework, composed by several different <em>reusable
components</em> called plugins. Plugins can be of more than one kind: sources,
demuxers, decoders, video and audio players. We mentioned demuxes and decoders
only because we are building a player application, but GStreamer, as the name
suggest, is also able to produce contents, so it's also equipped with muxers,
encoders and network stremers.</p>
<p>Plugins are interconnected by <strong>pads</strong>. Pads are like
directional slots that produce or consume data. Some plaugins have just
producing pads, like file readers or stream downloaders, some have consuming
pads only, like audio or video players, some have both, like filtering plugins,
demuxes, decoders and so on. Producing pads are called
<strong>sources</strong>, consuming pads are called <strong>syncs</strong>.</p>
<p>Joining plugins by connecting pads creates a <strong>pipeline</strong>,
which is a complete chain of media management able to acquire, process and
output audio and video contents. If you need total control of what's happening
inside your application, you can build your own pipeline by yourself. Otherwise
you can follow GStreamer developer suggestion and use the prebuild
<strong>playbin</strong> pipeline. Playbin is a plugin providing a complete
pipeline which needs very little customization to work. Playing media content
requires just setting the <strong>uri</strong> property of playbin to point to
your file or stream and playbin will handle all the dirt work for you.</p>
<p>GStreamer comes with two useful command line tools: <code>gst-launch</code>
and <code>gst-inspect</code>. The first one can be used to test pipelines
before writing even one single line of code. The second one can be used to
inspect plugin properties and found the plugin that best matches your needs.
For example, the man page of gst-launch report some examples of pipelines, like
the following:</p>
<p><code>gst-launch filesrc location=music.mp3 ! mad ! audioconvert !
audioresample ! osssink</code></p>
<p>Reading for left to right, this pipeline does:</p>
<ol><li>read file music.mp3 with <strong>filesrc</strong> plugin</li><li>process it with <strong>mad</strong> plugin to decode the MP3 stream</li><li>convert it to a playable audio format with <strong>audioconvert</strong>
plugin</li><li>resample to a useful rate with <strong>audioresample</strong> plugin</li><li>play it to /dev/dsp using the <strong>osssink</strong> plugin, which is
based on OSS Linux audio system</li></ol>
<p><strong>location</strong> is a property of filesrc plugin which is set on
command line to point to source audio file. <strong>osssink</strong> is a
consumer only plugin, being at the end of the pipeline, while
<strong>filesrc</strong> is a producer only plugin. Similarly here is a
<strong>ogg/vorbis</strong> player:</p>
<br />
<code>gst-launch filesrc location=music.ogg ! oggdemux ! vorbisdec !
audioconvert ! audioresample ! osssink</code><br />
<br />
<p>The main difference is that ogg-vorbis has a container (the
<strong>Ogg</strong> format) around audio content (the
<strong>Vorbis</strong> stream), so the pipeline needs to unwrap Vorbis data before decoding it; that's done by the couple <code>oggdemux ! vorbisdec</code>, an Ogg demuxer
unwrapping content later fed to a Vorbis decoder.<br /><br />
That's both simple and complex at the same time. How I'm supposed to know which
plugin connect to which other in forming a pipeline? The answer is very easy.
GStreamer plugins provide self inspection. With command line tool
<code>gst-inspect</code> you can learn how a plugin interfaces to outside world
and what can be connected to it, and also which formats the plugin can receive
and produce and a lot more. Calling <code>gst-inspect</code> without parameters
will return a full list of all the available plugins. Providing the name of a
plugin will return more informations on that plugin only. Let see what can we
learn about the first plugin, <strong>filesrc</strong>:<br />
<br />
<code>Pad Templates:<br />
&nbsp; SRC template: 'src'<br />
&nbsp;&nbsp;&nbsp; Availability: Always<br />
&nbsp;&nbsp;&nbsp; Capabilities:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ANY</code><br />
<br />
That section informs us that any kind of output can be produced by this plugin
(Capabilities: ANY). That makes sense, since a file sourcing plugin can read
any kind of data from inside the file.<br />
<code><br />
Pads:<br />
&nbsp; SRC: 'src'<br />
&nbsp;&nbsp;&nbsp; Implementation:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Has getrangefunc():
gst_base_src_pad_get_range<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Has custom eventfunc():
gst_base_src_event_handler<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Has custom queryfunc(): gst_base_src_query<br />
&nbsp;&nbsp;&nbsp; Pad Template: 'src'</code><br />
<br />
The plugin provides a pad called src which refers to previously seen 'src'
template. So we now know that using this plugin will provides us a src pad
which is a producer pad outputting any kind of data in the known and unknown
universe. The output is actually much more longer but we don't manage to
analyze it all here. That was just to give you a taste of GStreamer plugins.
But, as we mentioned before, building a pipeline is quite complex. Another
thing to consider is that pads can be static or dynamic. Some file contains an
arbitrary number of streams of the same kind (think to multilanguage audio
tracks inside an AVI or Ogg file). So certain plugins will create pads
dynamically. If you really need all that complexity you can get your hands
dirt, but otherwise there is another solution: the <strong>playbin</strong>
pipeline we already mentioned before.<br />
<br />
Playbin is a full, dynamic pipeline implemented in a single plugin. To use it
you have just to set one or more properties and all the black magic will be
done behind the scenes by GStreamer. The most important one is the
<strong>uri</strong> property which points to media to be played, using&nbsp; a
compliant URI syntax, like <code>file:///home/myself/Video/concert.ogg</code>
or <code>http://www.on.line.source.net/song.mp3</code>. Doing it on the command
line is just a matter of:<br />
<br />
<code>gst-launch playbin uri="file:///usr/share/example-content/Experience
ubuntu.ogg"</code><br />
<br />
Just issue this command and you'll see and hear your media played for you.
We'll use playbin for our movie player in later posts.<br />
<br />
I hope the load of information has not been too high. GStreamer is quite easy to
be used as a multimedia framework, but <em>quite easy</em> should be intended
in relation to the intrinsics complexity of multimedia frameworks. You need to
study for some days the good documentation the project provides and you'll be
able to start coding more faster than you imagine.<br />
<br />
So far, that's all. In the next issue we'll use GStreamer playbin inside our
application to provide playing capability. See you next time. </p>]]></description>
            <link>http://blog.strumentiresistenti.org/2008/03/how-to-build-a-movie-player-pa-1.html</link>
            <guid>http://blog.strumentiresistenti.org/2008/03/how-to-build-a-movie-player-pa-1.html</guid>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">GStreamer</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">howto</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">multimedia</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">player</category>
            
            <pubDate>Thu, 06 Mar 2008 22:46:36 +0000</pubDate>
        </item>
        
        <item>
            <title>How to build a movie player - part 1</title>
            <description><![CDATA[<p>Recently I've started to play with <a hreflang="en" href="http://gstreamer.freedesktop.org/">GStreamer</a>, a powerful and complex
multimedia framework based on <a hreflang="en" href="http://library.gnome.org/devel/glib/unstable/index.html">glib</a> <a hreflang="en" href="http://developer.gnome.org/doc/API/2.0/gobject/index.html">object
model</a>. In less than two weeks I've been able to build a (basic) player
which can handle audio and video. In this post I'm starting a report on how to
build such a basic player as an introduction to GStreamer.</p>
<p>We'll use <a hreflang="en" href="http://glade.gnome.org/">Glade-2</a> to
build a <a hreflang="en" href="http://www.gtk.org/">Gtk+2.0</a> interface for
our player and we'll build the interface code using C as target language. We'll
also use autotools from GNU project, since Glade kindly provides all the setup
files for use. We'll need just to tweak a little bit with Makefile.am to add
GStreamer compile flags.</p>
<p>Ok, starting! Run Glade and start a new project. Call it as you prefer. In out
tutorial we'll call our application <strong>blogtheater</strong>. Then start
placing widgets on the ground. The very first widget you should pick is of
course a <strong>window</strong>. After clicking on window item in glade
palette, something similar should appear:<br /><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="mt001.jpeg" src="http://blog.strumentiresistenti.org/media/mt001.jpeg" class="mt-image-center" style="margin: 0pt auto 20px; text-align: center; display: block;" height="329" width="410" /></span></p>
<p>Now it's time to fill the interface with familiarly looking widgets: a menu
bar, a working area and a status bar which informs the user about what's going
on. We place a vertical box of four slot, we add the menu bar in the first and
the status bar in the last. In the second one we'll place the main contents
while in the third one we'll place the controls. The result should look like in
following picture:<br /><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="mt002.jpeg" src="http://blog.strumentiresistenti.org/media/mt002.jpeg" class="mt-image-center" style="margin: 0pt auto 20px; text-align: center; display: block;" height="329" width="410" /></span></p>
<p>The buttons need some makeup: using stock buttons will do the job. First button
will be Open, then Play, Pause and (we miss a slot, should add one!) Stop. In
the left most slot we'll put a two lines vertical box with timestamp up and a
range down, to visualize the media playing position. The result, again, look
like the picture:</p>
<p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="mt003.jpeg" src="http://blog.strumentiresistenti.org/media/mt003.jpeg" class="mt-image-center" style="margin: 0pt auto 20px; text-align: center; display: block;" height="329" width="588" /></span>More promising, isn't it? OK. Let me explain some tricks I've used with glade.
Nothing is marked as "fill" and "expand" except the vertical box holding the
range and the timestamp. The timestamp if formed by three distinct labels: the
first and the third (for elapsed and total time) and another one which is just
"/". That will simplify the callback, as we'll see while coding file
callbacks.c. Now, let's add the screen and the playlist, the first on left, the
second on right, as follows:</p>
<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="mt004.jpeg" src="http://blog.strumentiresistenti.org/media/mt004.jpeg" class="mt-image-center" style="margin: 0pt auto 20px; text-align: center; display: block;" height="329" width="588" /></span>Inside the vertical pane object (the one divided in two vertical region by a
draggable separator, are placed two frame widgets with "No file playing" and
"Playlist:" as labels. The GtkAdjustment of left frame has been set to
resizeable while the rightest one has not. That's due to gravity behaviour when
the window is resized. Left frame hosts a GtkImage widget which will be used by
GStreamer to show video contents. The right one contains a GtkTreeView widget
which allows displaying of a structured list of arbitrary data.</p>
<p>The interface is almost complete (OK, no "About" dialog, but who cares? You are
skilled enough to add it yourself) and we miss just a file selector dialog, so
we click on the FileChooser widget inside Glade palette. Than we save the
project and we build the code which will look like any other ordinary GNU
package, with <code>configure</code> and everything in place.</p>
<p>So far, that's all. If you wish, you can download <a href="http://blog.strumentiresistenti.org/media/blogtheater.glade">blogtheater glade project</a>. In the next issue
we'll see how GStreamer performs data pipelining and how use it inside a
multimedia application. Stay tuned. :-) <div><br /></div><div><br /></div><div><br /></div>]]></description>
            <link>http://blog.strumentiresistenti.org/2008/03/how-to-build-a-movie-player-pa.html</link>
            <guid>http://blog.strumentiresistenti.org/2008/03/how-to-build-a-movie-player-pa.html</guid>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">GStreamer</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">Gtk</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">howto</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">multimedia</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">player</category>
            
            <pubDate>Thu, 06 Mar 2008 22:44:37 +0000</pubDate>
        </item>
        
        <item>
            <title>An update on bitflu web interface</title>
            <description><![CDATA[<div class="post-content"><p>Just after having published the web interface plugin for BitFlu, I've tested
it on newest version of bitflu development branch. The good news is that it's
still working. The bad news (if it's so) is that something has changed and
installation is a bit different, but even better (so definitely it isn't a bad
news).</p>
<br />
<p>First of all, the plugin should be renamed as <code>10_AdminWeb.pm</code>.
But you no longer need to add <code>Bitflu::AdminWeb</code> to plugin list to
have the plugin loaded, 'cause plugins list is built by reading plugin
directory contents.</p></div> ]]></description>
            <link>http://blog.strumentiresistenti.org/2008/03/an-update-on-bitflu-web-interf.html</link>
            <guid>http://blog.strumentiresistenti.org/2008/03/an-update-on-bitflu-web-interf.html</guid>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">bitflu</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">p2p</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">plugin</category>
            
            <pubDate>Thu, 06 Mar 2008 22:42:30 +0000</pubDate>
        </item>
        
        <item>
            <title>An AJAX interface for Bitflu</title>
            <description><![CDATA[<p><a hreflang="en" href="http://blog.strumentiresistenti.org/media/bitflu_screenshot.png">Bitflu</a> is a
bittorrent client written in Perl by Adrian Ulrich. It's very lightweight and
is well suited for installation on small machines like your linux mini firewall
that you have built with that old mother board and that 400MHz CPU you found in
a closet. Its memory usage is impressively low: 15/20M with many active
torrents; nothing to share with other clients occupation (150M + ).</p>
<br />
<p>Bitflu comes in two releases: a stable and a development one. We need the
second one which is a new rebirth for bitflu, being a completely rewriting from
scratch of everything with a deeper modular design in mind (even core functions
of bitflu has been implemented as plugins). Stable version included a web
interface, while the development one has just a textual telnet interface.</p><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.strumentiresistenti.org/media/bitflu_screenshot.png"><img alt="bitflu_screenshot_s.jpg" src="http://blog.strumentiresistenti.org/media/bitflu_screenshot_s.jpg" class="mt-image-left" style="margin: 0pt 20px 20px 0pt; float: left;" height="103" width="240" /></a></span>
<p>And here enters my plugin. <code><a hreflang="en" href="http://www.strumentiresistenti.org/public/bitflu-admin-web.tgz">AdminWeb.pm</a></code>. It's basically a Perl
plugin which provides a nice web interface to most of Bitflu functions. You can
upload a .torrent by specifying the URL on the web or the path on server
(Adrian told me that URL fetching will be included in bitflu and so will
disappear from my plugin). You can monitor downloads by expanding download
section, you can commit a download when finished and see its progress in
percentage. You can query bitflu about installed plugins and other
informations. By installing <code><code>Filesys::</code>DfPortable</code> Perl
module you can also have a report about available disk space.</p>
<p>
<strong>To install:</strong> download <a hreflang="en" href="http://blog.strumentiresistenti.org/media/bitflu-admin-web.tgz">the plugin</a> and simply extract the archive in
your <code>bitflu_dir/plugins/Bitflu/</code> directory and edit
<code>bitflu.conf</code> by adding <code>Bitflu::AdminWeb</code> to entry
<em>plugins.</em> If the entry (or the whole file) does not exists and you feel
yourself hacker enough, you can also edit <code>bitflu.pl</code> itself by
adding plugin name to internal list (search for
"<code>$self-&gt;{conf}-&gt;{plugins}</code>" and edit the value pointed by
this key). </p><div><br /></div>]]></description>
            <link>http://blog.strumentiresistenti.org/2008/03/an-ajax-interface-for-bitflu.html</link>
            <guid>http://blog.strumentiresistenti.org/2008/03/an-ajax-interface-for-bitflu.html</guid>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">bitflu</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">p2p</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">plugin</category>
            
            <pubDate>Thu, 06 Mar 2008 22:37:50 +0000</pubDate>
        </item>
        
        <item>
            <title>Domain Name Anarchy: a new approach to DNS</title>
            <description><![CDATA[<div class="post-content"><p>Recent development in Distributed Hash Tables has opened a huge landscape of
possibilities. DHT has been used for storage and retrieval of an enormous range
of information kinds. One of this kind of informations is network names. A lot
of alternatives to DNS has been proposed and sometimes even deployed, providing
registration flexibility and ease of use. But most of that solutions deviated
from DNS original standard, settling into to vertical application niches which
lead to dead routes.</p>
<br />
<p>DNA tries to depart from this tradition learning from errors and wants to
develop e new compatible standard able to smoothly interoperate with existing
DNS server network. Basically, using DHT to route informations through
participant nodes, DNA is able to resolve unofficially registered TLDs (Top
Level Domains) as well as official ones. Zones are managed in a delegated way
as already done for usual domains, but TLD registration will be bureaucracy
free and will be anonymous.</p>
<br />
<p>If a DNA TLD will clash with an official one, DNA network will simply drop
registering request and will serve query requests as normal DNS ones. For the
end user, using DNA means just selecting a DNA node as resolver. Disabling DNA
is as easy as substituting DNA resolver with a traditional one, probably
provided by user ISP.</p>
<br />
<p>Actual DNA implementation is called RNA (Rhizomatic Name Archiver) and is
entirely written in Perl, released as free software under GNU GPL v.2. For
further informations please refer to <a hreflang="en" href="http://www.dna-project.net/">http://www.dna-project.net/</a></p></div> ]]></description>
            <link>http://blog.strumentiresistenti.org/2008/03/domain-name-anarchy-a-new-appr.html</link>
            <guid>http://blog.strumentiresistenti.org/2008/03/domain-name-anarchy-a-new-appr.html</guid>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">DHT</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">DNS</category>
            
            <pubDate>Thu, 06 Mar 2008 22:34:10 +0000</pubDate>
        </item>
        
        <item>
            <title>paypal and tor: a lot of troubles coming?</title>
            <description><![CDATA[<p>Several weeks ago something happened with my paypal account. They was
claiming irregular use of my account and decided to block it until I send city
released papers about me.</p>
<p>
I've tried to get more informations from paypal about the very nature of
irregular use, but they have not revealed anything simply sticking to repeat
that something went wrong and, of course, being them so concerned about
<strong>my</strong> very own security, they blocked near everything. After
sending a city issued paper, everything come back to order. But still no
info.</p>
<p>I've two answers, which one is the right one, I still don't know.</p>
<p>First answer: they where just trying to be sure that I was the one I was
claiming to be. So they used a little trick to force me sending some
papers.</p>
<p>Second answer: I was using <a hreflang="en" href="http://tor.eff.org/">tor</a>
to navigate anonymously. May be paypal did not consider tor as a an accepted
tool of modern Internet life because of money being involved. Tor is basically
a tool to navigate without being traced by the other peer and anyone being
finger tapping the network in between. But, as you already may know, privacy is
no value while money are involved.</p>
<p>I don't which one is true. But what's worse, I even don't know which one is
better. ]]></description>
            <link>http://blog.strumentiresistenti.org/2008/03/paypal-and-tor-a-lot-of-troubl.html</link>
            <guid>http://blog.strumentiresistenti.org/2008/03/paypal-and-tor-a-lot-of-troubl.html</guid>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">money</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">paypal</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">privacy</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">tor</category>
            
            <pubDate>Thu, 06 Mar 2008 22:32:52 +0000</pubDate>
        </item>
        
        <item>
            <title>Tagsistant, your personal file organizing tool</title>
            <description><![CDATA[<p><a href="http://www.tagsistant.net/">Tagsistant</a> is a filesystem for
Linux/BSD kernels based on <a href="http://fuse.sourceforge.net/">libfuse</a>.
As you already know, every day you manage lots of files. Searching takes some
time very long time and finding is not always guaranteed. Tagsistant is a
simple tagging layer between you and your files. Mount it on a dedicated
directory and create tags with tools you already are used to by making new
directories inside it and copy your files in tag-directories. To perform a
search just walk inside tagsistant space to write a query, like in path
<tt>tagsistant/holidays/AND/summer/AND/sea/OR/holidays/AND/Rome/</tt>. Finding
your stuff has never been simpler.</p>
<p><a href="http://www.tagsistant.net/">Tagsistant</a> e' un filesystem per kernel
Linux e BSD basato su <a href="http://fuse.sourceforge.net/">libfuse</a>. Ti
sarai gia' reso conto che ogni giorni maneggi molti file. Cercarli a volte
richiede molto tempo e trovarli non e' sempre garantito. Tagsistant e' un
semplice layer di etichettatura fra te e i tuoi file. Montalo in una directory
dedicata e crea le tag usando strumenti a cui sei gia' abituato semplicemente
creando nuove directory dentro cui copiare i tuoi file. Per eseguire una
ricerca muoviti nello spazio gestito da tagsistant per scrivere una query, come
con il percorso</p><p>
<tt>tagsistant/vacanze/AND/estate/AND/mare/OR/vacanze/AND/Roma/</tt>.</p><p>Trovare
le tue cose non e' mai stato cosi' semplice. </p>]]></description>
            <link>http://blog.strumentiresistenti.org/2008/03/tagsistant-your-personal-file.html</link>
            <guid>http://blog.strumentiresistenti.org/2008/03/tagsistant-your-personal-file.html</guid>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">BSD</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">Linux</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">Semantic</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">filesystem</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">libfuse</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">tagsistant</category>
            
            <pubDate>Thu, 06 Mar 2008 22:30:12 +0000</pubDate>
        </item>
        
        <item>
            <title>Magma: building a distributed hash table filesystem</title>
            <description><![CDATA[<p><a href="http://www.magmafs.net/">Magma</a> is a network filesystem for
Linux/BSD kernels. Its main goal is to provide a reliable filesystem built on
distributed hash tables, fault tolerant to network and hardware failure and
redundant on managed data.</p>
<p><a href="http://www.magmafs.net/">Magma</a> e' un network filesystem
per kernel Linux e BSD. Il suo scopo principale e' fornire un filesystem
affidabile basato su distributed hash table, resistente agli inconvenienti
della rete e dell'hardware e capace di ridondare i dati contenuti. </p>]]></description>
            <link>http://blog.strumentiresistenti.org/2008/03/magma-building-a-distributed-h.html</link>
            <guid>http://blog.strumentiresistenti.org/2008/03/magma-building-a-distributed-h.html</guid>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">BSD DHT filesystem libfuse Linux magmafs network filesystem</category>
            
            <pubDate>Wed, 05 Mar 2008 14:40:51 +0000</pubDate>
        </item>
        
        <item>
            <title>Yet another software devoted site?</title>
            <description><![CDATA[<div class="post-content"><p>Strumenti resistenti is a place to discuss about software that place
resistance as main goal. Resistence as quality in conception and programming
it, but also as an attitude on raising pressure exercised on digital rights
done by who would want a community of&nbsp; obedient and malleable users.</p>
<p>Strumenti resistenti e' un contenitore per discutere di software che pongano
la resistenza come obiettivo centrale. Resistenza intesa sia come qualita'
nella programmazione e nella concezione, sia come attitudine alla crescente
pressione esercitata sui diritti digitali da chi vorrebbe una comunita' di
utenti docili e malleabili.</p></div> ]]></description>
            <link>http://blog.strumentiresistenti.org/2008/03/yet-another-software-devoted-s.html</link>
            <guid>http://blog.strumentiresistenti.org/2008/03/yet-another-software-devoted-s.html</guid>
            
            
            <pubDate>Wed, 05 Mar 2008 14:13:09 +0000</pubDate>
        </item>
        
    </channel>
</rss>
