Quantcast

Evolution control surface



Evolution control surface, originally uploaded by tiki.robot.

Snuggle tunnel



Snuggle tunnel, originally uploaded by tiki.robot.

Dorkbot sf



Dorkbot sf, originally uploaded by tiki.robot.

My parents on the playa

I love this pic of my mom at Pyramid Lake that my dad sent from his iPhone while they were wandering around Nevada. Next year they’ll probably go to Burning Man without me.

Why gcc has a free Objective C frontend

Apple compiles OS X and almost all of its software with gcc. I still find it hard to believe that such a secretive company builds almost all of its software products using gcc, the compiler that anchors the Free Software movement.

Apple’s uses Objective C because NeXT used Objective C. When Steve Jobs was at NeXT, he didn’t want to place their objc gcc frontend under the GPL, but ended up having to. Here is an excerpt of an email from Stallman:

I say this based on discussions I had with our lawyer long ago.  The
issue first arose when NeXT proposed to distribute a modified GCC in
two parts and let the user link them.  Jobs asked me whether this was
lawful.  It seemed to me at the time that it was, following reasoning
like what you are using; but since the result was very undesirable for
free software, I said I would have to ask the lawyer.
 
What the lawyer said surprised me; he said that judges would consider
such schemes to be "subterfuges" and would be very harsh toward
them.  He said a judge would ask whether it is "really" one program,
rather than how it is labeled.
 
So I went back to Jobs and said we believed his plan was not allowed
by the GPL.
 
The direct result of this is that we now have an Objective C front
end.  They had wanted to distribute the Objective C parser as a
separate proprietary package to link with the GCC back end, but since
I didn't agree this was allowed, they made it free.

So that’s why. Via this email thread between Richard Stallman and Bruno Haible about why Common Lisp is under the GPL. Via reddit.

Apple’s move to the GNU Toolchain has been very good for developers (remember MrC and MPW?), but it sure took a long time to get here. Yesterday I remotely debugged an iPhone app using gdb. Spending time in a debugger isn’t usually a very pleasant, but I surprisingly happy when gdb stopped at my first breakpoint…

photo.jpg



photo.jpg, originally uploaded by tiki.robot.

photo.jpg



photo.jpg, originally uploaded by tiki.robot.

Announcing the Open Library Blog

Check out the new Open Library Blog! Development on openlibrary.org is happening at a fantastic pace, and hopefully the new blog will help people keep up with new features of the site.

I set up the Open Library Blog with the new WordPress 2.7 beta, which is big improvement over the older WP version that we use on TikiRobot. The OL Blog also uses a clean, widget-capable theme, and a syntax highlighter plugin that is better maintained than the one we use on TR. The visual editor in 2.7 works well, which means I don’t have to install any markup plugins. I can’t wait to update TikiRobot to modern software and get rid of the clunky CSS that we’ve inherited!

Official light bulb of the Internet

ffmpeg hook to aid with “rectangular pixels”

Tired of screen-scraping the output of ffmpeg and/or mplayer to get the parameters / clip info for a media file?

This hook attempts to remedy this by printing simple information about the passed in video from the cmd line.

It will also print out whether or not the clip is using “rectangular pixels”.

WTF is a rectangular pixel?

 

Well, the easiest examples are DVDs.  You only want to buy a DVD if it says one of two standard phrases on it — “Enhanced for 16:9 TVs” or “Anamorphic widescreen“.  They both mean the same thing — namely that the video on the DVD disk is wider than 4:3 aspect (pretty much all films are ratio 16:9 or even wider like ratio 2.35:1) *and* that it didn’t *waste* any DVD bytes by encoding “top/bottom black bars”.  (If it doesn’t say those code phrases, it’s an older, crappy/low budget produced, or worse a “pan-n-scan” chopped film (where they lop off the left and right sides of each frame to fit into a 4:3 TV!)  Worst yet, if the DVD only says something like “widescreen version”, though it sounds good, it means while they didn’t cut off the picture, they wasted 25% (or more!) of the pixels encoding “black bars” on the top and bottom.  So you have less pixels in the DVD encoding the picture compared to an “anamorphic” version of the same thing.  Hello crappy quality!)

 

 

