debuggable

 
Contact Us
 
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13

Git remote hates you

Posted on 17/11/09 by Felix Geisendörfer

No, you didn't do anything wrong. Git sometimes is like your best friend who secretly hates you. Let's say you start a fresh new project:

mkdir new-project
cd new-project
git init
touch README
git add README
git commit -m 'first commit'
git remote add origin git@github.com:felixge/new-project.git
git push origin master

So far so good. But - if like any self respecting geek, you juggle a million git repositories on your machine - you will soon have forgotten whether you started or cloned this particular repository. If you are unlucky that means you will run into this:

% git push
fatal: The current branch master is not tracking anything.

Not helpful. "git pull" seems to try to make up for it by giving you way too much information:

% git pull
You asked me to pull without telling me which branch you
want to merge with, and 'branch.master.merge' in
your configuration file does not tell me either.	Please
specify which branch you want to merge on the command line and
try again (e.g. 'git pull <repository> <refspec>').
See git-pull(1) for details.

If you often merge with the same branch, you may want to
configure the following variables in your configuration
file:

    branch.master.remote = <nickname>
    branch.master.merge = <remote-ref>
    remote.<nickname>.url = <url>
    remote.<nickname>.fetch = <refspec>

See git-config(1) for details.

Ok, so what exactly do I have to do to fix this? Right, you ignore all those blobs in your repository making fun of you, and type:

git pull origin master

Using git and feeling like one has a certain overlap in the beginning. On your way to git enlightenment, or to the madhouse, you may eventually discover the fix:

git config branch.master.merge refs/heads/master
git config branch.master.remote origin

And no, do not, not even for a second, assume you could skip "branch.master.remote". Git remote will be very clear about how much it hates you if you do:

% git pull
You asked me to pull without telling me which branch you
...
# The 2s delay made you suspicious, turn off wifi
% git pull
ssh: Could not resolve hostname github.com: nodename nor servname provided, or not known
fatal: The remote end hung up unexpectedly

What in the name of the kernel? Git clearly knows the remote you are talking about, its merely teasing you, possibly corrupting your repo by turning some blobs into LOLcats. For added frustration, here is my output for "git push":

% git push
Bus error

This is probably unique to my install. In case git does not hate you equally, you can try to complain about it in #git. That of course will only result in people telling you that you are being unreasonable. To a kernel hacker, the idea of git remote making some smart assumptions when adding the first remote to your fresh repository that only has a single branch, that is like talking healthcare reform with a right-wing hardliner.

Disclaimer: I love git, but some parts of it seem to purely back up the name. But relax. I'll save talking about git modules, tracking empty folders and checking out partial trees for another time ...

-- Felix Geisendörfer aka the_undefined

 

FFMPEG multiple thumbnails

Posted on 21/10/09 by Felix Geisendörfer

I'm currently implementing /video/thumbnail functionality for transload.it and did some research on how to implement it.

First I set out to create a single thumbnail which was very easy:

ffmpeg -i intro.mov -vframes 1 -s 320x240 -ss 10 thumb.jpg

This takes a video file (-i intro.mov) and extract a single frame (-vframes 1) with 320x240px (-s 320x240) at an offset of 10 seconds (-ss 10) and saves it as thumb.jpg.

So far so good. But we actually want to offer the ability to take multiple thumbnails (like 8) in 1/8th increments of the video playtime. My initial idea was that there had to be more efficient way then calling up ffmpeg 8 times, and indeed I found one:

ffmpeg -i intro.mov -r 1/10 -s 320x240 thumb_%03d.jpg

This command works the same as the one above, except that it tries to set the frame rate to 1/10 (-r 1/10 = 1 frame every 10 seconds) and saves the results as thumb_000.jpg, thumb_001.jpg, thumb_002.jpg etc. Unfortunately I could not get it to produce the exact results I wanted. I would always end up with the first frame being captured twice, and the frame rate I set would be off by 2-3 seconds.

So I hopped to IRC and asked #ffmpeg for help. Dark_Shikari (one of the crazy people who build the best video codec in the world) was kind enough to help me.

It turns out that the offset parameter (-ss) needs to be set before the input parameter (-i). That will cause ffmpeg to seek to that position in the stream *without* decoding it and in fact skipping anything but key frames! This is pretty significant as performance improved from ~20 seconds for 4 thumbnails to about 2-3 seconds.

So my final setup is pretty much like this. First I find out the video duration by running:

midentify intro.mov

This gives me all kinds of useful information including the length of the video:

ID_AUDIO_ID=0
ID_VIDEO_ID=1
ID_FILENAME=intro.mov
ID_DEMUXER=mov
ID_VIDEO_FORMAT=avc1
ID_VIDEO_BITRATE=0
ID_VIDEO_WIDTH=630
ID_VIDEO_HEIGHT=360
ID_VIDEO_FPS=25.000
ID_VIDEO_ASPECT=0.0000
ID_AUDIO_FORMAT=sowt
ID_AUDIO_BITRATE=0
ID_AUDIO_RATE=48000
ID_AUDIO_NCH=2
ID_LENGTH=81.32
ID_VIDEO_CODEC=ffh264
ID_AUDIO_BITRATE=1536000
ID_AUDIO_RATE=48000
ID_AUDIO_NCH=2
ID_AUDIO_CODEC=pcm

I then divide the length by the amount of thumbnails I need, and run a loop like this:

ffmpeg -ss $i*$interval -i intro.mov -vframes 1 -s 320x240 thumb_$i.jpg

Where $i is the number of the thumb I'm extracting and $interval is the duration of the video divided by the amount of thumbs.

Works like a charm!

-- Felix Geisendörfer aka the_undefined

 

Burning Apple

Posted on 13/10/09 by Felix Geisendörfer

Apple fanboy? Caught in the distortion field? No problem, there is a cure:

Play video

As you can see, I have not always been a Mac user. In fact I passionately hated anything Mac after my first contact with an iMac (OS 10.3). I did this video in 2005 while I was a foreign exchange student in Atlanta. My friend in the video is still using PCs - don't flash you fancy macbook next to him in a coffee shop!

Why I have held back posting this for so long? I just integrated transload.it into debuggable.com and needed a video to test. More gems like this are on their way : ).

-- Felix Geisendörfer aka the_undefined

 

7 + 8 === 7 in JavaScript

Posted on 6/10/09 by Felix Geisendörfer

I kid you not, this is an issue I actually ran into a long time ago and have been terribly careful of avoiding ever since.

It must have been a fantastic day in the "Bad Parts" JavaScript department. While one team was busy screwing up the + operator to be responsible for both string concatenation and addition, another team set out to build a nasty trap inside the parseInt() function.

This together results in probably my favourite JavaScript bug of all times. It goes like this: You have two strings that contain zero padded numbers (like hours or minutes) and you want to perform some math on them:

var a = '07';
var b = '08'

alert(a + b);

Of course you would not write such code, but maybe you have a friend who has done it. This friend probably quickly realized that '0708' was not the result he was hoping for, so he got clever and updated his code to:

var a = '07';
var b = '08'

alert(parseInt(a) + parseInt(b));

However, it turns out that the result of this operation is actually 7. SEVEN you ask? Yes: it's not a bug, it's a feature.

JavaScript assumes that any 0-prefixed string ought to be referring to an octal number. This will not become apparent until your string represents an invalid octal such as '08'. So in order to outsmart this "feature" you have to explicitly provide the base for your integer:

var a = '07';
var b = '08'

alert(parseInt(a, 10) + parseInt(b, 10));

I hope this will one day safe somebody the hour of my life that went into this : ).

-- Felix Geisendörfer aka the_undefined

PS: Got a great JavaScript bug like this as well? I'd be happy to hear about it in the comments.

 

Turning JavaScript's arguments object into an array

Posted on 1/10/09 by Felix Geisendörfer

JavaScript is awesome when you stick to the good parts. But sometimes you have to touch it's bad parts. Consider this:

function hello() {
    arguments.unshift('hello');
    alert(arguments.join(' '));
}

hello('pretty', 'world');

"TypeError: arguments. unshift is not a function"! How dare you JavaScript?

JavaScript might trick you into thinking the arguments variable is an array because you can access it like one (arguments[0], arguments[1], ...), but it's lying. The truth is that the arguments variable really is an object.

Lucky for us, the good parts of JavaScript come to rescue, namely prototypical inheritance:

function hello() {
    var args = Array.prototype.slice.call(arguments);
    args.unshift('hello');
    alert(args.join(' '));
}

hello('pretty', 'world');

This creates a variable called args that holds a true array version of the arguments variable. This works by hjacking the Array.splice function to make it work on the arguments variable.

Yes, this is the kind of code you might want to document for the poor kids who will have to debug grandpa's "AJAX museum" one day.

Got a better solution? Let me know!

-- Felix Geisendörfer aka the_undefined

 
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13