Tag Archives: projects

Everything’s a trade-off

My hands, damaged from pull-up and hanging practice with callouses I have to file down or risk tearing off.

My fitness goal for 2024 is to be able to do a single one armed pull-up on each arm. I still want to maintain my previous progress of being able to do a pistol squat (and improve it to be less ugly).

This means I now have to do hand maintenance, which is new to me. I have to take a FILE to my hand to sand down callouses or they build up and TEAR OFF.

An Ode to the Dremel

It’s not the tool I use around the house the most. That’s probably the Skeletool I keep on my hip or my drill. I actually look forward to seeing how fast I can assemble flatpack furniture with my drill.

But the Dremel makes little impossible things possible in a small apartment.

Like when the top for my daughter’s favorite water bottle broke.

It’s a very short task to use the carving attachments to cut the sharp bits off and then use a sander to round over the edges.

A water bottle covered in cute pandas and goat stickers. In front of it, the top is roughly rounded over and sanded down where it was damaged previously.

Little things become easy. Or if we need to cut off a section of our outdoor tiles or small metals sections. If you can’t fit it in tin snips, you can still use the metal cutting disks to cut through it or score things enough to snap.

Every Frame a Wallpaper

Years ago, Tony Zhou and Taylor Ramos made 28 video essays about film form called Every Frame a Painting and it’s incredible in teaching outsiders a whole new way to think about the art of film. The title is perfect. The content is just stunning, simple ways to look at masters of a form at work.

Lots of folks are known for one-shot takes, but this shows how Spielberg sneaks in gorgeous “oners” that do work without calling attention to themselves.

This essay on Fincher is great, but I love the little golden nugget about how spacing shows the evolving relationship between Mills and Somerset

That title always struck me. Every Frame a Painting. That’s gotta be a bar filmakers strive for. Some make it.

Some movies are just so damn beautiful. Just gorgeous.

Like Across the Spider-Verse. Yowza!

Like Sita Sings the Blues! Beautiful.

Like The Fountain

Like the one that you like that isn’t my cup of tea.

Might be nice to see an image from it, right there behind all of your terminals and windows and such, set as your wallpaper. If every frame’s a painting, set a random one as your wallpaper whenever I like it.

So here’s the plan. I want it. So I made it for me. You can have it. But here’s the terms of the deal. I made it for me, so if it doesn’t work for you, you have to make it work for you. If it causes you problems, those are not my problems. If you don’t agree, this isn’t for you.

This will take as an input a movie file, anything that ffmpeg can deal with. You’ll need to install ffmpeg – look on the official site for instructions.

By default, it won’t use the first 5 or last 10 minutes since that’s often the credits. But you can override this.

We’ll find out how many frames are in that remaining part of the movie.

We’ll pick one randomly and extract it from the movie.

Then we’ll set it as your wallpaper. Nice!

Want to change this often? Set up a cron job!

Pulling a single frame out the middle of a movie is CPU intense, so you probably want to use nice in your cron job so it doesn’t interfere with the rest of your work.

Here’s the code, save this in a file called every_frame_a_wallpaper.zsh and then chmod u+x every_frame_wallpaper.zsh

#! /bin/zsh
# This is a pretty processor intensive set of tasks! You should probably nice this script
# as in call it with nice -n 10 "every_frame_a_wallpaper.zsh /path/to/video.mkv"

SCRIPT_NAME=$(basename "$0")

# I like a nice log file for my cron jobs
function LOG() {
  echo -e "$(date --iso-8601=seconds): [$SCRIPT_NAME] :  $1"
}

# set up some options
local begin_skip_minutes=5
local end_skip_minutes=10
local wallpaper="$HOME/Pictures/wallpaper.png"
local usage=(
	"$SCRIPT_NAME [-h|--help]"
	"$SCRIPT_NAME [-b|--begin_skip_minutes] [-e|--end_skip_minutes] [<video file path>]"
	"Extract a single random frame from a movie and set it as wallpaper"
	"By default, skips 5 minutes from the beginning and 10 from the end, but this is overridable"

)

