Automatically process Zoom recordings to switch between speaker-only and side-by-side views based on screen sharing chapters
Project description
ZoomCutter
Automatically process Zoom recordings to switch between speaker-only and side-by-side views based on screen sharing chapters.
What it does
ZoomCutter intelligently combines your Zoom camera and screen sharing recordings into a single video that:
- Shows speaker-only view when you're not sharing your screen
- Switches to side-by-side view (slides + camera) when screen sharing is detected
- Maintains camera's native resolution for optimal performance
- Uses Zoom's built-in chapter markers to detect sharing automatically
Perfect for creating professional-looking recordings of presentations, lectures, or meetings!
Features
- Automatic switching: Reads Zoom chapter markers to detect when screen sharing starts/stops
- Smart resolution handling: Uses camera's native resolution (no unnecessary upscaling)
- Trim support: Cut your video to specific start/end times
- Fast processing: Optimized ffmpeg settings for quick encoding
- Dry-run mode: Preview the ffmpeg command before processing
Installation
pip install zoomcutter
Requirements
ZoomCutter requires ffmpeg to be installed on your system:
macOS:
brew install ffmpeg
Ubuntu/Debian:
sudo apt install ffmpeg
Windows: Download from ffmpeg.org or use Chocolatey:
choco install ffmpeg
Usage
Basic Usage
zoomcutter camera_file.mp4 slides_file.mp4 output.mp4
Where:
camera_file.mp4- Your Zoom camera recording (usually named*_avo_*.mp4)slides_file.mp4- Your Zoom screen sharing recording (usually named*_as_*.mp4)output.mp4- The output filename
Trim Video
Cut your video to a specific time range:
# Start at 2 minutes, end at 45 minutes
zoomcutter camera.mp4 slides.mp4 output.mp4 --start 00:02:00 --end 00:45:00
# Using short options
zoomcutter camera.mp4 slides.mp4 output.mp4 -ss 00:02:00 -to 00:45:00
Dry Run
Preview the ffmpeg command without processing:
zoomcutter camera.mp4 slides.mp4 output.mp4 --dry-run
How It Works
- Reads chapter markers: ZoomCutter analyzes the screen sharing video file to find "Sharing Started" and "Sharing Stopped" chapter markers that Zoom automatically adds
- Detects camera resolution: Uses the camera feed's native resolution for optimal quality
- Builds filter: Creates an ffmpeg filter that:
- Shows camera at full resolution when not sharing
- Switches to side-by-side (slides on left, camera on right) during sharing
- Processes video: Runs ffmpeg with optimized settings for fast, high-quality output
Output Quality
- Video codec: H.264 with CRF 18 (high quality)
- Preset: veryfast (good balance of speed and compression)
- Audio: Copied directly from camera feed (no re-encoding)
- Resolution: Matches camera's native resolution
Example
# Process a 1-hour Zoom recording
$ zoomcutter zoom_0.mp4 zoom_share.mp4 final.mp4
Processing Zoom recordings...
Camera: zoom_0.mp4
Slides: zoom_share.mp4
Output: final.mp4
Camera resolution: 1920x1080
Found 12 chapters
Found 3 screen sharing intervals:
1. 120.50s - 850.30s
2. 1200.00s - 2400.50s
3. 2800.00s - end
Output resolution: 1920x1080 (camera native)
- Speaker-only mode: No scaling (maximum performance!)
- Side-by-side mode: Only scales slides down
Running ffmpeg...
Successfully created: final.mp4
Troubleshooting
Error: "Could not detect camera resolution"
- Make sure the camera file is a valid video file
- Try running
ffprobe camera_file.mp4to verify
Error: "Error running ffprobe"
- Ensure ffmpeg (which includes ffprobe) is installed and in your PATH
No chapters found
- Verify you're using the screen sharing file (
*_as_*.mp4) for chapter detection - Some older Zoom versions may not include chapters
Development
Setup
git clone https://github.com/weltonrodrigo/zoomcutter.git
cd zoomcutter
uv pip install -e .
Run locally
python main.py camera.mp4 slides.mp4 output.mp4
License
MIT License - see LICENSE file for details
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file zoomcutter-0.1.0.tar.gz.
File metadata
- Download URL: zoomcutter-0.1.0.tar.gz
- Upload date:
- Size: 7.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
880f23da83d59a0b5d56888ff032d0857e0dc5688c4e5b9ff6602fa1d8d70235
|
|
| MD5 |
3309583daedf6b05fac90b062288cdf5
|
|
| BLAKE2b-256 |
e1cc3a8490d5fe19520c1b59fc0ab89e171c793894159c9f9d04fb5736be2854
|
Provenance
The following attestation bundles were made for zoomcutter-0.1.0.tar.gz:
Publisher:
publish.yml on weltonrodrigo/zoomcutter
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
zoomcutter-0.1.0.tar.gz -
Subject digest:
880f23da83d59a0b5d56888ff032d0857e0dc5688c4e5b9ff6602fa1d8d70235 - Sigstore transparency entry: 622695147
- Sigstore integration time:
-
Permalink:
weltonrodrigo/zoomcutter@c5b612bd8a7935ba5341e80d517ff4b4b0cdc9a3 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/weltonrodrigo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c5b612bd8a7935ba5341e80d517ff4b4b0cdc9a3 -
Trigger Event:
release
-
Statement type:
File details
Details for the file zoomcutter-0.1.0-py3-none-any.whl.
File metadata
- Download URL: zoomcutter-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
657b0dec8c56d42eaa24759df116bb24580b25c28180bf53a77c9be9ddf01ea5
|
|
| MD5 |
9d60984464437cf01e461a954cb72f37
|
|
| BLAKE2b-256 |
db3537679983d3275379df46417fbe2ee09bd063aaaa456303caa9583d0027ac
|
Provenance
The following attestation bundles were made for zoomcutter-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on weltonrodrigo/zoomcutter
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
zoomcutter-0.1.0-py3-none-any.whl -
Subject digest:
657b0dec8c56d42eaa24759df116bb24580b25c28180bf53a77c9be9ddf01ea5 - Sigstore transparency entry: 622695151
- Sigstore integration time:
-
Permalink:
weltonrodrigo/zoomcutter@c5b612bd8a7935ba5341e80d517ff4b4b0cdc9a3 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/weltonrodrigo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c5b612bd8a7935ba5341e80d517ff4b4b0cdc9a3 -
Trigger Event:
release
-
Statement type: