Markus Hedlund

Developer / Photographer

Contact / GitHub / Instagram

Work With Me

Timelapse from GoPro images with FFmpeg

Create a timelapse from GoPro images with FFmpeg and save it with MJPEG video encoding.

cd some/directory/with/gopro/images
ffmpeg -r 6 -f image2 -pattern_type glob -i '*.JPG' -s 4000x3000 -c:v mjpeg -q:v 10 ./

See FFmpeg documentation for reference.

Now drag this video into a video editing software to make post editing.

Deploy Node.js on Ubuntu 16 with Git post-receive hook

Use git push to deploy your code, and nvm to use seperate node versions per project.


Step 1. Setup in the user account

SSH in as myproject


Create the bare git repo that you will push to for deployment.

mkdir ~/myproject.git
cd ~/myproject.git
git init --bare
nano hooks/post-receive

Paste the script below.


set -e

export NVM_DIR="$HOME/.nvm"
. "$NVM_DIR/"

NEW_DIR="$HOME/app/`date +%Y-%m-%d-%H.%M.%S`"

mkdir -p $REPO_DIR

git --work-tree="$REPO_DIR" --git-dir="$GIT_DIR" checkout -f
git --work-tree="$REPO_DIR" checkout-index -a --prefix="$NEW_DIR/"

cd "$NEW_DIR" && nvm i && npm i --production

rm -f "$CURRENT_DIR"

sudo restart myproject

What's happening:

  1. Initiate environment.
  2. Config variables.
  3. Make a copy of the project to a new directory.
  4. Build the project.
  5. Relink to the latest version and restart the service.

Now set execute rights on the script.

chmod u+x hooks/post-receive

Step 2. Setup as root

Switch to root.

sudo su -

Create the service description file by editing /etc/init/myproject.conf.

start on runlevel [2345]

env LANG=en_US.UTF-8
env PORT=7777

setuid myproject
setgid myproject

chdir /home/myproject/app/current

  NODE_VERSION=`cat /home/myproject/app/current/.nvmrc`
  exec /home/myproject/.nvm/versions/node/v$NODE_VERSION/bin/node .
end script
  1. What runlevel this service will start on.
  2. Environment variables.
  3. What user and group id we will run as.
  4. Make sure the service respawns automatically if it crashes.
  5. cd into the latest deployment and start with the correct version of Node.

Add visudo entry with command visudo and add this to the bottom.

myproject ALL=NOPASSWD: /sbin/restart myproject, /sbin/start myproject, /sbin/stop myproject

Step 3. Test deployment

On you local machine, add the remote and push to it. prod in the example below is the name of the deployment environment, prod is short for produciton.

git remote add prod
git push prod master

Note: The first time it will fail to restart the service because it isn't running. I recommend that you uncomment that line the first time.

Possible improvements

LoadError on line [“45”] of C: cannot load such file – zurb-foundation

You are missing ZURB-Foundation. Install it with

gem install zurb-foundation

Google Apps Calendar: sync all calendars with iPhone

If you've set up your iPhone/iPad to sync calendars with Google Apps over Exchange, but are not getting all calendars, there's one thing more you need to do.

Go to on your iPhone/iPad and log in with your Apps credentials. Make sure you set the language to English.

Click on your device in the list, select the calendars you want to sync and then hit Save.

Now restart your iPhone/iPad, and it should start syncing all calendars.

Fix iMessage/SMS on iPhone with iOS6

This is quickly solved in 3 steps:

Open up Settings and then Messages. Switch iMessage off and then on again. While you are here, check what phone number and addresses you have setup with iMessage, under Send & Receive.