# Complete VapourSynth Setup for macOS (ARM64) This guide is going to show you how to install VapourSynth with a complete workflow including VSEdit (VapourSynth Editor), my own VapourSynth Trimmer, and a reimagined visual resizer tool. I AM NOT A PROGRAMMER so like ... do not expect much from me. I did this with minimal coding info, lots of internet access, moderate embarassment in VapourSynth official servers and nothing but grit and determination because I wanted to get back into giffing but I couldn't handle my gifs looking way uglier now without VapourSynth than they did years ago on my old laptop. Shout out [nibreon](https://hackmd.io/@nibreon/vapoursynth-book/%2F%40nibreon%2Fmacos) for her guide and [brandinator](https://hackmd.io/@nibreon/resizer) for the resizer in the old guide that I built on top of here, but it's 5 years old and the whole guide is not functional for ARM64 Macs. Keep in mind, this guide is **only** functional for **Macbooks with M1 chips and forward**. I made this for my M2 Macbook Air on macOS Sequoia, not sure whether it'll stay good or not with updates, but I guess we find out !! DISCLAIMER: Again, I AM NOT A PROGRAMMER, I did my best to make this as beginner-proof as possible but I don't think I'll be able to help with major errors. I do recommend having some veryyyy minimal knowledge of python but not all of us are doing compsci, so just grit your teeth and give it a go lol. DISCLAIMER 2: I am assuming that you have used the old VapourSynth guide before and know how the plugins work !! If not, maybe go read over them lol, I don't know. Just follow this guide extra-hard and don't be afraid to leave a comment if something goes wrong. ## 🎯 The Goal - **VapourSynth R72** with 15+ compiled ARM64 plugins - we will be using homebrew to install it - **VSEdit** (VapourSynth script editor) - fully functional on ARM64 now, after a lot of blood sweat and tears lol - **VapourSynth Trimmer** (custom video trimming tool) - you will load your video into this - **Visual Workflow Tool** (HTML-based cropping and processing interface) - a functional resizer basically - **Integrated workflow** from trimming → editing → processing → export ## 📋 What We Need ### System Requirements - **macOS 11.0+** (Big Sur or later) - **Apple Silicon Mac** (M1/M2/M3/M4) - ARM64 only - **Admin privileges** for installation ### Install Homebrew Dependencies We're going to open the terminal and paste these commands in order to install Homebrew if you don't have it, and then install Python, VapourSynth and FFmpeg. ```bash /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" brew install python@3.13 ``` IMPORTANT: **If you have tried to install VapourSynth on your laptop before**, using the old guide linked above or a YouTube tutorial or ANYTHING, **we MUST ensure that you DO NOT have any remains of that install**, because it will *completely destroy* this setup from the start. If this is the case, clean up by: - Installing [this script](https://drive.google.com/file/d/10HDJHBURVpiqIhIa8yXVm8dfk5a8vnxT/view?usp=sharing) and saving it to your desktop. - Opening terminal and running: ```bash cd /Desktop chmod +x /Desktop/cleanup_script.sh ./Desktop/cleanup_script.sh ``` (If you have never installed VapourSynth before, you can skip the 'IMPORTANT' note and the command above, and process with the command below.) After this, you are safe to continue the installation: ``` brew install vapoursynth ffmpeg ``` That won't take long. Now, we need to install the LLVM dependancy for some of our plugins (essential for FineSharp; sorry, this **will** take a while lol it's an annoying one; just don't close your computer while installing it and make sure your internet is kind of stable; it can be annoying if it doesn't install properly.) ``` brew install llvm ``` Verify installation: ```bash python3 -c "import vapoursynth as vs; print('VapourSynth version:', str(vs.core))" ffmpeg -version ``` The vs.core command shouldn't output much yet, as we have not moved the compiled plugins into the folders. We are just making sure everything is set up right now. The ffmpeg should output something like this: ![Screenshot](https://hackmd.io/_uploads/Hk1KyLwtlx.png) You may get an error about `llvm` on output; it is purely cosmetic and the script is functional. ## 📦 Download and Install ### 1. Download the Complete Package Download the VapourSynth macOS package: **[HERE](https://drive.google.com/file/d/153vb567LurD7YMwGhs87OXSKn7A0Pfsc/view?usp=sharing)** ### 2. Extract and Install - Extract the downloaded archive (VapourSynth.zip) into your download folder, and **move and make sure that the ```VapourSynth``` folder is moved to your DESKTOP**. It will live there forever now (sorry to people who don't like things on their desktops, I cannot for the life of me figure out another way to do it). After moving the folder to desktop, we will be moving things out: - Select VapourSynth Editor and VapourSynth Trimmer, and **drag** them both to the `Applications` folder on your computer, right there on the left. ![Screenshot 2025-08-28 at 10.59.05 pm](https://hackmd.io/_uploads/ryIzrNRFgg.png) Then open the terminal, and copy paste the following commands: ``` bash mkdir -p ~/Library/Python/3.13/lib/python/site-packages/ ln -s /usr/local/lib/vapoursynth/ ~/Desktop/VapourSynth/plugins-location ln -s ~/Library/Python/3.13/lib/python/site-packages/ ~/Desktop/VapourSynth/python-libraries-location ``` This should create 2 new shortcut folders: `plugins-location` and `python-libraries-location` (the two new folders with the arrows). ![Screenshot 2025-08-28 at 11.10.26 pm](https://hackmd.io/_uploads/HkWaD40Flx.png) Open `plugins-to-move` in another window, and select all the files inside it. Then drag them onto the `plugins-locations` folder: ![Screenshot 2025-08-28 at 11.14.38 pm](https://hackmd.io/_uploads/rkVEFECYeg.jpg) - Now the same for the scripts. Open the `python-libraries` folder, it should have assorted files and folders. Select everything inside and drag all the files to `python-libraries-location` folder: ![Screenshot 2025-08-28 at 11.17.51 pm](https://hackmd.io/_uploads/BJsYt4Atex.jpg) ### 3. Checking Installed Python VapourSynth Libraries - After ensuring these have been moved, let's test if they are working: ```bash python3 -c " import havsfunc, kagefunc, mvsfunc, G41Fun print('✅ All Python libraries installed successfully!') print('havsfunc version:', havsfunc.__version__ if hasattr(havsfunc, '__version__') else 'installed') " ``` - It should give you a result like this: ![aaaa-min](https://hackmd.io/_uploads/ryefq6PYgg.png) ## 🔐 Handling App Security (First Launch) Since the apps are unsigned, macOS will block them from the security. We have to allow them: ### VapourSynth Editor - Right-click Vapoursynth Editor in your applications and click open; it will fail and state that *"VapourSynth Editor cannot be opened because it is from an unidentified developer."* **To fix:** 1. Go to **System Preferences** → **Privacy & Security** and scroll down, making sure the Security option says `Allow apps from App Store and known developers`; if it says `Allow apps from App Store`, click it and change it. 2. Find *"VapourSynth Editor was blocked..."* underneath this option 3. Click **"Open Anyway"** 4. Click **"Open"** in the confirmation dialog and use your TouchID or type your password to confirm. ### VapourSynth Trimmer Do the same for Vapoursynth Trimmer; it will fail and state that *"VapourSynth Trimmer cannot be opened because it is from an unidentified developer."* Repeat the process: **System Preferences → Privacy & Security → Open Anyway** ![Screenshot_2025-08-30_at_8.19.27_pm](https://hackmd.io/_uploads/Bk9Y-Il5xg.png) ## 🔧 Plugin Permission Setup When you first use VapourSynth, macOS will ask permission for each plugin. This is normal but tedious. To be prepared, open **System Preferences → Privacy & Security** to be prepared in advance before you type this into terminal: ```bash # Test VapourSynth and trigger all permission dialogs python3 -c " import vapoursynth as vs core = vs.core print('Loading plugins...') # This will trigger permission dialogs for each .dylib try: clip = core.std.BlankClip() print('Core plugins loaded successfully') except: pass " ``` - This is going to create a pop up for every .dylib plugin we will be using, so the popup will appear about 15 times. It's annoying, but press okay when one pops up, do 'open anyways' in the settings page and use your password/TouchID and repeat until they don't pop up anymore. It's a bit bothersome but like, we only have to do it once, so I think it's easier than fully disabling and enabling the Gatekeeper security protocol over and over every time you want to use VapourSynth. **For each plugin permission dialog:** 1. Click **"Close"** ONLY for one. Do not click more than one plugins dialogue box, we have to do this one at a time 2. Go to **System Preferences** → **Privacy & Security** and scroll down. There should be a message about not opening the plugin (the name will match the name that popped up earlier). 3. Use TouchID or enter your password when prompted to allow the plugin to run. 4. Repeat for all the plugins (this takes a few minutes, there's like 15-ish of them) 5. Done !! ## 🧪 Test Your Installation - Copy-paste this into your terminal. ### Test VapourSynth Core ```bash python3 -c " import vapoursynth as vs core = vs.core print('VapourSynth version:', str(core)) print('Available plugins:') print('- std (core functions)') try: print('- bm3d (denoising)') core.bm3d print('- fmtc (format conversion)') core.fmtc print('- resize (scaling)') core.resize print('- eedi3 (interpolation)') core.eedi3 print('- knlm (KNLMeansCL)') core.knlm except Exception as e: print(f'Plugin test failed: {e}') " ``` It should show your loaded plugins, which should look a little like this: ![sffs](https://hackmd.io/_uploads/Bk9tCowKxe.jpg) ### Test VSEdit 1. Launch **VapourSynth Editor** from Applications 2. Click the top to create a new script 3. Try this basic script by pasting it into the blank textbox: ```python import vapoursynth as vs core = vs.core # Create a test clip clip = core.std.BlankClip(width=640, height=480, length=100) clip.set_output() ``` 4. Press the preview option on the top. It should show a blank video with a black screen and 100 frames, like this: ![Screenshot 2025-08-23 at 6.20.02 pm](https://hackmd.io/_uploads/BJbrrAwtex.png) That means the basic VapourSynth installation is complete and working !! :D Just close VS Editor now, no need to save the script or try to encode this lol. - It shouldn't crash at this point but if VapourSynth Editor crashes at any point when you're using it/giffing after the setup. Just close it and open it again... to this day I can't figure out why it does that lol but I just power through 🤷🏾‍♀️. ### Test the Complete Workflow 1. **Launch VapourSynth Trimmer**: - Go to the `Applications` folder and double-click it. It should look like this once opened: ![Screenshot 2025-08-24 at 12.16.49 am](https://hackmd.io/_uploads/BkTbg2PKlg.png) 2. **Import a video file** and set trim points (I used a .ts file for this example to also demonstrate deinterlacing, but you can use whatever file. I picked minute 02:58 and I want a 3 second clip.) ![Screenshot 2025-08-23 at 6.53.45 pm](https://hackmd.io/_uploads/B1g9y2vYel.png) 4. **Click "Trim and Launch"** 5. This should: - Create `video_cut.mkv` in your `VapourSynth` folder - Launch VSEdit - Open the visual resizer HTML tool ## 🛠️ How Giffing Will Work ### 1. Trim Your Video - Launch **VapourSynth Trimmer** - Import video file - Set start point and clip length using MM:SS format - Click **"Trim and Launch"** -- This is what it should look like: ![Screenshot 2025-08-23 at 6.53.45 pm](https://hackmd.io/_uploads/SJ_LEwPKxg.png) ### 2. Visual Processing Setup - The HTML resizer should open automatically and load your video like this (default size is 540 x 300) ![Screenshot 2025-08-23 at 6.56.46 pm](https://hackmd.io/_uploads/rkf0UdDYee.jpg) - Use visual cropping to select your region (this works like the old resizer, just use it like that.) ![Screenshot 2025-08-23 at 8.15.22 pm](https://hackmd.io/_uploads/B1CUDuDtxx.jpg) I have resized my GIF to 268x350 by changing the canvas size in the top left. This works just like the old resizer. ![Screenshot 2025-08-23 at 6.57.23 pm](https://hackmd.io/_uploads/S1w6xhvteg.png) - Configure processing options (QTGMC, denoising, etc.) Some of the options look different: ---- Picking QTGMC ensures that your GIF is deinterlaced in VapourSynth; use this on **.ts files and interlaced videos** ONLY. Do not use it on YouTube videos and fancams as it probably won't do much on those other than add more frames lmao. If it looks smoother for you feel free to use it, but I'll recommend keeping QTGMC for interlaced videos only. Ticking the 60fps box is self-explanatory, not ticking it will deinterlace at 30fps. ---- You can choose to denoise using BM3D or KNLM, pick the option. you prefer and move the slider to your preferred strength. Sharpening is only through FineSharp (if it's not broken don't fix it lol). - Copy generated VapourSynth code once you are done and open up VapourSynth Editor! ### 3. Script Editing - **VSEdit** should have opened automatically when the resizer opened. - For the first time you use it, click **File → Open script** and then open ```GIF Script.vpy``` in the `VapourSynth` folder on your desktop. A script will load up, this will be the script that you will use for your giffing. I will paste the text here too so you can check it. - Common pipeline order (you will see these commands in the script, along with comment titles on each one. I do not recommend copy-pasting them though, I'm pretty sure my syntax is incorrect lol; they're already in the script anyways, this is just for you to confirm they're looking similar): ```python import vapoursynth as vs core = vs.core core.max_cache_size = 2048 class Znedi3Wrapper: def __init__(self, plugin): self.nnedi3 = plugin.NNEDI3 znedi3 = Znedi3Wrapper(core.sneedif) def monkeypatch_znedi3(module): g = module.__dict__ if 'core' in g: try: g['core'].znedi3 = znedi3 except AttributeError: class CoreProxy: def __init__(self, original): self._original = original self.znedi3 = znedi3 def __getattr__(self, name): return getattr(self._original, name) g['core'] = CoreProxy(g['core']) import havsfunc import kagefunc import mvsfunc import G41Fun monkeypatch_znedi3(havsfunc) monkeypatch_znedi3(kagefunc) monkeypatch_znedi3(mvsfunc) video = core.lsmas.LWLibavSource("/Users/YOURNAME/Desktop/VapourSynth/video_cut.mkv") # === PROCESSING BLOCK === # # === END BLOCK === video = core.fmtc.resample(video, css="444") video = core.fmtc.bitdepth(video, bits=16) video = core.fmtc.resample(video, css="422") video = core.fmtc.bitdepth(video, bits=10) video.set_output() ``` - Also, **do not forget to change** the ```YOURNAME``` in the script to the **name of your user folder**. - The ```'PROCESSING BLOCK & END BLOCK'``` area is what we are interested in. In your editor script, there will be commands here. Now, after you've resized your GIF in the resizer and used the sliders to change the strength of the plugins, there will be a block of text on the right. **This** is the block we will be pasting into the VapourSynth Editor script. ![Screenshot 2025-08-24 at 12.25.35 am](https://hackmd.io/_uploads/rypnz3DYeg.png) - THIS is what you will copy-paste into the resizer. YOU MUST NOT. EVERRRR mess with the other parts of the script, because they are very fragile and the whole thing can break lol. You'll paste it here, and ***do NOT touch* any other part of the script**, ONLY paste the processing block: ![blej](https://hackmd.io/_uploads/HkIQW6vKxl.png) ### 4. Export To make sure everything is smooth, hit **Script > Check Script**. It should show you that everything is fine with this green message at the bottom, like this. (Save the script before lol, if it crashes, just reopen it. It'll work... eventually... 😬) ![asdlgjlaskdgja](https://hackmd.io/_uploads/H1WjW6vtee.png) Use the previewer to check if anything isn't to your liking, you can adjust the values for the filters and re-paste them and open the previewer to see the difference. When you want to encode, click **Script > Encode video**. It will look like this: ![sdafsdfa](https://hackmd.io/_uploads/S1p3s6wFel.png) and then paste *this* command into the empty textbox to render your final output (of course, change YOURNAME to the name of your user folder): ```bash -f yuv4mpegpipe -i - -c:v prores_ks -profile:v 4 -pix_fmt yuv444p10le -y "/Users/YOURNAME/Desktop/VapourSynth/output/output.mov" ``` After that, type ```.mov``` into the preset box, and make sure that the executable is leading you to ```/Library/Frameworks/VapourSynth.framework/bin/ffmpeg/bin/ffmpeg```. If it's not, click the yellow folder icon and select it (be careful when in your Libary folder though). Click ```Save``` after you do this so that you don't have to do it again. It should look this this (of course, replace ```YOURNAME``` with your user folder name.) ![Screenshot 2025-08-24 at 12.37.03 am](https://hackmd.io/_uploads/BkTBH2wtxx.png) Hit start and we're finally done! Once the video has finished encoding, it'll be in the output folder in the ```VapourSynth``` folder on your Desktop: ![Screenshot 2025-08-23 at 8.59.39 pm](https://hackmd.io/_uploads/B1CzNFPKel.png) From here, you can load it into Adobe Photoshop using the `convert video frames to layers` feature there (sorry to screencappers and `.psd` enthusiasts, I have no idea how to implement that; I've always used the `.mov` export lol.) Anyways, here's my gif after all that trouble 😝 (yeah it's mid and short but the upload limit on this website is ONE. MEGABYTE so spare me lol.) ![dalfkjs](https://hackmd.io/_uploads/SyMQVAwKxx.gif) ## 🚨 Troubleshooting ### "Plugin failed to load" Errors **Problem**: Permission denied for .dylib files **Solution**: ```bash # Fix plugin permissions sudo chmod +x /usr/local/lib/vapoursynth/*.dylib sudo xattr -r -d com.apple.quarantine /usr/local/lib/vapoursynth/ ``` ### RemoveGrain Plugin Issues **Problem**: `libremovegrain.dylib` fails to load (LLVM library issue) **Solution**: This is a known false alarm that pops up whenever you open the previewer. It will say at the top of the log at the bottom: ``` Failed to load /usr/local/lib/vapoursynth/libremovegrain.dylib. Error given: dlopen(/usr/local/lib/vapoursynth/libremovegrain.dylib, 0x0001): Library not loaded: /opt/homebrew/opt/llvm/lib/c++/libc++.1.dylib Referenced from: <4C4C443D-5555-3144-A126-A59E41372E00> /usr/local/lib/vapoursynth/libremovegrain.dylib Reason: tried: '/opt/homebrew/opt/llvm/lib/c++/libc++.1.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/opt/homebrew/opt/llvm/lib/c++/libc++.1.dylib' (no such file), '/opt/homebrew/opt/llvm/lib/c++/libc++.1.dylib' (no such file) ``` It's just a cosmetic error, but if it's annoying you can simply type this command into your terminal: ``` sudo install_name_tool -change /opt/homebrew/opt/llvm/lib/c++/libc++.1.dylib /usr/lib/libc++.1.dylib /usr/local/lib/vapoursynth/libremovegrain.dylib ``` And it should be gone next time you open the previewer :stuck_out_tongue_closed_eyes: . ### Python Version Conflicts **Problem**: VapourSynth not found in Python **Solution**: ```bash # Check your Python setup which python3 python3 -c "import sys; print(sys.path)" # If using wrong Python, ensure Homebrew Python is first in PATH echo 'export PATH="/opt/homebrew/bin:$PATH"' >> ~/.zshrc source ~/.zshrc ``` ### VSEdit Won't Launch **Problem**: Application cannot be opened **Solutions**: 1. **Security**: System Preferences → Privacy & Security → Open Anyway 2. **Permissions**: ```bash chmod +x "/Applications/VapourSynth Editor.app/Contents/MacOS/VapourSynth Editor" ``` 3. **Quarantine**: ```bash xattr -r -d com.apple.quarantine "/Applications/VapourSynth Editor.app" ``` Do this with VapourSynth Trimmer too if needed. ### HTML Workflow Tool Issues **Problem**: Workflow HTML doesn't load video **Solution**: Ensure `video_cut.mkv` exists in the VapourSynth folder: ```bash ls -la ~/Desktop/VapourSynth/video_cut.mkv ``` ### FFmpeg Not Found **Problem**: Trimmer can't find FFmpeg **Solution**: ```bash # Verify FFmpeg installation which ffmpeg # If not found, reinstall brew reinstall ffmpeg # Add to PATH if needed echo 'export PATH="/opt/homebrew/bin:$PATH"' >> ~/.zshrc source ~/.zshrc ``` ## 🎯 Advanced Tips ### Custom Sharpening Since other sharpening tools aren't available, use this manual sharpening if you want (and if you know what you're doing !! You can paste this right before the `# === END BLOCK ===`): ```python def gentle_sharpen(clip, strength=0.3): """Gentle sharpening using std.Convolution""" blur = core.std.Convolution(clip, matrix=[1, 2, 1, 2, 4, 2, 1, 2, 1]) return core.std.Expr([clip, blur], f"x x y - {strength} * +") def unsharp_mask(clip, strength=0.5, radius=1.0): """Unsharp mask implementation""" if radius <= 1.0: matrix = [1, 2, 1, 2, 4, 2, 1, 2, 1] # 3x3 Gaussian else: matrix = [1, 4, 7, 4, 1, 4, 16, 26, 16, 4, 7, 26, 41, 26, 7, 4, 16, 26, 16, 4, 1, 4, 7, 4, 1] # 5x5 blur = core.std.Convolution(clip, matrix=matrix) return core.std.Expr([clip, blur], f"x x y - {strength} * +") ``` ### Memory Management For large files, manage memory usage: ```python # Set cache size (in MB) core.max_cache_size = 1024 ``` You can adjust this in the script or remove it by putting a # before the word core, if you see fit. ## 📚 Additional Resources - **VapourSynth Documentation**: [vapoursynth.com](http://vapoursynth.com/doc/) - **Plugin Database**: [vsdb.top](https://vsdb.top/) (a lot of plugins here are outdated, keep in mind you might have to compile them yourself for arm64 Mac.) - **VapourSynth Forums**: if you'd like to torture yourself like me, trudge through the [VapourSynth Doom9 forums](https://forum.doom9.org/showthread.php?t=165771) for more plugins to compile, but I'd steer clear if you're a noob. - If you're having errors, do **not** ask ChatGPT !! Regardless of your stance on AI, ChatGPT and Gemini and other major AI chatbots are garbage here because they are not trained on VapourSynth, and it will probably mess up your problems more and not actually fix them. If you MUST use one to fix your errors because you don't know and can't get help, use Claude. Anything else will probably destroy your setup and ruin everything. But if you learn a tiny bit of code (like I forced myself to lol) then you'll be able to help yourself. - Regardless, if something doesn't work, leave a comment !! I said I can't help much because I'm a very busy overworked student who barely knows code, but I'll still try lol. --- ## 🫀 Credits This setup includes the HTML resizer elements I built on top of, borrowed from [brandinator](https://hackmd.io/@nibreon/resizer) in the [nibreon](https://hackmd.io/@nibreon/vapoursynth-book/%2F%40nibreon%2Fmacos) guide (shout-out to them for the inspo to write the guide. Feel free to look at the old guide for gif examples, but do not try to use the old code there because a lot of the plugins have different names now, and it will mess up your setup.) Thank you to YomikoR on github, whose forked version of [VSEditor](https://github.com/YomikoR/VapourSynth-Editor) was the only non-obsolete thing I could find because the old one was no longer working well. And thank you to me !! I had to build that app for Mac, and make all the ARM64 compilations of VapourSynth plugins and the trimmer app and build on the ``.html`` resizer tool lmao. All plugins retain their original licenses and credits to their respective authors, of course. Happy giffing !! :DD