Anamorphic DVDs are encoded internally at 720×480 pixels per image.

Now look at this:

  4:3 video == 1.33 ratio == 640×480 pixels image

16:9 video  == 1.78 ratio == 854×480 pixels image

so what is 720×480?  it’s almost perfectly in the middle of those two — math: 720/480 = 1.5

So the “encoded transport image size” is neither 16:9, nor 4:3 — it’s right in the middle, capable to encode either a 4:3 video (like non-high def TV, many computer screens) or 16:9 video (high def TV, some digital video).  I like to think of it as “how the formats that came out right before HDTV took off, compromised to hedge there bets to be between 4:3 and 16:9″.

The final critical bit of information about a DVD is the “aspect ratio” (not of the overall image, confusingly, but of each encoded *pixel*!)  This says “wait, this pixel isn’t square, literally, like you’d think if you just read the image — it’s actually supposed to be stretched to make the *overall image* either 640 pixels wide (squoosh down from 720) or 854 (stretch wider to 854).  So the video track is “flagged” with a “pixel aspect” (often referred to as PAR (Pixel Aspect Ratio), SAR (Sample Aspect Ratio), or DAR (Display Aspect Ratio) — some of those have some slight nuances/differences, but that’s digging too deep).  Anyway, neat, huh?  Your anamorphic DVD is a changeling!  (maybe “anamorphic” makes more sense mnemonically now 8-)  (PS: “DV” video — the most common format that digital camcorders that write to tape use — is similar.  720×480 pixels/image plus a “flag” for what each pixel “shape” is).

 

This hook I wrote will output information about the clip (like “ffmpeg -i” will do, but in a format easier to parse) as well as information about the pixels (unlike ffmpeg).  So you can then know more about a clip if you are going to do things like pull single frames/thumbnails from it or convert it to another format.  We have been using this at Internet Archive for our movies for over a year and a half now and it works great!

 

C Code is here.  

There are some instructions for compiling with an ffmpeg source at the top of the C code.  (There is also an ubuntu-on-AMD compiled “.so” at that link by changing the suffix from “.c” to “.so”, FWIW)

 

Example invocation and output:

ffmpeg -vhook "/petabox/deriver/identify.so oldpresidio.mpeg"
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2007 Fabrice Bellard, et al.
  configuration: --enable-gpl --enable-pp --enable-libvorbis --enable-libogg --enable-liba52 --enable-libdts --enable-dc1394 --enable-libgsm --disable-debug --enable-libfaac --enable-libfaad --enable-libmp3lame --enable-x264 --prefix=/usr/
  libavutil version: 49.3.0
  libavcodec version: 51.38.0
  libavformat version: 51.10.0
  built on Nov 30 2007 19:09:20, gcc: 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)
Video: mpeg2video, yuv420p, 720x480, q=2-31, 8000 kb/s
width: 720
height: 480
aspect: 32/27
fps: 29.97
duration: 00:03:05.2
audio: true
Failed to Configure /petabox/deriver/identify.so
Failed to add video hook function: /petabox/deriver/identify.so oldpresidio.mpeg
The “failure” above at the end is deliberate/OK (it just makes sure ffmpeg stops and doesn’t try to transcode).
So we see that this video clip:
is indeed widescreen by the “aspect” line above (indicating the pixels are rectangular, not square) with value 32/27.
If we multiply the encoded image width of “720″ by 32 and divide by 27, we get the magic/correct 853.33 (round up or down to nearest pixel).
We use this utility at Internet Archive to make user friendly formats like “h.264 .mp4″ videos and “Ogg Theora .ogv” videos that get converted to the proper square pixel equivalent (and *not* messup widescreen videos 8-)

Anti-prop 8 rally in union square

Fixing a bug in gnu tar



Fixing a bug in gnu tar, originally uploaded by tiki.robot.

xeyes is watchin our back.

Monkey Guard Dog

I love this image. Apparently this orphan monkey was being bullied at a zoo in China so the zookeepers gave it it’s own guard dog. Now the mean alpha monkeys stay away.

…the baby monkey is also very smart. Each time he smells danger he runs to jump on the dog’s back and holds on tight. The alpha male monkey has been really unhappy since we sent in Sai Hu. He tried to organise several ambushes on the little monkey, but they all failed because of the dog,” said a zoo spokesman.

