It’s already week 4 of Hacker School. I ended up messing up my post schedule by pulling a crazy all-nighter last week, which led to an unproductive Thursday and Friday, and then I got sick over the weekend. Week 3:
- Hacker School Day 11: Content Negotiation, Validation, JSON, TTLs, Ugly Commits
- Hacker School Day 12, Day 13 Combo – All Nighter
Thursday and Friday went by quickly since I was pretty tired. I got in late on Thursday and worked feverishly to make slides for my presentation on Youtube-Gif-Go. The slides are available here. I ended up breaking part of the web frontend right before the presentation, but didn’t notice until I was in front of everyone! Oh well. The command-line consumer worked 🙂
I spent Friday working more on the frontend consumer after being inspired by a conversation on Zulip about what it means to “finish” a project. I also spent a lot of time with Peter Seibel, the author of Coders at Work and the resident at Hacker School last week. I asked him about Twitter and for some recommendations for functional languages. Later, he gave a mini presentation on monads. I’ve now been to a few different talks on monads, and I think everybody’s collective description is starting to make sense (no burritos). At the end of the day a few of us joined together for a job interview prep meetup and that was good too.
I was sick all weekend and didn’t do much. I almost started working on something to parse old Age of Empires II recordings and then stopped.
This morning I took some DayQuil and my senses were kind of dulled. It turned out to be a perfect time to accidentally grind through some of the finishing touches on the frontend and some boring backend problems. I did a couple things today:
- GraphicsMagick is a fork of ImageMagick that’s been around for a while and is twice as fast in my use-case (stitching images into GIFs). The flags are almost identical.
- Mplayer was lying. If I asked for a GIF starting at 5 seconds, and ending at 7 seconds, I’d get a gif that was less than a second long. Checking the output directory of the PNG generation showed 12 frames of output on a 30FPS video (there should have been ~60 frames depending on how accurate everything was). I couldn’t seem to force mplayer to play it at a real rate, so I swapped it out for avconv.
- Finally made it so the frontend consumer loops the video. So when you want a GIF from second 5 up to 7 seconds in, it should keep showing that range so you can get a feel for the gif. It was a simple setInterval that checks if the video is past the range.
- Added the word “go” in front of another word to make everything faster :). I moved some code around and was able to make the backend workers handle multiple jobs at once. I expected to need to do more work for this, but Golang (and some pre-planning) made this simple.
- Made cropping better in a cheat-y way. I was trying to crop a video and getting the wrong output area in the GIF, or it would fail entirely. The backend was downloading the video at a different resolution. I started working on this by thinking about sending the current resolution to the backend/scaling the crop coordinates, but I cheated. I made the player slightly larger, and now the video the user sees is “medium”-sized (in YouTube-API speak). This happens to be the size I’m getting and works surprisingly well for a total hack.
It’s almost done for now. It’s at a point where I’m happy, but there’s so much more I could keep doing:
- Right now, you create a resource at /gifs, which spits back a GIF ID. You poll that resource, which returns status JSON, and then eventually turns into a GIF. I want to make it so hitting /gifs returns a job ID, then poll that job until it’s created, then hit the GIF.
- I want to do some WebSockets stuff, then copy the working frontend and make a WebSocket version.
- It would be nice to include percentages complete in the status for stitching images. I think I can eek this out of GraphicsMagick with the -monitor or -debug flag.
- The ops slog — it would be technically good to wrap up the backend stuff, maybe in Docker or something. I always feel happy after I do this, but until then I feel like my screen session works 🙂
Tonight we went to Trello’s offices to hear about Functional Reactive programming in Objective-C. Trello’s offices are absolutely beautiful — cool style, and an awesome view. It was cool seeing the offices for the programmers too. Week 4 is already here!
edit: MFW the frontend starts working the way I want: