A Python utility that synchronizes a video clip to MIDI note timings. Personal project.
- Background
- Project Overview
- Technologies Used
- Results
- Takeaways
- Improvements & Extensions
- Download & Setup
- Troubleshooting
- Contributing
- License
My early interest in YouTube Poop (YTP) edits, which are remix-style videos created from existing television and online media, led me to discover YouTube Poop Music Videos (YTPMVs). YTPMVs are a related subgenre in which sampled video clips are sequenced and synchronized to create a song, often a cover of an existing piece. I now enjoy making these myself from time to time, but one thing that had been holding me back was the video editing process. I found manually syncing video clips to notes to be extremely time-consuming and error-prone.
For me, the typical workflow involved:
- Creating a MIDI composition in a digital audio workstation (e.g. Logic Pro) and exporting the audio
- Placing video clips corresponding to each note on a timeline in video editing software (e.g. Final Cut Pro)
- Adjusting clip length for each note
- Adding visual effects and keying
I wanted to automate what I found to be the most tedious parts: the initial sync of video clips to note timings and the clip duration adjustments.
In this project, I created a tool that takes a MIDI file and a video clip, then produces a video with the clip synchronized to each note in the MIDI file. Silences between notes are filled with chroma key green for easy removal, and for even-numbered notes, the clip is horizontally flipped for more visual interest. Short clips are also cut or "bounced" back and forth to fit exactly to the note length.
The Python script can be executed on any system, but I also created an app for macOS that provides a user-friendly dialog interface for selecting files.
- Python 3.x (Core script logic)
- mido (MIDI file parsing)
- moviepy (Video processing and manipulation)
- numpy (Array operations for video transformations)
- AppleScript (macOS GUI wrapper)
This tool has dramatically improved my workflow. The automated process is more accurate (frame-perfect timing), faster (seconds vs. hours), and consistent (no human timing errors). The created videos are ready for immediate import into video editing software, where I can focus on cropping, effects, and other creative decisions instead of basic timing.
This project:
- Introduced me to video processing and frame manipulation with Python
- Taught me how to parse and work with MIDI data
- Showed me how to create seamless Python-AppleScript integrations
- Reinforced the value of automating repetitive tasks
- Add audio export option to include the MIDI playback to ensure proper clip placement.
- Add support for images as well as videos.
- Create a GUI app for Windows/Linux.
- Options presented all at once instead of in sequential dialog boxes.
- macOS (for the GUI app) or any OS (for command-line usage)
- Python 3.7+
mido,moviepy,numpy
- Download the
.ziparchive:MIDISync.zip. - Extract the archive and move the app to your Applications folder (optional but recommended).
- Run the app.
Note
The app will use your system's Python installation. If you encounter errors, verify Python is installed by running which python3 in Terminal.
- Clone this repository or download the Python file directly:
midisync.py. - Install the required packages:
pip install mido moviepy numpy- Run the script:
python3 midisync.py <midi_file> <video_clip> <output_video>Parameters:
- midi_file: Path to your MIDI file (.mid)
- video_clip: Path to your source video clip (.mp4, .mov, etc.)
- output_video: Path for the completed output video (.mp4, .mov, etc.)
Run the app and follow the dialogs to:
- Select your MIDI file
- Select your video clip
- Choose where to save the output
python3 /path/to/midisync.py /path/to/input.mid /path/to/video.mp4 /path/to/output.mp4If you want to synchronize an image to your MIDI file rather than a video clip, you can convert the image to a still-frame video first. This can be done manually, but I find it easier to use an online converter like video.online-convert.com. I would recommend setting the duration to 1 second for best results.
If certain notes do not appear in the output video, the issue is likely corrupted data in the MIDI file. Some notes may have zero-duration timestamps even though they display and play normally in your DAW.
Solution: Open the MIDI file in your DAW (e.g., Logic Pro), locate the problematic notes, delete them, and re-enter them manually. Adding slight spacing between notes can also help prevent timing conflicts.
- Fork the repo and submit a pull request with any improvements.
- Suggestions or bug reports welcome via email or GitHub issues.
This project is licensed under the MIT License. You are free to use, modify, and distribute this code, provided you include proper credit and retain the license notice.
© 2025 Ethan Griffith