Pics from the Halloween Renegade

Since 2001, we’ve spent Halloween morning with a few hundred of our freaky friends. This year we had a spectacular new location and plenty of donuts and bacon. Thanks for another crazy year, Brass Tax crew!

IMG_4963

IMG_4964
(more…)

Showing Twitter Status On Your Group Blog

First a bit of meta discussion: I changed the left sidebar of TikiRobot to show the five most recent status updates from the fellow robots! It was kind of silly to display tweets from people who haven’t updated since last year. If you want your status to show up in the sidebar, and it isn’t there for some reason, lemme know!

Twitter has an API for showing for retrieving the most recent status updates from your friends, so I created a new twitter user to follow the tikirobot posters. Then, I used this python script to fetch the friends timeline and spit out html for the blog. I wanted to do this all in javascript, but the the friends timeline api needs authentication, and I didn’t want to publicize the twitter account password. Plus, this way I can cache the data on our server, so it doesn’t hit twitter so often.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/usr/bin/python2.5
#Copyright(c)2008 TikiRobot.net - Software license GPL version 3.
 
import time
import datetime
import os
import fcntl
import sys
import codecs
import re
 
# CalculateRelativeTime()
#_______________________________________________________________________________
def CalculateRelativeTime(str):
    dt = datetime.datetime.strptime(str, '%a %b %d %H:%M:%S +0000 %Y')
    now = datetime.datetime.utcnow()
    delta = now - dt
    secs  = delta.seconds
    if (delta.days > 0):
        return "%d days ago"%(delta.days)
    elif (secs < 60):
        return "%s seconds ago"%(int(secs))
    elif (secs < 3600):
        return "%s minutes ago"%(int(secs/60))
    else:
        return "%s hours ago"%(int(secs/3600))
 
# main()
#_______________________________________________________________________________
print """Content-type: text/javascript; charset=UTF-8\n"""
 
useCachedRss = True
cacheFile    = 'cache/twitter.json'
sys.stdout = codecs.getwriter('utf8')(sys.stdout)
 
try:
    stats = os.stat(cacheFile)
    if (time.time() - stats.st_mtime) > 300:
        #cache expired
        useCachedRss = False
except OSError:
    #cache file not found
    useCachedRss = False
 
if useCachedRss:
    try:
        #print "reading cached json"
        fh = open(cacheFile, 'r')
        fcntl.lockf(fh, fcntl.LOCK_SH)
        contents = fh.read()
        fcntl.lockf(fh, fcntl.LOCK_UN)
        fh.close()    
    except:
        print "got some kind of error when reading cached json. quitting"
        sys.exit()
else:
    try:
        #print "fetching new json"
        import urllib2
        apiurl = 'http://twitter.com/statuses/friends_timeline.json?count=5'
        auth_handler = urllib2.HTTPBasicAuthHandler()
        auth_handler.add_password(
            realm='Twitter API', 
            uri=apiurl,
            user='username',
            passwd='password'
        )
        opener = urllib2.build_opener(auth_handler)            
        urllib2.install_opener(opener)
        urlfh = urllib2.urlopen(apiurl)
        contents = urlfh.read()
        urlfh.close()
        fh = open(cacheFile, 'w')
        fcntl.lockf(fh, fcntl.LOCK_EX)
        fh.write(contents)
        fcntl.lockf(fh, fcntl.LOCK_UN)
        fh.close()
    except:
        print "got some kind of error when fetching twitter timeline. quitting"
        sys.exit()
 
 
import json
timeline = json.read(contents)
htmlstr = ""
for i in range(5):
    name = timeline[i]['user']['screen_name']
    imgurl = re.sub(r'_normal.(jpg|png)$', r'_mini.\1', timeline[i]['user']['profile_image_url'])
    twit   = re.sub(r'\'', '&#39;', timeline[i]['text'])
    twit   = re.sub(r'\n', ' ', twit)
    twit   = re.sub(r'http://tinyurl.com/(\S+)', r'<a href="http://tinyurl.com/\1">tinyurl.com/\1</a>', twit)
    when   = CalculateRelativeTime(timeline[i]['created_at'])
    htmlstr += """<div class="twitter">"""
    htmlstr += """<img src="%s"/>"""%(imgurl)
    htmlstr += """<div class="twitterRight">"""
    htmlstr += """<a href="http://twitter.com/%s"><strong>%s</strong></a>: """%(name, name)
    htmlstr += twit
    htmlstr += """<span class="twitterMeta">- """ + when + "</span>"
    htmlstr += """</div>"""
    htmlstr += """<div class="clear"></div>"""
    htmlstr += """</div>"""
 
