Read the Docs
Python utility for clipping and stitching GoPro video from SEFIS video surveys
About
This is a Python utility used for merging GoPro videos collected during SEFIS video surveys. GoPro cameras are deployed and record continuously for about an hour at a time. These video files are automatically split into 4GB chunks by GoPro video processing software to prevent data loss, with each file containing approximately 15 minutes of footage. Current science protocol involves processing a 24-minute video segment from each deployment relative to the time the camera reaches the bottom:
- Video folders are named using a “collection number” convention consisting of a combination of a project code, year, collection, and camera.
- Each folder is a single deployment of a trap with a camera and contains a board file (a brief video prior to deployment showing metadata information) and a number of underwater video files.
- A metadata CSV file contains a “time on bottom” timestamp for each unique identifying collection number indicating the elapsed time from when the video files start to when the trap lands on the bottom.
- The objective is to extract a segment of video starting exactly 8 minutes after the trap lands on bottom (rounded up to the nearest 30 seconds) and ending 24 minute later, or 32 minutes after the trap lands on bottom. This involves slicing some videos and stitching relevant segments together.1
- The new stitched video is named exactly like the folder containing the files (i.e., the collection number).
This script does three things:
- Determines where in the collection of deployment videos the desired 24-minute segment is located using the CSV metadata file containing timestamps for when the camera reached the bottom and metadata extracted from the video files themselves (e.g., duration, frame rate, etc.)
- Clips the relevant portion of partial videos at the appropriate start and end times, as needed
- Stitches the required videos together into a single video file for each deployment
Some key features:
- Frame-Accurate Seeking: Uses
FFmpegfilters to ensure exact millisecond alignment across GoPro chapter seams. - NTSC Correction: Automatically2 handles 29.97 fps (30000/1001) timing to prevent timecode drift in long deployments.
- Diagnostic Overlays: Provides optional burned-in timecode with
HH:MM:SS:FFformat for frame-by-frame verification. - GoPro Logic: Intelligently sorts chapters (GX01, GX02) to maintain chronological continuity.
An optional diagnostic mode can be used to embed an authoritative video timestamp into the video frames (formatted HH:MM:SS:FF) to help find the splice times, since some video software do not preserve the original frame rate or fail to display the full time during playback. This embedded timestamp is fundamentally independent of the timestamp shown in most video players, which is merely a count from the start of the video. A video player would not know, for example, if a bad stitching operation inadvertently skips a frame or chunk of frames. Engaging diagnostic mode will also print out a table of the stitch times for each deployment to the console including where in the original video files the segments were taken. To assess the performance of the script, compare the frames in the new video at and around the stitch times (“NEW VIDEO TIME”) to the appropriate clip timestamps in the corresponding source files (“SOURCE TIMESTAMP”). If, for example, the stitch caused the same file to be read twice, the video player clock will keep advancing but the embedded timestamp in the video will reset or stutter. If the stitch is correct, the embedded timestamp will advance monotonically across the stitch.
This table is always added to a log file even when diagnostic mode is off, but printing to the screen can be a convenience for evaluation or troubleshooting.
Usage
Running the script is straightforward. After activating the appropriate Python environment, simply call the script from the command line specifying the configuration YAML file to use:
python clip_and_stitch.py configurations.yamlIf the configuration file is not co-located with the script, simply include the path to the file so that the script knows where to find it:
python clip_and_stitch.py path/to/configurations.yamlHelper files are also included for users unfamiliar or uncomfortable with command line. For more information and instructions, see Using the Utility.
Options
All user options are contained in a configuration YAML file (called configurations.yml by default, but can be named anything) to allow easier control and greater reproducibility. Settings are entered as key: value pairs as follows:
| Key | Description |
|---|---|
input_directory |
(str) Path to parent folder containing subfolders for set of videos. The subfolders should be named according to the collection number (e.g., DEPLOYMENT_001), which will be used to name the new video file, and should contain all of the video files for that deployment. |
output_directory |
(str) Path to folder where the new video file will be saved. The new video will automatically be named according to the collection number (e.g., DEPLOYMENT_001.MP4). |
csv_path |
(str) Path (including name) of the “time-on-bottom” CSV metadata file. This file should contain entries for each deployment (subfolder) in rows with collection number in one column and “time-on-bottom” in a separate column. All other columns will be ignored. Note that directory and file names are case-sensitive on some operating systems. |
col_foldername |
(str) Column name for the column containing the deployment or folder name. Defaults to foldername but can be changed here if needed. Case-sensitive. |
col_timebottom |
(str) Column name for the column containing the “time-on-bottom” timestamps. Defaults to timebottom but can be changed here if needed. Expected format of the timestamps is HH:MM:SS:FF. |
| Key | Description |
|---|---|
clear_log |
(Boolean) If true, clears the log file at the start of each run. Otherwise, appends to the existing log file. Defaults to false. |
diagnostic_mode |
(Boolean) If true, prints the video cut times and embeds an authoritative timestamp into the video itself to verify stitching. Defaults to false. |
reprocess |
(Boolean) If true, existing stitched videos of the same name will be overwritten. Otherwise, skips folders where the output file already exists. Defaults to false. |
use_gpu |
(Boolean) Whether to use GPU acceleration, if available. Requires GPU hardware and compatible ffmpeg build (see below). Defaults to false. |
| Key | Description |
|---|---|
ffmpeg_path |
(str) Path to the executable ffmpeg utility (see below). Defaults to “ffmpeg/bin/ffmpeg.exe”. |
ffprobe_path |
(str) Path to the executable ffprobe utility (see below). Defaults to “ffmpeg/bin/ffprobe.exe”. |
| Key | Description |
|---|---|
log_file |
(str) Path to and name of the log file where processing information will be recorded. Defaults to ./processing-log.txt (in the present working directory). |
min_gb_required |
(int) Minimum required free disk space in GB to start processing. Script will warn if available space is below this threshold. Defaults to 10. |
timeout_minutes |
(int) Maximum time in whole minutes to try processing a video before giving up. Can be used to prevent hang ups due to bad network connections, but be sure to allow enough time to actually process a video. Fractional minutes or MM:SS not yet supported. Defaults to None (no timeout). |
preread_time_minutes |
(int) Number of whole minutes between the time on the bottom and the start of the extracted video segment. Fractional minutes or MM:SS not yet supported. Defaults to 8. |
quality_crf |
(int or “auto”) Constant Rate Factor (CRF) for video encoding quality. Lower values mean better quality: 18 is high quality, 23 is standard. 10 with use_gpu: false or 11 with use_gpu: true produced bit rate and file size most similar to those of the original GoPro files during trial and error testing. Often machine (hardware) dependent. If quality_crf: "auto", the input video bit rate will be used to dynamically calculate a target bitrate for the output video. Defaults to “auto”. |
video_duration_minutes |
(int) Expected duration of the final video in whole minutes. Fractional minutes or MM:SS not yet supported. Defaults to 24. |
video_extension |
(str) The file extension for the video files to be processed. Defaults to “.MP4”. |
Use double quotation marks with forward slashes (/) or double backslashes (\\) for Windows paths to avoid issues with escape characters and spaces. For example, "C:/Users/user.name/Documents/configs.yaml" or "C:\\Users\\user.name\\Documents\\configs.yaml".
It is best practice to avoid spaces and special characters other than underscores and hyphens in directory and file names to avoid issues with file paths. For this project, this applies to video files, the CSV metadata file, configuration files, and relevant directory names.
Dependencies
This project requires the following software and libraries:
Python >= 3.14
Be sure to check the box to add Python to your system PATH during installation, or add it manually yourself after installation. This will allow you to run Python from the command line and ensure that the utility can find the Python executable when running. On Windows, you may also need to turn off app execution aliases related to Python (e.g.,
python.exe',python3.exe`.)ffmpegandffprobe>= 6.1The
ffmpegandffprobeutilities are automatically downloaded when the setup script is run; otherwise, they are available here. Both utilities are included in theffmpegdownload.
Python Libraries
- pandas >= 3.0.2
- pyyaml >= 6.0.3
- tqdm >= 4.67.3
Recommendations
- Git CLI for repository cloning and version control via command line
or
GitHub Desktop for repository cloning and version control via GUI - Anaconda for virtual environment implementation
Release Notes
Version History
- Version 2026.0.1 (BETA) (Apr 2026): Initial version for testing
License
Software code created by U.S. Government employees is not subject to copyright in the United States (17 U.S.C. §105). The United States/Department of Commerce reserve all rights to seek and obtain copyright protection in countries other than the United States for Software authored in its entirety by the Department of Commerce. To this end, the Department of Commerce hereby grants to Recipient a royalty-free, nonexclusive license to use, copy, and create derivative works of the Software outside of the United States.
Disclaimer
This software is a scientific product and is not official communication of the National Oceanic and Atmospheric Administration, or the United States Department of Commerce. All NOAA software and project code is provided on an “as is” basis and the user assumes responsibility for its use. Any claims against the Department of Commerce or Department of Commerce bureaus stemming from the use of this software will be governed by all applicable Federal law. Any reference to specific commercial products, processes, or services by service mark, trademark, manufacturer, or otherwise, does not constitute or imply their endorsement, recommendation or favoring by the Department of Commerce. The Department of Commerce seal and logo, or the seal and logo of a DOC bureau, shall not be used in any manner to imply endorsement of any commercial product or activity by DOC or the United States Government.
Footnotes
Both of these time windows are user-configurable, if desired. The default values are based on the current science protocol but can be adjusted as needed. See Options for more information.↩︎
The frame rate is extracted from the video metadata, rather than being hard-coded into the script, in an effort to make the utility camera-agnostic.↩︎