somewhere to talk about random ideas and projects like everyone else

stuff

#fast

Whammy: A Real Time Javascript WebM Encoder 19 August 2012

This is sort of a conceptual reversal (or not, this might just be making the description needlessly confusing) of one of my older projects,Weppy. First, what Weppy did was it added support for WebP in browsers which didn’t support it by converting it into a single-frame video. This is instead predicated on the assumption that the browser already has support for WebP (at this point, it means it only works on Chrome since it’s the only browser which actually supports WebP), not only decoding WebP but encoding it as well.

The cool thing about WebP which was exploited in Weppy is that it’s actually based on the same codec as WebM, On2’s VP8. That means the actual image data, when the container formats are ignored, are virtually interchangable. With a catch: it’s intraframe only.

So it’s a video encoder in that it generates .webm files which should play in just about any program or device which supports the WebM format. But interframe compression is actually a fairly important thing which could reduce the file size by an order of magnitude or more.

But, there isn’t too much you can do on the client side in the ways of encoding stuff. And whatever you do, you basically can’t do interframe compression (aside from some really rudimentary delta encoding). More or less, when your only alternative is to maintain an array of DataURL encoded frames or encoding it (rather slowly) as a GIF, a fast but inefficient WebM encoder stops looking too bad.

This was actually Kevin Geng‘s idea, and he contributed some code too, but in the end most of the code was just leftovers from Weppy.

Demo

http://antimatter15.github.com/whammy/clock.html

Basic Usage

First, let’s include the JS file. It’s self contained and basically namespaced, which is pretty good I guess. And it’s not too big, minified it’s only about 4KB and gzipped, it’s under 2KB. That’s like really really tiny.

<script src="whammy.js"></script>

The API isn’t terrible either (at least, that’s what I’d like to hope)

var encoder = new Whammy.Video(15); 

That 15 over there is the frame rate. There’s a way to set the individual duration of each frame manually, but you can look in the code for that.

encoder.add(context or canvas or dataURL); 

Here, you can add a frame, this happens fairly quickly because basically all it’s doing is running .toDataURL() on the canvas (which isn’t exactly a speed-demon either, but it’s acceptable enough most of the time) and plopping the result onto an array (no computation or anything). The actual encoding only happens when you call .compile()

var output = encoder.compile(); 

Here, output is set to a Blob. In order to get a nice URL which you can use to stick in a &lt;video&gt; element, you need to send it over tocreateObjectURL

var url = (window.webkitURL || window.URL).createObjectURL(output); 

And you’re done. Awesome.

Documentation

Weppy.fromImageArray(image[], fps) this is a simple function that takes a list of DataURL encoded frames and returns a WebM video. Note that the images have to all be encoded with WebP.

new Weppy.Video(optional fps, optional quality) this is the constructor for the main API. quality only applies if you’re sending in contexts or canvas objects and doesn’t matter if you’re sending in encoded stuff

.add(canvas or context or dataURL, optional duration) if fps isn’t specified in the constructor, you can stick a duration (in milliseconds) here.

Todo

This pretty much works as well as it possibly could at this point. Maybe one day it should support WebWorkers or something, but unlike the GIF Encoder, it doesn’t actually require much real computation. So doing that probably wouldn’t net any performance benefits, especially since it can stitch together a 120-frame animation in like 20 milliseconds already.

But one of the sad things about it is that now it uses Blobs instead of strings, which is great and all except that blobs are actually slower than strings because it still has to do the DataURL conversion from string to Blob. That’s pretty lame. Firefox supports the canvas toBlob thing, but for some reason Chrome doesn’t, but eventually it probably might, and that might be useful to add.

Also, if someone ever makes a Javascript Vorbis encoder, it would be nice to integrate that in, since this currently only does the video part, but audio’s also a pretty big part.


Multicore Javascript Pi Computing with WebWorkers 14 July 2010

