
As a content creator, I often need to convert landscape or square videos into the vertical 9:16 format required for Instagram Reels. Manually converting dozens of videos is time-consuming, so I built a Python script to automate this process. In this blog post, I'll walk you through how to create a robust video conversion tool using Python and FFmpeg.
The Challenge
Instagram Reels require a specific aspect ratio (9:16) and resolution (1080x1920 pixels). When you have a collection of videos in various formats (landscape, square, or other aspect ratios), converting them manually would take hours. Automation is the key to efficiency.
The Solution: Python + FFmpeg
I created a Python script that:
Automatically finds all video files in a directory
Converts them to 9:16 format (1080x1920)
Maintains video quality with optimised encoding settings
Provides progress tracking and error handling
Saves all converted videos in a dedicated output folder
Prerequisites
Before we dive into the code, you'll need:
Python 3.7+ - The script uses modern Python features
FFmpeg - The powerful multimedia framework that does the actual conversion
Install via: brew install ffmpeg (macOS) or apt-get install ffmpeg (Linux)
Or download from ffmpeg.org
The Complete Script
Here's the full Python script with detailed comments:
1#!/usr/bin/env python3
2"""
3Video to Reels Converter
4Converts videos to Instagram Reels format (9:16 aspect ratio, 1080x1920)
5"""
6
7import os
8import subprocess
9import sys
10from pathlib import Path
11from typing import List, Tuple
12
13
14def find_video_files(directory: str = ".", exclude: List[str] = None) -> List[Path]:
15 """
16 Find all video files in the specified directory.
17
18 Args:
19 directory: Directory to search for videos
20 exclude: List of filenames to exclude from conversion
21
22 Returns:
23 List of Path objects for video files
24 """
25 if exclude is None:
26 exclude = ["South_Africa_YouTube_Short_30sec.mp4"]
27
28 video_extensions = [".mov", ".mp4", ".MOV", ".MP4"]
29 video_files = []
30
31 directory_path = Path(directory)
32
33 for file_path in directory_path.iterdir():
34 if file_path.is_file() and file_path.suffix in video_extensions:
35 if file_path.name not in exclude:
36 video_files.append(file_path)
37
38 return sorted(video_files)
39
40
41def check_ffmpeg() -> bool:
42 """Check if ffmpeg is installed and available."""
43 try:
44 subprocess.run(
45 ["ffmpeg", "-version"],
46 stdout=subprocess.DEVNULL,
47 stderr=subprocess.DEVNULL,
48 check=True
49 )
50 return True
51 except (subprocess.CalledProcessError, FileNotFoundError):
52 return False
53
54
55def convert_video_to_reels(
56 input_path: Path,
57 output_dir: Path,
58 width: int = 1080,
59 height: int = 1920
60) -> Tuple[bool, str]:
61 """
62 Convert a video to Instagram Reels format.
63
64 Args:
65 input_path: Path to input video file
66 output_dir: Directory to save output file
67 width: Output width in pixels (default: 1080)
68 height: Output height in pixels (default: 1920)
69
70 Returns:
71 Tuple of (success: bool, message: str)
72 """
73 # Create output directory if it doesn't exist
74 output_dir.mkdir(parents=True, exist_ok=True)
75
76 # Generate output filename
77 output_filename = f"{input_path.stem}_reels.mp4"
78 output_path = output_dir / output_filename
79
80 # FFmpeg command to convert to 9:16 format
81 # Scale to fit height, then crop width, or scale to fit width and pad height
82 ffmpeg_cmd = [
83 "ffmpeg",
84 "-i", str(input_path),
85 "-vf", f"scale={width}:{height}:force_original_aspect_ratio=increase,crop={width}:{height}",
86 "-c:v", "libx264",
87 "-preset", "medium",
88 "-crf", "23",
89 "-c:a", "aac",
90 "-b:a", "128k",
91 "-movflags", "+faststart",
92 "-y", # Overwrite output file if it exists
93 str(output_path)
94 ]
95
96 try:
97 # Run ffmpeg and capture output
98 result = subprocess.run(
99 ffmpeg_cmd,
100 stdout=subprocess.PIPE,
101 stderr=subprocess.PIPE,
102 text=True
103 )
104
105 if result.returncode == 0:
106 return True, f"✓ Completed: {output_path}"
107 else:
108 return False, f"✗ Error converting: {input_path.name}\n {result.stderr[:200]}"
109
110 except Exception as e:
111 return False, f"✗ Exception: {str(e)}"
112
113
114def main():
115 """Main function to convert all videos to Reels format."""
116 print("=" * 50)
117 print("Video to Instagram Reels Converter")
118 print("=" * 50)
119 print()
120
121 # Check if ffmpeg is available
122 if not check_ffmpeg():
123 print("Error: ffmpeg is not installed or not in PATH.")
124 print("Please install ffmpeg: https://ffmpeg.org/download.html")
125 sys.exit(1)
126
127 # Find all video files
128 video_files = find_video_files()
129
130 if not video_files:
131 print("No video files found to convert.")
132 sys.exit(0)
133
134 total = len(video_files)
135 print(f"Found {total} videos to convert...")
136 print("Starting conversion to 9:16 format (1080x1920)...")
137 print()
138
139 # Create output directory
140 output_dir = Path("reels")
141
142 # Convert each video
143 converted = 0
144 successful = 0
145 failed = 0
146
147 for idx, video_file in enumerate(video_files, 1):
148 print(f"[{idx}/{total}] Converting: {video_file.name}")
149
150 success, message = convert_video_to_reels(video_file, output_dir)
151 print(f" {message}")
152 print()
153
154 converted += 1
155 if success:
156 successful += 1
157 else:
158 failed += 1
159
160 # Print summary
161 print("=" * 50)
162 print("Conversion Summary")
163 print("=" * 50)
164 print(f"Total videos processed: {converted}")
165 print(f"Successfully converted: {successful}")
166 print(f"Failed: {failed}")
167 print(f"All files saved in: {output_dir.absolute()}/")
168 print("=" * 50)
169
170
171if __name__ == "__main__":
172 main()Key Features Explained
1. File Discovery
The find_video_files() function uses Python's pathlib module to scan the directory for video files. It supports common formats (.mov, .mp4) and allows you to exclude specific files from conversion.
2. FFmpeg Integration
The script uses Python's subprocess module to execute FFmpeg commands. The conversion uses a video filter (-vf) that:
Scales the video to fit the 1080x1920 frame
Crops to ensure exact 9:16 aspect ratio
Maintains the original aspect ratio while fitting the new dimensions
3. Encoding Settings
The script uses optimized encoding parameters:
Codec: H.264 (libx264) - widely compatible
Preset: Medium - good balance between speed and file size
CRF: 23 - constant rate factor for quality (lower = better quality, larger file)
Audio: AAC at 128kbps - standard for web video
Faststart: Enables streaming-friendly playback
4. Error Handling
The script includes comprehensive error handling:
Checks if FFmpeg is installed before starting
Captures and displays conversion errors
Tracks successful vs. failed conversions
Provides a summary at the end
Usage
Save the script as convert_to_reels.py
Make it executable (optional):
1chmod +x convert_to_reels.pyRun it in a directory containing your videos:
1python3 convert_to_reels.pyFind your converted videos in the reels/ directory
Example Output
1==================================================
2Video to Instagram Reels Converter
3==================================================
4
5Found 25 videos to convert...
6Starting conversion to 9:16 format (1080x1920)...
7
8[1/25] Converting: video1.mov
9 ✓ Completed: reels/video1_reels.mp4
10
11[2/25] Converting: video2.mp4
12 ✓ Completed: reels/video2_reels.mp4
13
14...
15
16==================================================
17Conversion Summary
18==================================================
19Total videos processed: 25
20Successfully converted: 25
21Failed: 0
22All files saved in: /path/to/reels/
23==================================================Customization Options
You can easily customise the script:
Change output resolution: Modify the width and height parameters
Adjust quality: Change the CRF value (18-28 range, lower = better quality)
Change output directory: Modify the output_dir variable
Add more video formats: Extend the video_extensions list
Modify encoding preset: Change from "medium" to "fast" or "slow"
Performance Tips
Batch Processing: The script processes videos sequentially. For faster processing on multi-core systems, you could modify it to use Python's multiprocessing module.
Storage: Ensure you have enough disk space - converted videos can be large
Quality vs. Speed: The "medium" preset offers a good balance. Use "fast" for quicker conversions or "slow" for better compression
Conclusion
This Python script demonstrates how automation can save hours of manual work. By combining Python's ease of use with FFmpeg's powerful video processing capabilities, we've created a tool that efficiently converts videos to the Instagram Reels format.
The script is modular, well-documented, and easy to extend. You could add features like:
Progress bars using tqdm
Parallel processing for faster conversions
GUI interface using tkinter or PyQt
Integration with cloud storage APIs
Automatic upload to Instagram
Feel free to use this script as a starting point for your own video processing projects!
If you found this helpful, check out more of my projects and tutorials on tayloramitverma.com
Share this article
Found it helpful? Share it with your network.
Related Posts

How to Install NVM, Install Node.js, and Manage Multiple Node Versions (Windows, macOS & Linux)
Learn how to install NVM on Windows, macOS, and Linux and manage multiple Node.js versions easily. Step-by-step guide to installing Node.js, switching versions, setting defaults, and using .nvmrc for projects. Perfect for beginners and developers.