Table of contents

Introduction

Are you looking for a fun and innovative way to capture the passage of time? With FFmpeg, you can easily create stunning live webcam time-lapses with minimal effort. This guide will walk you through all the steps necessary to create a beautiful timelapse video using almost any video stream, whether it's from an IP webcam, online cam website, or even YouTube!

This works by using FFmpeg to extract a still frame from the video stream feed every minute and then compiling all of these frames into a timelapse video.

Sample Timelapses that I created from online webcams and YouTube Live

0:00
/
Bengtsfors - Lelång timelapse from a public webcam created with FFmpeg
0:00
/
Hawaii - Maui timelapse from a public YouTube live stream.

Prerequisites

Installing FFmpeg

The first step is to install FFmpeg on your computer. This is quite simple as FFmpeg can be downloaded from their official website or through some package managers such as Homebrew (for macOS) or apt-get (for Linux). Download and install it on your machine by following the instructions below.

MacOS:

  • Open your Terminal and paste the following command:
bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)
  • Wait for the script to finish then type brew install ffmpeg in Terminal and hit Enter.

Linux:

  • Open your terminal and type sudo apt-get update followed by Enter.
  • Then, type sudo apt-get install ffmpeg and hit Enter again to complete the installation.

Windows:

  • You can follow this guide to easily install FFmpeg on Windows.

Creating timelapse from IP camera

Once you have FFmpeg installed, it's time to capture the timelapse video. To do this, you need to first find the IP address of the webcam you wish to use.

Finding your camera's streaming protocol

Most IP cameras use the RTSP (Real Time Streaming Protocol) protocol. It's an open standard for transferring audio and video data over a network in real time. It can be used to transmit webcam feeds from one device to another. Although, your IP camera might use a different protocol, see FFmpeg's official documentation for a list of supported protocols.

ℹ️
The easiest way to find your camera's RTSP URL is just Googling for "<camera model> rtsp stream" and you should find plenty of results that will help you.

For example, 8mp/12mp Reolink cameras have the URL that looks like this: `rtsp://admin:111111@192.168.1.101:554/h265Preview_01_main`

Taking the screenshots

Open up your terminal and type in:

ffmpeg -i rtsp://<your-rtsp-stream-url-here> -q:v 0 -frames:v 1 screenshot.jpg

Once the command is done, you should see a screenshot appear in your current working directory. That means it's working! Let's create the bash script to take multiple stills.

Mac finder with one screenshot file

Bash script to capture screenshots from a video stream

Open up your favorite text editor and create a new file called capture_stills.sh and paste the following code into it:

#!/bin/bash

# Check if the video stream URL is set
if [ -z "$STREAM_URL" ]; then
  echo "Error: STREAM_URL is not set."
  exit 1
fi

# File name prefix
file_name_prefix="still_"

# File extension
file_extension=".jpg"

# Number of hours to run for
default_hours_to_run=8
hours_to_run=${HOURS_TO_RUN:-$default_hours_to_run}

# Total number of seconds to run for
seconds_to_run=$((hours_to_run * 60 * 60))

# Set the wait time between frames
default_wait_time=60
wait_time=${WAIT_TIME:-$default_wait_time}

# Set the counter
counter=1

# Get the system's kernel name to determine if we're on MacOS
kernel_name=$(uname)

# Total number of frames
total_frames=$(($seconds_to_run/$wait_time))

# Calculate the finish time
current_time=$(date +%s)
future_time=$((current_time + $seconds_to_run))
if [ "$kernel_name" == "Darwin" ]; then
    formatted_time=$(date -j -f "%s" $future_time +"%Y-%m-%d %H:%M:%S")
else
    formatted_time=$(date -d @$future_time +"%Y-%m-%d %H:%M:%S")
fi

echo "https://tunnel.page FFmpeg timelapse script"
echo "Hours to run: $hours_to_run"
echo "Stream URL: $STREAM_URL"
echo "Finish at: $formatted_time"
echo -ne "Time between frames: $wait_time\n\n"