Selection_012
http://antimatter15.github.com/pi/partial.html It’s not using the fastest algorithm, but the nice thing about this one is that it’s capable of digit-extraction (calculating one section without knowing the digits before it) and was nice for doing distributed computing. This also has the nice side effect of working pretty well with the MapReduce paradigm (To calculate a block, calculate primes 3 to 2*N, map it all to the magical pi algorithm and then add it all up and truncate the fractional part, however it doesn’t really use MapReduce because there aren’t enough machines/threads to make it really necessary to distribute out the reducing part). So on the time-memory tradeoff scale, this algorithm uses low memory and is slower, which makes it pretty good for the purposes of something implemented with WebWorkers as I can’t imagine it would be good to have the same data multiplied by the number of threads and having lots of data being passed with each postMessage.

Wave Reader 4.6 - Insanely Fast Edition 14 January 2010

Loading a 500 blip wave in Google’s GWT Client takes 3:34 to get to a usable state (Where the scroll bar works) on a 3ghz Core2 Duo (whose extra core admittedly won’t do much). It also uses 972 MB of RAM.

Loading the same wave in my Wave Reader, takes 678 milliseconds. A 315x speed-up. Also, my client is totally unoptimized, pure 30KB of javascript. On top of those features, anyone can view waves, without a google account, individual blips can be linked to, it supports rendering almost everything Wave can, that is gadgets, inline replies, nesting, font color/size, italics, bold, everything you could probably expect. Interestingly, when you add an attachment to Wave, and delete the parent blip, it still stores the attachment on the current wave state, and this client can display/link to them without using Playback. There is an option to generate plain simple HTML for turning a Wave into a standalone page or Website. Private waves can be exposed read-only as a website simply by adding the gwavereader@googlewave.com username.

Using it is simple, take a Wave https://wave.google.com/wave/#restored:wave:**googlewave.com!w%252Br5lewFqCA** and then put it after the Wave Reader URL http://antimatter15.com/misc/wave/read.html?**googlewave.com!w%252Br5lewFqCA** And magically you have a super awesome URL to link to.

You can learn some tricks on how to use it to do some more awesome things http://antimatter15.com/misc/wave/read.html?googlewave.com!w%252BrnG0vaFXA such as the before mentioned HTML generation.

Samples (Some random waves): http://antimatter15.com/misc/wave/read.html?googlewave.com!w%252Br5lewFqCA (New for 4.6 Inline reply support) http://antimatter15.com/misc/wave/read.html?Ze3l0mj0A http://antimatter15.com/misc/wave/read.html?oPg9HfEXE&beta http://antimatter15.com/misc/wave/read.html?Mu9eK7j2H http://antimatter15.com/misc/wave/read.html?AhbL5fooD&beta http://antimatter15.com/misc/wave/read.html?googlewave.com!w+UDMZOGpSG


JS vs Python 27 August 2009

I sorta expected it due to the new V8, Tracemonkey, Nitro, and SquirrelFish engines. But I’m thinking of making a port of ShinyTouch to JS and I was looking into what differences it might end up as.

I have to say I’m really quite suprised. It’s a simple piece of code:

setTimeout(function(){
    var start = (new Date).getTime();
    var n = 0;
    for(var i = 0; i &lt; 10000000; i++){
        n += i;
    }
    var end = (new Date).getTime();
    alert(end-start);
},5000)

Just doing a loop a huge number of times and adding some numbers. But the unscientific results are quite amazing:

Python: 2640, 2110, 2000, 2190

Firefox 3.0 Spidermonkey: 777, 672, 685, 665

Firefox 3.5 TraceMonkey: 659, 365, 629, 629

Chromium Nightly: 146, 150, 147, 152

While these only test basic arithmetic and recursion, The browser is 15 times faster than Python, it just feels quite incredable.


vX JS Library 13 July 2009

vX is the world’s smallest Javascript library. It’s modular, powerful, unlikely to interfere with operations of other libraries, open source (MIT license), and cross-browser. It’s designed with size first and foremost and everything else secondary. The cross-browser GET/POST AJAX function with callbacks is only 200 bytes. The closest thing is over twice the size. This extreme density is present in every function of the library.

