thefoundationhttp://www.thefoundation.de2010-07-01T22:53:07Z(c) 2012 Michael Kurze, Aachen, GermanyQuickTime Reference Movies in Python2010-07-01T22:53:07ZDavid Murmannhttp://www.thefoundation.de/about/davidquicktime-reference-movies-python<p>HTML5 video is on its way, and Apple likes to use reference movies to
send different versions of movies to different clients. So, how do
you generate these if you don't have OSX handy (for example on a
server)?
</p><p>This is pretty much the premise of a little tool I wrote to generate
QuickTime reference movies. It is written in Python, because it is to
be used in a Django app that handles video uploads and encodes. Well,
that and because I <em>love</em> Python! There isn't much else to say, so here
is the code if you are interested:</p>
<p><code class="block">hg clone http://bitbucket.org/dmurmann/root pyqtref</code></p>
<p class="annotation notice center">This is very much alpha software, it may fail horribly for you!</p>
<p>The simplest possible example, generating a reference movie to 'content.mov' looks like this:</p>
<p><code class="block">from pyqtref import *
ref_mov = Movie(ReferenceMovie(Descriptor(
DataReference('content.mov')))).to_bytes()</code></p>
<p>The boilerplate is necessary, because the API is pretty close to the <a href="http://developer.apple.com/mac/library/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25756">Quicktime File Format Specification</a>.</p>
It appears I was wrong2009-04-08T23:18:11ZMichael Kurzehttp://www.thefoundation.de/about/michaelit-appears-i-was-wrong<p>Yesterday, Google <a href="http://googleappengine.blogspot.com/2009/04/seriously-this-time-new-language-on-app.html" title="Seriously this time, the new language on App Engine: Java™">announced</a> the availability of Java as the new programming language for the App Engine, refuting <a href="http://www.thefoundation.de/michael/2008/sep/21/javascript-next-app-engine-language/" title="Is JavaScript The Next App Engine Language?">my guess</a> from last year that it might be JavaScript — though of course, not entirely.</p><p>
If you take the demand of the users into account, Java is of course the right choice as the next language. It might just alienate lots of Java-Developers if a niche language of the server zoo such as JavaScript was to emerge first. Additionally, Java is one Step short of full (albeit sandboxed) <abbr title="Java Virtual Machine">JVM</abbr> support.
</p>
<p>
To allow for sandboxing, Google wraps some of its own <abbr title="Application Programmer Interface">API</abbr>'s into Java SE or <abbr title="Java Specification Request">JSR</abbr>–standardized services such as <tt>javax.mail</tt> and <tt>java.net.URL</tt>. Also, there is a <a href="http://code.google.com/appengine/docs/java/jrewhitelist.html" title="The JRE Class White List">white-list</a> currently containing 1323 of the 3700+ <a title="Overview (Java Platform SE 6)" href="http://java.sun.com/javase/6/docs/api/">Java SE 6</a> classes. Most of the classes that are not available are from the Swing and AWT suites which a web developer will not need anyway. Instead, Google provides the homebrewn <abbr title="Google Web Toolkit">GWT</abbr>.
</p>
<p>
Thanks to the free and open source <a href="http://www.mozilla.org/rhino/" title="Mozilla Rhino: JavaScript for Java">Rhino</a> JavaScript Interpreter written in Java, server side JavaScript on the App Engine is rather easy to achieve now. I guess I might have to check it out and report back about it later, so I just signed up for the Java technology preview on my App Engine account.
</p>
<p>There are <a title="Campfire One: App Engine Redux" href="http://www.youtube.com/view_play_list?p=DFDBB63922B90A70">some videos</a> from the Google Campfire event over at Youtube. Most of the time they are rather interesting, plus Kevin Gibbs does a pretty decent imitation of Steve Jobs during the presentation (voluntary or not).</p>
Streaming from iTunes to the iPhone: A Sketch2008-10-20T01:18:12ZMichael Kurzehttp://www.thefoundation.de/about/michaelstream-audio-itunes-iphone<p>Wireless playback of your music collection from iTunes to your stereo equipment, using the iPhone instead of cables or an AirPort Express. Requires a Mac, an iPhone, the Apple Developer tools and Fink, and the power to use them all.</p><p>
I own an <a href="http://www.apple.com/airportexpress/" title="Apple – AirPort Express product page">AirPort Express</a> wireless access point that I used to stream my iTunes music to, so that it would play on the stereo equipment. In my current home though, my stereo sits in a corner, where an airport unit would cover my room but never the whole apartment. Also, I would have to pull an ethernet cable into my room for wireless internet access. So I put the airport unit into the hall instead.
</p>
<p>
Before the App Store launched, I used to run a simple web service on my notebook. Written in Python, it would report the currently playing iTunes track using <a href="http://appscript.sourceforge.net/" title="appscript Project Page">Python — AppleScript</a> bindings. The iPhone would load a page containing an iframe for the actual audio resource (the HTML 5 audio support is not yet available on the iPhone) and an poll for song updates via XMLHttpRequest. This solution worked so-so, as there was a pause between tracks because the iPhone browser had to bring up the Quicktime plugin in a slow animation for each track, before even preloading the actual song file.
</p>
<p>
Fortunately, <a href="http://www.sourcemac.com/" title="Website of Julien-Pierre Avérous">Julien-Pierre Avérous</a> offers his web radio streaming client <a href="http://www.sourcemac.com/?page=fstream" title="FStream WebRadio listener/recorder software">FStream</a> at the App Store for free! What's left to do now, is turning iTunes into a web radio station using free components:
</p>
<ul>
<li><a href="http://jackaudio.org/" title="Jack Audio project page">Jack Audio Connection Kit</a> to rewire the iTunes output to a stream encoder</li>
<li><a href="http://darkice.tyrell.hu/" title="DarkIce live audio streamer">DarkIce</a> to create an MP3 stream that can be fed to a streaming web server. You will also need to get <a href="http://lame.sourceforge.net/" title="LAME MP3 Encoder">lame</a> using Fink.</li>
<li><a href="http://www.icecast.org/" title="IceCast project page">IceCast 2</a> as the actual streaming server. I had to switch to Fink unstable to get this version.</li>
</ul>
Next thing is to configure these tools to play along, which I shall describe in a follow-up article for the patient.
Project »INFINITY« [update]2008-10-18T23:43:40ZMatthias Schulzhttp://www.thefoundation.de/about/matthiasproject-infinity<p>Bringing movement to lights.</p><p>Together with the German light designer <a href="http://www.lichtwerke.de">Stefan Hofmann</a> we created the animations for his light installation <cite>INFINITY</cite> for the <a href="http://light-building.messefrankfurt.com/frankfurt/de/fakten_luminale.html">Luminale 2008</a> in Frankfurt.<br/>
The installation was constructed in Frankfurt's <a href="http://www.senckenberg.de/root/index.php?page_id=28">Senckenberg Museum</a> in April. The construction consists of 50, 3m high columns with integrated <abbr title="Light Emitting Diode">LED</abbr> Pixels. The columns stand in a circle of a about 7m radius.<br/>
The idea was to entirely surround the spectators with light, creating an infinite light room. Our abstract 360° animations supported the infinite surrounding we wanted to create.
</p>
<p>
<youtube id="Y3mdWnGN27Y" />
</p>
<p>
<youtube id="hmCuFevjxfc" />
</p>
<p>
<gallery slug="project-infinity">Project »INFINITY«</gallery>
</p>
<p>
The installation will be presented again at <a href="http://www.gloweindhoven.nl/">GLOW 2008</a> in Eindhoven, Netherlands in November 2008.
</p>Is JavaScript The Next App Engine Language?2008-09-21T04:00:28ZMichael Kurzehttp://www.thefoundation.de/about/michaeljavascript-next-app-engine-language<p>As <em>the</em> language of the browser, JavaScript has become a kind of common denominator among web programmers. On the server it is rare compared to Java, PHP, Ruby or Python. Could this change, since Google has built an implementation of JS <em>and</em> an affordable yet scalable web application infrastructure?</p><h2>Scripting Language of The Open Web</h2>
<p>
JavaScript was created as a scripting language for the Netscape 2.0 browser. Other than its namesake Java, it has remained in the browser since then. Web Developers know this language because they have to use it, no matter if they like it. Throughout the late 90s and well into this decade, JavaScript was mostly regarded as a toy language for silly effects and simple form checks. Due to the more recent experience with Ajax applications and the resulting thorough coverage in technical literature, the users of JavaScript have become more professional.
</p>
<h2>The Server Domain</h2>
<p>
The development on the server side has — with some notable exceptions — ignored the language JavaScript for many years. Perl was a dominant language in the early days. Then, PHP gained momentum in the fast growing developer community during the internet bubble due to its gentle learning curve, the simple integration with MySQL and <em>the overwhelming availability of inexpensive shared hosting</em>. You could say that in its ubiquity, PHP has mimicked JavaScript, only on the server.
<br />
Other languages and tool chains have gained momentum since then, most notably Ruby, Java and Python. They are not as affordable as PHP (except Python on the App Engine), and seem to be used mostly because of their modern <abbr="Model, View, Controller">MVC</abbr> frameworks.
</p>
<h3>Why JavaScript Is Not Popular on The Server</h3>
<p>
JavaScript has some fundamental weaknesses that have inhibited its inception as a server side programming language:
</p>
<ul class="block">
<li>JavaScript, — or rather ECMAScript — has no real standard library, it is just a language. There are no tools for file or process manipulation. There are no database bindings and there is no shared memory. There is no way to open a socket.</li>
<li>In the past, JavaScript Interpreters have not been known for their performance. Anyone who has seen the message <q>A script on this page may cause Firefox to run slow.</q> would think twice before writing an application in JavaScript.</li>
</ul>
<p>
The <a href="http://dev.helma.org/">Helma</a> framework tries to address the first issue by using the Rhino Interpreter, making the Java SDK available to the JavaScript programmer. The second issue is at least partially resolved as some performance intensive tasks are moved to Java. In Java 6, Rhino is even bundled with Java. Nevertheless Helma and similar integration efforts are not very popular, compared to Rails or Struts. A reason for this might be that Java for the web (the <em>enterprise edition</em>) is a very serious business, while the perception of JavaScript has long been ...well, the opposite of serious. The two cultures do not seem to mix well yet, as good as the technologies might blend.
</p>
<h3>Why The App Engine Loves JavaScript</h3>
<p>
When Guido van Rossum adopted Python for the Google App Engine, he had to remove lots of features because they would not work with the sandboxed, replicating environment which is the App Engine. It turns out that the limitations of JavaScript really make it an ideal candidate for the App Engine.
</p>
<ul class="block">
<li>JavaScript is just a language: It cannot create sockets, files or processes. App Engine does not allow for that anyway, so this is a plus!</li>
<li>The language is easily sandboxed. Web Browsers have to do this all the time. This is ideal for a shared hosting environment.</li>
<li>It has a no database bindings included, but a natural serialization format, <a href="http://www.json.org" title="JavaScript Object Notation">JSON</a>. This is great for the Google Data Store, because it stores objects, not table rows.</li>
<li>Recently, JavaScript Interpreters (or, lets say <em>JavaScript Machines</em>) have become fast. There is <a href="http://code.google.com/p/v8/" title="">V8</a> and it is fast.</li>
</ul>
<p>
It is known (at least since Guido van Rossums talk at DjangoCon 2008) that Google plans to adopt more languages for the app engine. Also, there are four primary languages that Google uses for development: Python, Java, C++ and JavaScript. Python is already available. Java is a good candidate for the App Engine, but it is not exactly lightweight certainly not <em>shared nothing</em>. C++ is probably the opposite of any sandboxable language.
</p>
<p>
In combination with a template engine, a free offer on the App Engine might give the already ubiquitous JavaScript language a final boost. The prospect of <em>one language</em> from model definition to client side computation is certainly compelling!
</p>
<p>
To encourage further speculations: With Google's V8 machine comes an embedding, <tt>process.cc</tt>, that contains <q>code necessary to extend a hypothetical HTTP request processing application - which could be part of a web server, for example (...)</q> (<cite><a href="http://code.google.com/apis/v8/samples.html" title="Sample Code — V8 JavaScript Engine Documenation">V8 Documentation</a></cite>).
</p>Nobody Expects The Production Problems2008-09-21T00:08:05ZMichael Kurzehttp://www.thefoundation.de/about/michaelnobody-expects-the-production-problems<p>Sometimes you need to track down problems in a production setup. How the combination of Django and Flup make this difficult, and why I think that both should provide more than <q>log by mail</q>.</p><h2>Our Setup</h2>
<p class="annotation right"><q>Our chief weapon is development!</q>
<cite><a href="http://people.csail.mit.edu/paulfitz/spanish/script.html" title="The Spanish Inquisition">— Cardinal Ximinez of Spain</a></cite>
</p>
<p>
To the developer, the <a href="http://www.djangoproject.org" title="Django Project Site">Django</a> web development Framework offers a set of debugging helpers such as the verbose error page with interactive traceback and the management commands. The automatic reloading of python modules allows you to instantaneously see changes to your application, without even losing running sessions. If that is not enough for you, you might be interested in the powerful <a href="http://code.google.com/p/django-command-extensions/" title="Django Command Extensions, Project Site">Django Command Extensions</a>. The <a href="http://rob.cogit8.org/blog/2008/Sep/19/introducing-django-debug-toolbar/" title="Rob Hudson:
Introducing the Django Debug Toolbar">Django Debug Toolbar</a> also looks promising yet rather unfinished. I might come back to that another time.
</p>
<h2>The Other Setup</h2>
<p class="annotation right">
<q>... and production! Our two weapons are development and production!</q>
</p>
<p>
Web applications written in Django are also highly portable: Development can take place on a different <abbr title="Operating System">OS</abbr> than production will, using a different version of Python and different database and HTTP systems. With respect to debugging, these alternatives are equalized by the abstraction layers of the Python and Django stack — and fairly well. Once you have sorted out the do's and dont's of your <abbr title="Relational Database Management System">RDBMS</abbr>, there is the decision on how to handle HTTP requests. Django <a title="Deploying Django | Django Documentation" href="http://docs.djangoproject.com/en/dev/howto/deployment/">recommends</a> using the Apache HTTP Server and <tt>mod_python</tt>. Another performant <a href="http://docs.djangoproject.com/en/dev/howto/deployment/fastcgi/" title="How to use Django with FastCGI, SCGI or AJP | Django Documentation">setup</a> that seems to be quite common is using a <a href="http://nginx.net/" title="nginx">modern</a> FastCGI-capable Web Server in combination with the <a href="http://trac.saddi.com/flup" title="flup Project">flup</a> FCGI/WSGI bridge. This is what I did.
</p>
<h4>Production: Turn Off the Debug Switch!</h4>
<p>
When preparing your production setup, you will want to look into your <code>settings.py</code>. Actually, you will probably have multiple settings files of different names in revision control. Then, you will create a symlink to the settings matching the current setup. In your production settings, you will turn off debugging. This replaces the verbose traceback pages with neat-looking <abbr title="Internal Server Error">500</abbr> views which will — hopefully — never see the light of day! And otherwise, you will receive a nice error report somehow, right?
</p>
<p>
Of course you will probably encounter a production error in your site, be it a bunch of downloaded third party applications or your own magnificent creation. In my case, I soon had <a href="http://joseph.randomnetworks.com/archives/2005/08/05/postgresql-index-limitation-index-row-size-xxxxx-exceeds-btree-maximum-2713/" title="PostgreSQL Index Limitation">problems with an index</a> on a text column.
</p>
<h2>The Third Setup</h2>
<p class="annotation right">
<q>... and ruthless stage testing! Our <em>three</em> weapons are development, production, and ruthless stage testing.</q>
</p>
<p>
To catch such problems before they occur with your production setup, it is highly desirable to use a <em>stage setup</em>. This setup has its own database, usually a copy of your production database, updated on demand. The other settings should mirror your production setup. Run your staging application on the production machine or — if you can afford it — on a separate identical system and make it accessible to selected testers only. For example, you might make it listen to the local IP only and ssh-tunnel from your development machine there. On this machine, you can turn on debugging whenever needed.
</p>
<h3>Problem One: Logging by E-mail</h3>
<p>
Of course, there might still be problems that are discovered in your production setup. Unfortunately, out of the box Django reports errors only <a href="http://docs.djangoproject.com/en/dev/howto/error-reporting/" title="Error reporting via e-mail | Django Documentation">via e-mail</a>. To me, this has some critical drawbacks:
</p>
<ul class="block">
<li>You do not know if the error reporting works unless a problem occurs. In this case, you will only know that error reporting works <em>if it works</em>. Avoid this problem by enabling <abbr title="Resource not found">404</abbr> reporting and then testing an invalid URL!</li>
<li>It is <em>not secure</em>! To my knowledge there is no PGP-support for the error mails sent by Django. The messages might contain sensitive data that should not be sent unencrypted.</li>
<li>If your production setup does not work right away, you will need debugging information in fast iterations. Obtaining such information by mail is inconvenient as it is tiresome to link a browser-click to an e-mail that you might receive minutes later.</li>
<li>Your machine might not be allowed to send mails! Many <abbr title="System Operators">sysops</abbr> put firewall rules in place to prevent machines in their domain from becoming spam robots. This is what I did on my production machine, so fortunately I knew in advance that debugging by mail would not work. I am not sure if every django admin is aware of this potential problem.</li>
<li>If you host a high traffic site and an error occurs (for example if you database does not respond due to slashdotting effects or denial of service attacks), the volumes of e-mail it generates might be so high that the error reporting competes with your application on IP-connections, worsening your problems.</li>
</ul>
<h4>Solution: Exception-Logging Middleware</h4>
<p>
For my basic needs, I have written a simple <a href="/files/michael/python-modules/exception_handling.py" title="Exception Logging middleware">middleware</a> that should handle any exceptions raised by views in your production setup. Please note that this middleware relies on the <a href="http://code.activestate.com/recipes/444746/" title="ActiveState Code Recipe 444746">Exception Helpers</a> module written by <a href="http://www.targeted.org/" title="Dmitry Dvoinikov&squot;s Homepage">Dmitry Dvoinikov</a> to format tracebacks.
The traceback information is written into the logfile specified by the (custom) <tt>LOG_FILE</tt> setting. If the <tt>LOG_LEVEL</tt> is at least as verbose as <tt>DEBUG</tt>, the request object is dumped as well.
</p>
<h3>Problem Two: Exceptions Outside of Views</h3>
<p>
We are now prepared for errors that might occur when running your views production. But there is a different class of exceptions that cannot be handled by our middleware because of their nature:
</p>
<p>
On your Site, you probably want caching, <a href="http://en.wikipedia.org/wiki/HTTP_ETag" title="HTTP ETags">ETags</a> and transfer compression. So you enable the corresponding middleware, hopefully in the right <a href="http://phaedo.cx/archives/2007/07/26/django-middleware-order/" title="Django middleware order">order</a>, as <a href="http://effbot.org/zone/zone-django-notes.htm#middleware-order" title="Django Performance Observations">explained</a> by Fredrik Lundh.
And you might just add some middleware from <a href="http://www.djangosnippets.org/tags/middleware/" title="Django Snippets: Tag "Middleware"">djangosnippets</a> or some of your own. Perhaps you want to prettyprint or to simplify your output, or to yield custom error pages for Ajax-Requests.
</p>
<h4>Solution: Enable Flup Traceback Pages</h4>
<p>
Any exceptions raised during middleware processing are not caught and handled by Django, but instead propagated up to the flup FastCGI handler. By default, Flup would present an error page like Django does in debugging mode, which is quite helpful (if not as beautiful). But Django <a href="http://code.djangoproject.com/changeset/4170" title="Django Trac — Changeset 4170">disables</a> this error page explicitly during startup. I filed a <a href="http://code.djangoproject.com/ticket/6610" title="Ticket #6610">patch</a> that allows to specify a debug flag to your FastCGI process to remedy this issue.
</p>
<h3>Summary</h3>
<p class="annotation right">
<q><em>Amongst</em> our weaponry are such diverse elements as development, production, ruthless stage testing, almost fanatical verboseness to the log and nice red flup tracebacks, my oh my oh my.</q>
</p>
<p>
To anticipate and tackle production bugs, the solution consists of these parts:
</p>
<ul>
<li>separate staging and production setups</li>
<li>use exception logging middleware</li>
<li>enable flup error pages in the stage setup</li>
</ul>
<p>
This is still not perfect. Ideally, flup would also log errors in production mode. Weirdly, flup also knows
<em>log by e-mail</em>, and in this case it is not even configurable from your Django app! I will probably complement this article when I find an elegant way to fix this.
</p>
Using ffmpeg in Python2008-09-11T16:18:32ZDavid Murmannhttp://www.thefoundation.de/about/davidusing-ffmpeg-python<p>Or: how to effectively use other peoples work...
</p><p>First some background: A while ago I wrote a simple Python script that
processed a sequence of images in some specific way. I used the <a
href="http://effbot.org/zone/pil-index.htm">PIL</a> to open the
images, then do the transformation and write a sequence of images
again. It quickly became apparent that there was significant overhead
involved in dealing with larger sequences (>10000 files), especially
for some OS/filesystem combinations. The slowest of these was probably
the OSX Finder trying to access such a directory over SMB, switching
to AFP helped a lot there.</p>
<p>To get rid of the need to use (at least one of) these image sequences at all,
I decided to redo the reading part of the script to use ffmpeg to read
the frames from a quicktime file. As it stands there are some attempts
to wrap ffmpeg in Python (see <a
href="http://pymedia.org/">PyMedia</a>, <a
href="http://code.google.com/p/pyffmpeg/">PyFFmpeg</a>), but they
seemed to be outdated or weren't compiling on my 64bit machine. So, I
went ahead to try a ctypes-based approach on my own, which, as it
turns out, is really easy. I don't want to bore you with the details
of what I tried, here just comes the summary of what worked well:</p>
<p>First some prerequisites that you might not have:
<code class="block">sudo apt-get install gccxml libavcodec-dev \
libavformat-dev libswscale-dev libavfilter-dev \
libavdevice-dev libpostproc-dev</code>
Next is the tool that makes everything incredibly simple: ctypeslib.
<code class="block">svn co http://svn.python.org/projects/ctypes/trunk/ctypeslib</code>
Note that the trunk version of ctypeslib only works well with older versions
of gccxml (like 0.7), if you have a newer version, get the following branch:
<code class="block">svn co http://svn.python.org/projects/ctypes/branches/ctypeslib-gccxml-0.9</code>
After that a simple
<code class="block">sudo ./setup.py install</code>
should give you a working h2xml.py and xml2py.py. With these you can
generate ctypes wrappers:
<code class="block">h2xml.py -c -I/usr/include/ffmpeg libavcodec/avcodec.h \
libavformat/avformat.h libswscale/swscale.h \
libavdevice/avdevice.h libavfilter/avfilter.h \
libpostproc/postprocess.h -o av.xml
xml2py.py av.xml -o av.py -l libavcodec.so -l libavformat.so \
-l libswscale.so -l libavdevice.so -l libavfilter.so \
-l libpostproc.so
</code>
If that worked you can use ffmpeg in Python like this:
<code class="block">from av import *
av_register_all()
pFormatCtx = POINTER(AVFormatContext)()
if av_open_input_file(pFormatCtx, filename, None, 0, None):
handle_error("could not open file")
... (insert your usual ffmpeg code, examples <a
href="http://www.inb.uni-luebeck.de/~boehme/using_libavcodec.html">here</a> and <a href="http://www.inb.uni-luebeck.de/~boehme/libavcodec_update.html">here</a>) ...
</code></p>
<p>Up to now I only found two things that I needed that weren't converted
correctly by ctypeslib. The first were some defines, which could
probably be done right but I didn't need many so I just added them by
hand. The second was this inline function
<code class="block">static inline void av_free_packet(AVPacket *pkt)
{
if (pkt && pkt->destruct) {
pkt->destruct(pkt);
}
}
</code>
which I replaced by this definition (to be called with an AVPacket
object instead of a pointer to one):
<code class="block">def av_free_packet(pkt):
if pkt and pkt.destruct:
pkt.destruct(byref(pkt))
</code>
With a little bit of scripting to convert the ffmpeg decoded frame to
a PIL image the script can now read anything ffmpeg can read. All
thats left to do is encode the output with ffmpeg, once that is done I
might post this as a module that encapsules the conversion from
ffmpeg to PIL image sequence and back.</p>
<p><em>Last update on: Thursday, 9th October, 2008</em></p>Animating Frankfurt #12008-09-10T14:56:53ZMatthias Schulzhttp://www.thefoundation.de/about/matthiasanimating-frankfurt-1<p>Creating images for a media facade. 2km of cabels and a UMTS internet card in a small three bed hotel room in the middle of Frankfurt, Germany. </p><p>Yesterday, <a href="/daniel/">Daniel</a>, <a href="/david/">David</a> and me moved all our stuff to Frankfurt, Germany to proceed with a project we began in 2007. A bank in Frankfurt redesigned their front facade and integrated a grid of LEDs into the glass facade. <br>
So now we are here to animate a video for the facade. The tricky thing about this is the arrangement of the pixels. We have a grid of <abbr title="approximately">approx.</abbr>1100 Pixels vertically and only 49 horizontally on a building that is 6 stories high and 250 meters long. So we have 49 high resolution LED lines on the building. For our animations we have to consider this lack in horizontal resolution.<br>
<a href="/daniel/">Daniel</a> and me animate the themes while <a href="/david/">David</a> is in charge of the correct pixel conversion of the animation and all the connection to the servers we need.</p>
Now we really have to get something to eat! I will add some images soon...