# the docs suck on zparseopts so let this be a reference for next time
# -D pulls parsed flags out of $@
# -F fails if we find a flag that wasn't defined
# -K allows us to set default values without zparseopts overwriting them
# Remember that the first dash is automatically handled, so long options are -opt, not --opt
zparseopts -D -F -K -- \
	{h,-help}=flag_help \
	{b,-begin_skip_minutes}:=begin_skip_minutes \
	{e,-end_skip_minutes}:=end_skip_minutes \
	|| return 1

[[ -z "$flag_help" ]] || {print -l $usage && return }
if [[ -z "$@" ]] {
   print -l "A video file path is required"
   print -l $usage && return

} else {
   MOVIE="$@"
}

if [[ $DISPLAY ]]
then
  LOG "interactively running, not in cron"
else
  LOG "Not running interactively, time to export the session's environment for cron"
  export $(xargs -0 -a "/proc/$(pgrep gnome-session -n -U $UID)/environ") 2>/dev/null
fi

LOG "skipping $begin_skip_minutes[-1] minutes from the beginning"
LOG "skipping $end_skip_minutes[-1] minutes from the end"
LOG "outputting the wallpaper to $wallpaper"
LOG "using file $MOVIE"

LOG "Let's get a frame from ${MOVIE}";


LOG "What's the duration of the movie?"
DURATION=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 \
  $MOVIE);
DURATION=$(printf '%.0f' $DURATION);

LOG "Duration looks like ${DURATION} seconds";

LOG "what's the frame rate?"

FRAMERATE=$(ffprobe -v error -select_streams v:0 \
  -show_entries \
  stream=r_frame_rate \
  -print_format default=nokey=1:noprint_wrappers=1 $MOVIE)




FRAMERATE=$(bc -l <<< "$FRAMERATE");

FRAMERATE=$(printf "%.0f" $FRAMERATE);

LOG "Looks like it's roughly $FRAMERATE"

FRAMECOUNT=$(bc -l <<< "${FRAMERATE} * ${DURATION}");
FRAMECOUNT=$(printf '%.0f' $FRAMECOUNT)
LOG "So the frame count should be ${FRAMECOUNT}";


SKIP_MINUTES=$begin_skip_minutes[-1]
SKIP_CREDITS_MINUTES=$end_skip_minutes[-1]

LOG "We want to skip $SKIP_MINUTES from the beginning and $SKIP_CREDITS_MINUTES from the end".

SKIP_BEGINNING_FRAMES=$(bc -l <<< "${FRAMERATE} * $SKIP_MINUTES * 60");
LOG "So $SKIP_MINUTES * 60 seconds * $FRAMERATE frames per second = $SKIP_BEGINNING_FRAMES frames to skip from the beginning."
SKIP_ENDING_FRAMES=$(bc -l <<< "${FRAMERATE} * $SKIP_CREDITS_MINUTES * 60");
LOG "So $SKIP_CREDITS_MINUTES * 60 seconds * $FRAMERATE frames per second = $SKIP_ENDING_FRAMES frames to skip from the ending."

USEABLE_FRAMES=$(bc -l <<< "$FRAMECOUNT - $SKIP_BEGINNING_FRAMES - $SKIP_ENDING_FRAMES");
UPPER_FRAME=$(bc -l <<<"$FRAMECOUNT - $SKIP_ENDING_FRAMES")
LOG "That leaves us with ${USEABLE_FRAMES} usable frames between $SKIP_BEGINNING_FRAMES and $UPPER_FRAME";

FRAME_NUMBER=$(shuf -i $SKIP_BEGINNING_FRAMES-$UPPER_FRAME -n 1)
LOG "Extract the random frame ${FRAME_NUMBER} to ${wallpaper}";
LOG "This takes a few minutes for large files.";
ffmpeg \
  -loglevel error \
  -hide_banner \
  -i $MOVIE \
  -vf "select=eq(n\,${FRAME_NUMBER})" \
  -vframes 1 \
  -y \
  $wallpaper


WALLPAPER_PATH="file://$(readlink -f $wallpaper)"
LOG "Set the out file as light and dark wallpaper - using ${WALLPAPER_PATH}";
gsettings set org.gnome.desktop.background picture-uri-dark "${WALLPAPER_PATH}";
gsettings set org.gnome.desktop.background picture-uri "${WALLPAPER_PATH}";

In my crontab I call it like this:

# generate a neat new background every morning
0 4 * * * nice -n 10 ~/crons/every_frame_a_wallpaper.zsh -b 5 -e 12 /home/mk/Videos/Movies/Spider-Man_Across_the_Spider-Verse.mkv >> ~/.logs/every_frame_a_wallpaper/`date +"\%F"`-run.log 2>&1

Automated export of your goodreads library

Goodreads used to have an API but they stopped giving access and it looks like they are shutting it down. A real garbage move.

I like to be able to use my data that I put in so I wrote a script to automatically download my data regularly. Then I can do stuff like check to see if books I want are in the library or keep my own list or analytics, etc.

Here’s the python script to export your good reads library, hope it helps you. I’ll put it in the public domain.

Updated to add: I got tired of dealing with places that do garbage moves. I left GoodReads for BookWyrm and it’s better.

Quick Project Names Demo

At work, I’m trying to convince people that we should auto-generate at least a suggested code name for our project names. It’s an important thing for compliance and secrecy. You’d rather someone is overheard talking in the elevator about “Project Icy Gneiss” than about “the restructuring of Acme Corp”.

I wanted to make the point that if you just have a small list of adjectives and nouns you quickly get a vast space of possible names – more than we’ll exhaust.  But a working demo is more persuasive than logic.

I knocked this together last night: Projects-a-Plenty.

projects-a-plenty

Used bootstrap & angular which is kind of overkill on something this tiny.

Quick TV Pillar Mount Project.

early assembly with TV

Now that Maximum Baby is crawling I wanted to get our huge tv off of the rickety cart it was sitting on. Sam had a tv fall on her as a child and one is enough for us.

The tricky thing here is that we wanted to mount the TV on a concrete pillar.

Trying to attach a flat thing to a curved thing is tricky.  My solution was this:

  1. Got a 2×8 of Douglas Fir from my local Home Depot. They usually have crappy wood, but I managed to find a piece that looked quarter-sawn, so that’s good.
  2. Cut it to length based on the height of my TV, the height of my soundbar and allowing room for attaching some shelves later.
  3. At the base trim each side 45°, then angle the saw blade to 45 and make a cross cut. Makes a nice beveled end instead of a dramatic right angle.
  4. Use some of the scrap at the top to increase the depth so the TV mount screws get a lot of purchase depth. I used wood glue and 8 screws.
  5. Prime and paint.
  6. Attach hardware.
  7. For attaching it all to the pillar I decided to go with a friction mount. I ordered 3 endless loop ratchet straps and ratchet them tight against the pillar.

Using a friction mount is a dicey thing. Materials have two kinds of stickiness – or friction coefficients. One is how sticky two things are when they are at rest (static friction coefficient) and the other is how sticky two things are when they are moving (kinetic friction coefficient). Friction works great right up until you overcome the static friction coefficient and then it works very poorly because the kinetic friction coefficient is always lower than the static friction coefficient.

Good news is we can calculate how much force our friction mount should support! Friction is dependent on the pressure between two surfaces (the normal force) and the stickiness between them (the friction coefficient). The frictive force is going to be our normal force times the static friction coefficient.

How much normal force do we have? I’m estimating that I can ratchet around 150lbs of pressure on one of those ratchet straps. Let’s cut that a little bit because I haven’t been working out and I am an optimist. Let’s call it 120lbs. I’m using 3 ratchet straps so that adds up to 360lbs of pressure.

There’s a table on that page with friction coefficients for common materials. Looks like they say the static friction coefficient between wood and concrete is 0.62. 360lbs * 0.62 = 223.2lbs.

I’m around 175lbs – I should be able to do a pullup on this!

me doing a pull up on a ratchet strapped wood.

And I CAN!

My TV weighs 50.8 lbs, the tv mount weighs 8lbs,  my shelves weigh 11lbs and they can support 22 lbs per shelf. I forget how much my soundbar weighs. Let’s call it 10 lbs.

50.8 + 8 + 11 + 22 + 22 + 10 = 123.8 lbs. I’ve got around 99 lbs of spare capacity before we hit the limit of  my static coefficient of friction!

I feel like I can trust this not to drop on Max for a while!  How long until Max might hang off of this and make it drop? Hmmm – when is he likely to be around 100lbs? Wolfram Alpha tells me a 10 year old American is around 94lbs. I should be able to teach him not to do it by then or get another ratchet strap.