Currently, the whole framework, including Ajax, Events, URL Encoding, Animation (including Fading), Namespacing, JSON Serialization, JSON Parsing, Document onReady, HTML entities encode/decode, Array Index, Get Elements By Class Name, Object Extending, Templating, Queueing, Class Manipulation and more. is under 3KB total uncompressed.

All functions are aliased to full reader-friendly names as well as very consise abbreviations. For example, Ajax can be accessed by.ajax or .X.


New MirrorTouch Algorithm 27 June 2009

MirrorTouch Diagram
MirrorTouch Diagram

MirrorTouch (the new name for my mirror-based multitouch system). For those who don’t remember, it is a project to create a retrofittable cheap new technology for touch detection. It can be made of mostly off-the-counter or even household items. The software has the potential to be VERY fast, many orders of magnitude faster than the current technology. It is less seceptable to occlusion than many other technologies.

It began well over 2 months ago. It started out with IDEALISTIC paint sketches and then a VB.NET application to parse it. Then it was ported to Python and could handle the same sketches. After discovering that in real life the positioning of the points varies due to some very strange and illogical factor, the project had a several-month hiatus.

The issue is clearly demonstrated here:

noooo!! why doesnt it work?!?!?!?!?!
Oh Noes!

Last week, I considered the project a failure. I was playing around with a flashlight and tried looking into the strange behavior of the light. And something began to dawn on me. The shape as on diagram 1, can be flattened out as a visualization for what it behaves like. So from the pyramid shape, it looks more like a little 4-pointed star. Since the mirror is only on two sides, you can simplify it to half a star emerging from a square.

The diagram
Flattened Diagram

To the side is a geometicalified sketch of it from my notebook. Here you can see the relation between the point and where it shows up on the mirror.

From that, you can use the distance between m and the y point (y-m) and divide it all over the distance from the mirror to the webcam (l) and plug it into y=mx+c form. Repeat that over the x axis and you can use basic algebra to find the interesction.

From that is the new magical formula that powers the application:

Yay! Purtyful!
Yay! Purtyful!

The new formula is so magical that it actually works. Yes, it’s amazing, it has survived the most strictest of tests of mathematical consistency. It works.…. At least in theory. Now what about scientific tests? Oh no! it actually has to work in the physical world? Oh no!

With these 2 magical equations. I have (theoretically) in an idealistic model of the system, solved the issue with distortion. It should theoretically resolve all issues with the system. It should work.

So i set up the model again, attaching my webcam to a ruler and taping it to a speaker. Taping mirrors down on a piece of paper, and this time, Scribbling down measurements on the side. I got it to work. Workign without resetting configuration every time it ran. It works. It truly actually works. Multi-Touch too.

Since I cant get the webcam to feed directly to the python script, I have to use Cheese (it’s a linux app for taking pics from a webcam) to save screenies of the webcam mounted percariously from a ruler using only a bit of transparent Scotch tape. I copy the images over to the mirrortouch directory and go in the commandline and type in python process.py and watch as lines of logging output fly past as the windows autoscrolls down filled with coordinates and color hashes.

I watch as it generates a .png file.

It works in the _real_ world!

Yes it works! AMAZING!

Note: The random scribbles in the back aren’t for any contstructive purpose. No, actually they just stop my stupid webcam from adjusting the contrast and making everything all ugly and ewwie. If my webcam sucked less than maybe it would work but my webcam really does really really really suck.

Now if it could get ported over to somethign like C++, and actually parse a live video feed from the webcam then it may become an actual working implementable multitouch technology. As it stands, it’s just a multitouch proof of concept, and I don’t know C++ so it probably won’t work.

Anyone dying for the source code can find it in the SVN repository at : http://code.google.com/p/mirrortouch/ Just beware that it may take lots of scary and tedious configuring in current stages (Configuring color range of background in the band, configuring color range of target, setting distances and middle length and other horrors, but from the SVN you can also do the insanely boring act of running various images that are already there through the script, and most of the images just wont work even with replacing huge blocks of code).