# Loop for the specified number of minutes
while [ $counter -lt $seconds_to_run ]; do
  echo -ne "Taking screenshot $counter/$total_frames"

  # Set the current date and time
  current_date_time=$(date +"%Y-%m-%d_%H_%M_%S")

  # Set the file name
  screenshot_file="${file_name_prefix}${current_date_time}${file_extension}"

  ffmpeg -hide_banner -loglevel error -i $STREAM_URL -vframes 1 -q:v 0 $screenshot_file
  echo " .. done"

  counter=$((counter+1))
  sleep $wait_time
done

Make it executable, in your console type in: chmod +x ./capture_stills.sh

Then to start capturing frames, type in the command below, you should change the parameters according to your preferences, don't forget to also change the STREAM_URL. In the example below, the script will run for 6 hours and wait 1 minute between each frame.

export HOURS_TO_RUN=6
export WAIT_TIME=60 
export STREAM_URL=http://<yourstream.com>/mjpg/video.mjpg
./capture_stills.sh
FFmpeg timelapse script
Here's what the output from your console should look like, your params will be different.

And now you should see frames start appearing automatically in your folder! As you can see, the script also calculates the date and time of when it's going to finish capturing all requested frames.

osx finder with timelapse video stills

Generating an MP4 timelapse video with FFmpeg

Generating an mp4 timelapse video from the frames is also quite easy with FFmpeg. All you need to do is run this command:

ffmpeg -framerate 30 -pattern_type glob -i '*.jpg' -vcodec libx264 -crf 15 timelapse.mp4

You can replace timelapse.mp4 with the name of your video file. This command will generate a timelapse at 30 frames per second which is usually the default frame rate for webcam streams. If you want to adjust the speed, you can do so by changing 30 in the command above to whatever time interval you desire (e.g., 60 for 60 frames per second).

You can also adjust the other parameters in the command to suit your needs. For example, if you want to reduce the size of the video file, you can use -crf 25 parameter which sets the quality of the output video (0-51). The lower the number, the highher the output quality and larger file size. Read more about H.264 parameters. That's it, once the command has finished running you should have a timelapse video in your current working directory!

Generating Timelapse videos from YouTube Live

Prerequisites

To create a timelapse video from a YouTube live stream, you will need youtube-dl. This is an open-source command line program designed specifically for downloading videos from YouTube and other websites. FFmpeg will also be needed, see "Installing FFmpeg" for installation details.

MacOS

Open Terminal and paste the following command: brew install youtube-dl, then hit Enter.

Linux

Open your terminal and type sudo apt-get update followed by Enter. Then, type sudo apt-get install youtube-dl and press Enter.

Windows

Go to https://youtube-dl.org/downloads/latest and download the Windows executable. After that, install it as you would with any other software on Windows.

YouTube Live timelapse bash script

The script allows you to provide the following environment variables:

  • YouTube live URL (YT_URL)*
  • Number of hours you want to record the frames for HOURS_TO_RUN (default 1 hour)
  • Seconds between each frame WAIT_TIME (default 60 seconds)

*required params

The way it works is, it uses youtube-dl to download the .m3u8 playlist from YouTube, save it as stream.m3u8 and then feed that stream file into FFmpeg.

#!/bin/bash

# Check if the youtube live URL is set
if [ -z "$YT_URL" ]; then
  echo "Error: YT_URL is not set."
  exit 1
fi

# File name prefix
file_name_prefix="still_"

# File extension
file_extension=".jpg"

# Number of hours to run for
default_hours_to_run=1
hours_to_run=${HOURS_TO_RUN:-$default_hours_to_run}

# Total number of seconds to run for
seconds_to_run=$((hours_to_run * 60 * 60))

# Set the wait time between frames
default_wait_time=60
wait_time=${WAIT_TIME:-$default_wait_time}

# Set the counter
counter=1

# Get the system's kernel name to determine if we're on MacOS
kernel_name=$(uname)

# Total number of frames
total_frames=$(($seconds_to_run/$wait_time))

# Calculate the finish time
current_time=$(date +%s)
future_time=$((current_time + $seconds_to_run))
if [ "$kernel_name" == "Darwin" ]; then
    formatted_time=$(date -j -f "%s" $future_time +"%Y-%m-%d %H:%M:%S")
else
    formatted_time=$(date -d @$future_time +"%Y-%m-%d %H:%M:%S")
fi