Secret Project D – a Custom DIY Dresser

Secret Project B has been so on my mind that I totally forgot to write up my Secret Project D!

thin_hudson_dresser

Sam had been talking about wanting a dresser, but none of the ones we found really fit where we wanted to put one. We liked West Elm’s Hudson dresser. Clean modern style, but it was too deep to fit our space. Sounds like a job for me!

Screen Shot 2013-07-03 at 5.57.12 AM
I made measurements and decided that the best way for a nerd like me to proceed would be to make a sketchup design. I found a sketchup model of the thin hudson and made my dresser model based on that.
I started working on this last August on nights and weekends.

Screen Shot 2013-07-02 at 1.26.10 PM

Screen Shot 2013-07-02 at 1.27.52 PM

Afterwards, I dropped by a West Elm to see how they put theirs together. That’s when I realized that I didn’t have to make the stretchers in the carcass solid – I could make them a frame and they’d be just fine. Also – less weight in the furniture will be helpful when we move it around.

Then life gets in the way – the project was on hold for months. After figuring out what I wanted to do I bought tools, and got started in December.

I decided to go with a furniture grade plywood. Not all plywood is crappy – some looks really nice. I went with Baltic Birch. It’s good looking, the beveled edges on the drawers have a sweet pinstripe on them and I could get it nearby at the Brooklyn Dyke’s Lumber1.

bevel_drawers

Plywood has a couple of other sweet properties for small apartment woodworking. The cross-grain layering of plywood makes it very stable with regard to moisture. This means I don’t have to have a jointer or planer to flatten the wood. In addition, the sheet of plywood has a continuous grain veneer – so you cutting the drawer fronts from one sheet of plywood preserves that grain across the drawers.

drawer_fronts

When you buy lumber, you have to know how to order it, and you need to know how much you want. The sales folks are used to dealing with people who order very large amounts, so not knowing makes you an irritant. You won’t get what you need. Fortunately, if you build your model in Sketchup first, there’s a handy plugin that calculates how much lumber to buy and gives you a cutlist based on your model. It even gives you a plan on how to get the most out of the wood with the least waste. That’s so helpful!

Armed with my cutlist, I grabbed a truck from zipcar and brought back three huge 4’x4′ sheets back to my woodshop in the sky.
wodshop_in_the_sky

After many nights and weekends of cutting, swearing, panicking, gluing, screwing, sanding and shellacing I got the dresser done. My woodshop in the sky has turned into a baby room, so I’ll have to find a new place to make any future furniture. If any folks are interested in either how I made it or what I’ve learned about small apartment woodworking, I could write more about that.

1ks-see-ya-later

  1. I cannot imagine the creepy search terms those folks find in their server logs  (back)

New up on the wall

 

Just got two new things framed. When Sam was little, her mom made her a cross stitch pillow with a scene of animals calmly gathered around a lion. We’ve put it in a deep shadowbox so it can go up on the wall for Secret Project Baby‘s room.
Little pillow shadow box

We also have a memento from Japan that we’ve never figured out how to properly display.  We loved the idea of Furoshiki – little cloth wrappings that you can reuse. We bought a really nice one and, after trying some other approaches, found a way to really show it off.20130428_124122_Livingston St

I also just got some new panoramas from friends for above the dining table and I’m excited to try them out!

Save Crush3r – an open letter to Ericson de Jesus

Hi Ericson,
Crusher was my favorite invite service.  I used it once or twice a year for my parties and thought it was just dandy.  I want to avoid big services because I didn’t like the way they were monetizing me and my friends. They felt gross.

I am an open source developer.  Not a great one, but a persistent one. If you are shutting down crusher and you don’t have a way to make enough money off it to support it, why not get some credit for what you made? If you want to make it an open source offering from Particle, that would be awesome.  If, instead, you’d like some help, I’d be willing to offer some hours from my side to open source it and make it easier for other folks to self-host and contribute.

I think it would be a shame if the great work you did just went poof!  I’m willing to chip in some effort to make this usable to lots of other folks.  If you can’t open source it, I’d love any advice or patterns you can suggest if I want to take this on as a project after I finish up Wordprss – an feed reader for wordpress. I’d like to have an easy evite alternative that I can self host and trust with my friend’s info.

So I’d love to hear from you – any thoughts on how to do this?