vX JS Library 12 October 2008

Built on top of the vX Ajax Function, is the vX JS Library. It’s probably the world’s smallest JS Library, in total, about 1.45kb, with things like Animations, Ajax, JSON Serialization, URL Encoding, Cloning, Event Handling, Fade Effects, and more. It’s signifigantly less elegant than jQuery and others, but it is extremely lightweight and quite cross-platform. The code has been optimized down to each individual byte.

http://code.google.com/p/vxjs/

It’s not too useful. It may be useful for some tiny things, but it’s not really that useful.

It’s not good enough to make things really high-quality, or complex such as the Ajax Animator. It’s good only if your making like something small, where you might want some ajax, but still want it to load fast.

Also, another thing, not exactly part of the library is vXg, a Get-Only version of vX that’s only 221 bytes. http://vxjs.googlecode.com/svn-history/r26/trunk/ajaxget.js

vXg(URL, CALLBACK)


vX Ajax Function 07 October 2008

For one of my projects, I needed a really simple, lightweight one. It’s super lightweight. I mean really. really lightweight. Only 337 bytes (though 1 kilobyte of random crap in front of it would make it 1337 bytes). Most libraries are over 60kb! If you’re using it only for ajax. You’re using 180 TIMES what you really need.

This one can do GET/POST requests with a callback

/*vX Ajax Function. (C) Antimatter15 2008*/
function vX(u,f,p){var x=(window.ActiveXObject)?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();
x.open(p?"POST":"GET",u,true);if(p) x.setRequestHeader("Content-type","application/x-www-form-urlencoded");
x.onreadystatechange=function(){if(x.readyState==4&amp;&amp;x.status==200) f(x.responseText)};x.send(p)}

It takes 3 parameters. the URL, the Callback function, and the post parameters (optional).

vX(AJAX URL, CALLBACK FUNCTION[, POST PARAMETERS]);

Note that here the callback is required, not optional, though it could probably be made to do that by changing f?f(x.responseText):x.

To Use:

GET:

vX("ajax.php?you=suck&amp;howmuch=alot", function(responsetext){alert(responsetext)})

POST:

vX("ajax.php", function(responsetext){alert(responsetext)}, "you=suck&amp;howmuch=alot")

That’s it. In case your wondering what the name is, I wanted somethign that was short so it was lightweight. I didnt want it to be single letter because single-letter names are likely to collide with other libraries. Also because “V” and “X” are two widely overused characters anyway. Another reason might be that you dont know what version it is :P


New Features coming in Ajax Animator 0.15 (aka 1.5, read to find out why) 02 December 2007

Okay, so one day i felt crazy and changed everything by 1 decimal place because i don’t want this to seem misleadingly good. I mean, if it hits a 1.0 release, then some people would think it’s almost as good as Flash 1 (futuresplash animator) which it it isn’t even near yet.

So it should be 1.5 but now it’s 0.15 :D

Read more to find out the whole list, a summary of it would be axml2, UI polishing, save space, nicer code (but still hideous), css, users, tweening, finish partially completed ideas etc.

What’s done so far

  • Redesigned Register UI
  • Save Lots of code
  • New Save/Open file format (around 5x faster, and 10 times smaller)
  • Relocating stuff
  • interactive tutorials
  • Backwards Compat Mode
  • for the first time it’s gonna be a legitimate GPLv2 project (I’m gonna include the gpl.txt file for once)
  • replaced wz_tooltips with native ext.js ones
  • Change save file to computer architecture
  • change organization of Save/Open buttons in file menu (submenus)
  • optimized stuff
  • fixed bugs
  • No more save/open window (now, single-purpose dialog alerts, much better)
  • Progress bars
  • User friendly upload error message (yay!)
  • relocate css
  • delete lot’s of stuff from user-management
  • REAL SUPPORT FOR LINES/ELLIPSES, lines didn’t work for tweening, ellipses didn’t work for tweening or flash, and ALL suffered from a programming error causing line-widths to be messed up.
  • FastMode …and more to come