print """var tikiTwits = '"""+htmlstr+"';"
print """document.write(tikiTwits);"""

It’s fun to see that Twitter still uses the Javascript API that I proposed to them over the phone a couple years ago.

Also, dear lazyweb: please send my a python function that converts a UTC date string to PST. Thanks!

geek stuff from archive.org — making Ogg Theora videos

Fast, reliable way to encode Theora Ogg videos using ffmpeg, libtheora, and liboggz

archive.org has started to make theora derivatives for movie files, where we create an Ogg Theora video format output for each movie file.   after trying a bunch of tools over a good corpus of wide-ranging videos, i found a neat way to make the Archive derivatives.

 High Level:

  • use ffmpeg to turn any video to “rawvideo”. 
  • pipe its output to *another* ffmpeg to turn the video to “yuv4mpegpipe”.
  • pipe its output to the libtheora tool. 
  • for videos with audio, ffmpeg create a vorbis audio .ogg file. 
  • add tasty metadata (with liboggz utils). 
  • combine the video and audio ogg files to an .ogv output!   

Detailed example:  

 
/usr/bin/ffmpeg -v 0 -an -deinterlace  -s 400x300 -r 20.00 -i CapeCodMarsh.avi -vcodec rawvideo -pix_fmt yuv420p -f rawvideo -  | \
/usr/bin/ffmpeg -v 0 -an -f rawvideo   -s 400x300 -r 20.00 -i - -f yuv4mpegpipe -  | \
/petabox/deriver/libtheora-1.0/lt-encoder_example --video-rate-target 512k - -o tmp.ogv;
 
/usr/bin/ffmpeg -y -i CapeCodMarsh.avi -vn -acodec vorbis -ac 2 -ab 128k -ar 44100 audio.ogg;
/petabox/sw/bin/oggz-comment audio.ogg -o audio2.ogg TITLE="Cape Cod Marsh" ARTIST="Tracey Jaquith" LICENSE="http://creativecommons.org/licenses/publicdomain/" DATE="2004" ORGANIZATION="Dumb Bunny Productions"  LOCATION=http://www.archive.org/details/CapeCodMarsh;
/petabox/sw/bin/oggzmerge tmp.ogv audio2.ogg -o CapeCodMarsh.ogv;

WTFs:

  • Why the double pipe above? Some videos could not go directly to yuv4mpegpipe format such that libtheora (or ffmpeg2theora) would work all the time.
  • We do the vorbis audio outside of libtheora (or ffmpeg2theora) to avoid any issues with Audio/Video sync.
  • We convert to yuv420p in the rawvideo step because ffmpeg2theora has (i think) some known issues of not handling all yuv422 video inputs (i found at least a few videos that did this).
  • We add the metadata to the audio vorbis ogg because adding it to the video ogv file wound up making the first video frame not a keyframe (!)

So this will end up working in Firefox 3.1 and greater — the new HTML “video” tag:

<video controls=”true” autoplay=”true” src=”http://www.archive.org/download/commute/commute.ogv”> for firefox betans </video>

This technique above worked nicely across a wide range of source and “trashy” 46 videos that I use for QA before making live a new way to derive our videos at archive.org ( http://www.archive.org/~MY-FIRST-NAME/_/stream.php  [sorry don't necessarily want all that crawled by non rajbot robots] )

-tracey jaquith   “don’t make me 3:2 pulldown you”

Yes we CAN



Yes we CAN, originally uploaded by tiki.robot.

Obama



Obama, originally uploaded by tiki.robot.

photo.jpg



photo.jpg, originally uploaded by tiki.robot.

Good luck cupcakes



Obama cupcakes, originally uploaded by tiki.robot.

Raj made these! they worked!

may

This better work…