Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Authored by Souvik Mandal, Ph.D.

Project Leader & Instructor, Computational Behavioral Sciences, LS100, FAS, Harvard University | Linkedin ID: souvik-mandal-phd


Last updated: 2026-07-04

Open in Colab Open in GitHub Codespaces

This notebook processes videos in a directory where files come in pairs with names like:

  • running_1.mp4 and running_2.mp4

  • swimming_1.MOV and swimming_2.MOV

For each pair, it automatically:

  • Finds all valid _1 / _2 pairs in the directory.

  • From the _1 video, creates:

    • *_clip1 → first 60 seconds

    • *_clip2 → a 60-second clip from the middle

    • *_clip3 → last 60 seconds

  • From the _2 video, creates:

    • *_clip4 → a 60-second clip from the middle

    • *_clip5 → last 60 seconds

All new clips are saved to the same directory as the original videos, keeping the same file extension.

If a video is shorter than 60 seconds, the clip will simply be as long as the video allows.

We will use:

  • pathlib: to handle file paths in a clean, OS-independent way.

  • re (regular expressions): to detect file name patterns like prefix_1.ext and prefix_2.ext.

  • moviepy.editor: to load videos and write subclips to new files.

Helper functions: pair detection and segment computation

The functions below:

  1. find_video_pairs(directory)

    • Scans a directory for video files whose names match <prefix>_<index>.<ext>.

    • Groups them by (prefix, ext) and returns a list of pairs where both _1 and _2 exist.

  2. Segment computation functions

    • compute_first_segment(duration) → first 60 seconds.

    • compute_middle_segment(duration) → 60 seconds around the middle.

    • compute_last_segment(duration) → last 60 seconds.

Helper functions: resizing and writing clips

The functions below handle resizing and saving clips:

  1. make_square_clip(clip, target_size)

    • Resizes the clip so that the smaller dimension becomes at least target_size.

    • Center-crops to a square of size target_size × target_size.

  2. write_segment_clip(clip, input_path, start, end, suffix)

    • Extracts a subclip between start and end.

    • Resizes and crops it to 1080 × 1080.

    • Writes it to disk with the appropriate suffix.

  3. process_video_for_index(input_path, index)

    • For _1 videos: creates _clip1, _clip2, _clip3.

    • For _2 videos: creates _clip4, _clip5.

Set the input directory

Update the input_dir path below to point to the folder that contains your videos.

All output clips will be saved in the same directory as their corresponding input videos.

Set Your Input Directory Here

Replace the path below with your video folder path.

Using directory: /Users/souvikmandal/Documents/06_Teaching_Mentoring/LS100_comp_etho/2025/Students_data/Zach_Buller/videos

Run the pipeline

This cell will:

  1. Find all valid (prefix_1, prefix_2) video pairs.

  2. For each pair:

    • Process the _1 video and create clips 1–3.

    • Process the _2 video and create clips 4–5.

  3. Show an overall progress bar across all pairs.

When it finishes, your output clips (*_clip1–*_clip5) will be available in the same directory as the originals.

Found 1 pair(s):

  - Danny_1.MP4  &  Danny_2.MP4

Starting processing...

Loading...

======================================================================
Pair: Danny_1.MP4  |  Danny_2.MP4
Processing Danny_1.MP4 (duration = 896.90 s, index = 1)
  -> Writing Danny_1_clip1.MP4 [0.00s - 60.00s] at 1080x1080
  -> Writing Danny_1_clip2.MP4 [418.45s - 478.45s] at 1080x1080
  -> Writing Danny_1_clip3.MP4 [836.90s - 896.90s] at 1080x1080
Processing Danny_2.MP4 (duration = 846.36 s, index = 2)
  -> Writing Danny_2_clip4.MP4 [393.18s - 453.18s] at 1080x1080
  -> Writing Danny_2_clip5.MP4 [786.36s - 846.36s] at 1080x1080

All pairs processed.