echo "https://tunnel.page FFmpeg Youtube live timelapse script"
echo "Hours to run: $hours_to_run"
echo "Youtube URL: $YT_URL"
echo "Finish at: $formatted_time"
echo -ne "Time between frames: $wait_time\n\n"

fetch_playlist() {
  echo -ne "Fetching YouTube Live playlist"
  youtube-dl -f best -g "$YT_URL" > stream.m3u8
  echo " .. done (stream.m3u8)"
}

take_screenshot() {
  ffmpeg -hide_banner -loglevel error -i $(cat stream.m3u8) -vframes 1 -q:v 5 $1
}

fetch_playlist

# Loop for the specified number of minutes
while [ $counter -lt $seconds_to_run ]; do
  echo -ne "Taking screenshot $counter/$total_frames"

  # Set the current date and time
  current_date_time=$(date +"%Y-%m-%d_%H_%M_%S")

  # Set the file name
  screenshot_file="${file_name_prefix}${current_date_time}${file_extension}"
  take_screenshot $screenshot_file
  if [ "$?" -eq 0 ]; then
    echo " .. done"
   else
    echo " .. error"
    fetch_playlist
    take_screenshot $screenshot_file
   fi

  counter=$((counter+1))
  sleep $wait_time
done

To run the script, first make it executable: chmod +x ./capture_youtube_live_stills.sh

Then you can run the script like this, make sure to adjust the settings according to your needs.

export YT_URL="https://www.youtube.com/watch?v=fQrKBlRilaw" 
export WAIT_TIME=30 
export HOURS_TO_RUN=6
./capture_youtube_live_stills.sh

Here's what the script looks like in action:

youtube live timelapse bash script console output
Console output of YouTube live timelapse script

And now that your script is running, you should see frames appearing in your directory!

mac finder with timelapse frame stills

Once you're finished capturing your stills, run the following command to generate the timelapse video. See more details about creating timelapses with FFmpeg.

ffmpeg -framerate 30 -pattern_type glob -i '*.jpg' -vcodec libx264 -crf 15 timelapse.mp4

Tips for creating timelapses and additional resources

The length of the timelapse will depend on the desired effect. For slow, sweeping scenes such as stars or slow moving clouds, use a longer interval such as 30-45 seconds. For faster-paced action like traffic or people moving around, you can use shorter intervals between 2 to 10 seconds. If you want something in the middle, then 15-30 seconds is a good compromise. You can also experiment with different intervals to see what works best for your particular timelapse scenario.

Finally, don't forget to consider the total length of time that will be captured in the timelapse. If it is too short, you may miss important details; if it is too long, the video will become overly long and may lose its impact. Experiment with different intervals and durations to see what works for your timelapse. If you're using FFmpeg, remember that you can always adjust the interval and duration of the timelapse afterward.

Timelapse calculator

A timelapse calculator can be an invaluable tool when creating time-lapses. It can help you to figure out the necessary length of a timelapse, number of frames per second, and overall playback speed. This is especially useful if you need to create a video with a specific duration or want to calculate how long it will take for your timelapse to be complete. By inputting the desired video duration, the timelapse calculator will be able to provide you with all the necessary information so that you can adjust your frame rate accordingly and make sure your timelapse looks stunning! Additionally, a timelapse calculator can also suggest the optimal settings for taking webcam frames based on the camera.

Timelapse Calculator | PhotoPills
Quickly compute parameters you need to collect sequences of still images to create timelapse videos.
Timelapse calculator 1
Time Lapse Calculator
Time lapse calculator helps you determine the perfect parameters for your time-lapse.
Timelapse calculator 2

365 day timelapse

If you want to capture the whole year in timelapse, cronjob is your best friend. It's a powerful tool that allows you to schedule tasks at specific times so that they run automatically. With it, you can easily create a script that captures a couple of frames every day, so by the end of the year, you will have the perfect timelapse showing all seasons of the year!

Summary

Creating timelapses from webcam streams and YouTube Live with FFmpeg is a great way to capture stunning visuals that showcase the passing of time. With a few simple commands, you can download and install FFmpeg on your system, find out the streaming protocol of your webcam, use my bash script to take multiple stills, and generate timelapse videos from YouTube Live.