Timelapse of Writing a Thesis in 180 Days🎓

While procrastinating on my thesis research, I came across a timelapse of a research paper in the making by Tim Weninger. I wanted to create a video similar to his but for my own thesis.🥳

Timelapse

Making-of

The basic idea is to create montages from different versions of the pdf and stitch them together as a video. All you need is a version-controlled LaTeX document, a little github magic, and the power of ImageMagick and FFmpeg.

First, I set up a github action in my thesis repo, that compiled my document and committed the resulting PDF to a second repo. The action runs on every push to the reports/ directory. Every pushed commit becomes a new frame in the final video.

name: Build LaTeX document
on:
  push:
    paths:
      - reports/**
  workflow_dispatch: null
jobs:
  build_latex:
    runs-on: ubuntu-latest
    steps:
      - name: Set up Git repository
        uses: actions/checkout@v4
      - name: Compile LaTeX document
        uses: xu-cheng/latex-action@master
        with:
          latexmk_shell_escape: true
          root_file: |
            thesis.tex
          working_directory: reports
          latexmk_use_lualatex: true
      - name: Release
        uses: softprops/action-gh-release@v1
        if: startsWith(github.ref, 'refs/tags/')
        with:
          files: |
            reports/thesis.pdf
      - name: save tmp copy
        run: |
          mkdir ~/tmplatex
          mv reports/thesis.pdf ~/tmplatex/thesis.pdf
      - name: setup target repo
        uses: actions/checkout@v4
        with:
          repository: KarelZe/thesis2video
          ref: main
          token: ${{secrets.API_TOKEN_GITHUB}}
      - name: setup git config
        run: |
          git config user.name "GitHub Actions Bot"
          git config user.email "action@markusbilz.com"
      - name: Move file and push
        run: |
          mv ~/tmplatex/thesis.pdf ${{github.event.repository.pushed_at}}-thesis.pdf
          git add -A
          git commit -m "Version @ ${{github.event.repository.pushed_at}}"
          git push origin main

Once I had finished my thesis, I had a second repository (KarelZe/thesis2video) containing all the timestamped PDF versions. Since some commits, like removing unused packages, didn’t change the layout, I decided to deduplicate the PDF files before proceeding.

find . -type f -exec md5sum {} + | sort | uniq -w32 -d --all-repeated=separate | sed -r 's/^[^ ]* //' | xargs rm

To generate the montages from the pdfs, I used the paper2movie script by Raymond Vermaas. I tweaked the script to adapt to my preferences. In particular, I adjusted the scaling logic to dynamically scale the size of the tiles in the montage with the number of pages in the document and removed the code for compiling the LaTeX documents and reading the git history, as I had compiled the pdf files already.

Initially, I experimented with converting the pdf to frames using a GitHub action but ran into memory issues quickly. Therefore, I decided to perform the conversion locally.

#!/bin/bash

# adapted from: https://github.com/momentofgeekiness/paper2movie

############################
### INPUTS ###
############################
# Name of the (input) paper file (without extension)
filename=thesis.avi

# Video size (by default 4k)
totalWidth=3840
totalHeight=2160
# Video frames per second
# Use low values (< 5) on papers with many pages (> 50).
# It will give a better results, since there is much more to look at. ;-)
fps=4
############################
### CLEANUP STUFF ###
############################
echo -e "\nCleaning up...\n"
rm *.png > /dev/null
rm *.avi > /dev/null

############################
### CREATING IMAGES ###
############################
for f in `ls -1 *-thesis.pdf`; do
pages=`pdfinfo $f | awk '/^Pages/ { print $2}'`
# maximum number of pages
# The width/height ratio of A4 paper (1/sqrt(2))
ratioA4="0.7070"
# The height of an individual tile
tileHeight=`echo "scale=10;sqrt(($totalWidth*$totalHeight)/($ratioA4*$pages))" | bc`
tileWidth=`echo "scale=10;$tileHeight*$ratioA4" | bc`
# Calculate grid
numTilesHeight=`echo "scale=10;$totalHeight/$tileHeight" | bc`
numTilesWidth=`echo "scale=10;$totalWidth/$tileWidth" | bc`
# Ceil tiles to integers,
numTilesHeight=`awk -v var="$numTilesHeight" 'BEGIN{var = var < 0 ? int(var) : (int(var) + (var == int(var) ? 0 : 1)); print var}'`
numTilesWidth=`awk -v var="$numTilesWidth" 'BEGIN{var = var < 0 ? int(var) : (int(var) + (var == int(var) ? 0 : 1)); print var}'`
# Report measurements
echo -e "Processing File: $f"
echo -e "\nMovie measurements:"
echo -e "Number of horizontal tiles: $numTilesWidth"
echo -e "Number of vertical tiles: $numTilesHeight"
# Having ceiled the number of tiles, they exceed the totalWidth and totalHeight.
# So, we also need to recalculate the tileHeight and tileWidth. This step will
# (slightly) change the A4 ratio, but it beats half pages in the video.
tileHeight=`echo "scale=5;$totalHeight/$numTilesHeight" | bc`
tileHeight=`echo $tileHeight |cut -f1 -d"."`
tileWidth=`echo "scale=5;$totalWidth/$numTilesWidth" | bc`
tileWidth=`echo $tileWidth |cut -f1 -d"."`

montage $f -tile ${numTilesWidth}x${numTilesHeight} -background white -geometry ${tileWidth}x${tileHeight} $f.png
done
############################
### RENDER MOVIE ###
############################
echo -e "\nRendering movie...\n"
cat $(find . -maxdepth 1 -name "*.png" | sort -V) | ffmpeg -r $fps -i - $filename

echo -e "Movie available at $filename"

Depending on your image magick version installed, you might have to adjust policies for pdf conversion. That’s all it needs.

comments