wschrab revised this gist 1 month ago. Go to revision
No changes
wschrab revised this gist 1 month ago. Go to revision
No changes
wschrab revised this gist 1 month ago. Go to revision
1 file changed, 23 insertions, 3 deletions
VideoConvert.py
| @@ -1,12 +1,32 @@ | |||
| 1 | + | import sys | |
| 2 | + | import os | |
| 1 | 3 | import subprocess | |
| 2 | 4 | from pathlib import Path | |
| 3 | 5 | ||
| 6 | + | # --- PyInstaller & Path Handling --- | |
| 7 | + | if getattr(sys, 'frozen', False): | |
| 8 | + | # Running as a compiled PyInstaller executable | |
| 9 | + | EXE_DIR = Path(sys.executable).parent | |
| 10 | + | BUNDLE_DIR = Path(sys._MEIPASS) | |
| 11 | + | else: | |
| 12 | + | # Running as a standard Python script | |
| 13 | + | EXE_DIR = Path(__file__).parent | |
| 14 | + | BUNDLE_DIR = EXE_DIR | |
| 15 | + | ||
| 16 | + | # Locate the bundled ffmpeg.exe | |
| 17 | + | FFMPEG_EXE = BUNDLE_DIR / "ffmpeg.exe" | |
| 18 | + | ||
| 19 | + | # If ffmpeg.exe isn't bundled inside, fallback to system PATH | |
| 20 | + | if not FFMPEG_EXE.exists(): | |
| 21 | + | FFMPEG_EXE = "ffmpeg" | |
| 22 | + | ||
| 4 | 23 | # Settings | |
| 5 | 24 | TARGET_WIDTH = 1280 | |
| 6 | 25 | TARGET_HEIGHT = 720 | |
| 7 | 26 | TARGET_FPS = 24 | |
| 8 | 27 | ||
| 9 | - | input_folder = Path(__file__).parent | |
| 28 | + | # Process videos relative to where the executable/script resides | |
| 29 | + | input_folder = EXE_DIR | |
| 10 | 30 | output_folder = input_folder / "converted" | |
| 11 | 31 | output_folder.mkdir(exist_ok=True) | |
| 12 | 32 | ||
| @@ -15,7 +35,7 @@ mp4_files = list(input_folder.glob("*.mp4")) | |||
| 15 | 35 | if not mp4_files: | |
| 16 | 36 | print("No MP4 files found.") | |
| 17 | 37 | input("Press Enter to exit...") | |
| 18 | - | quit() | |
| 38 | + | sys.exit() | |
| 19 | 39 | ||
| 20 | 40 | for video in mp4_files: | |
| 21 | 41 | output_file = output_folder / video.name | |
| @@ -23,7 +43,7 @@ for video in mp4_files: | |||
| 23 | 43 | print(f"Converting: {video.name}") | |
| 24 | 44 | ||
| 25 | 45 | cmd = [ | |
| 26 | - | "ffmpeg", | |
| 46 | + | str(FFMPEG_EXE), # Points directly to bundled ffmpeg.exe | |
| 27 | 47 | "-y", | |
| 28 | 48 | "-i", str(video), | |
| 29 | 49 | "-vf", | |
wschrab revised this gist 1 month ago. Go to revision
1 file changed, 49 insertions
VideoConvert.py(file created)
| @@ -0,0 +1,49 @@ | |||
| 1 | + | import subprocess | |
| 2 | + | from pathlib import Path | |
| 3 | + | ||
| 4 | + | # Settings | |
| 5 | + | TARGET_WIDTH = 1280 | |
| 6 | + | TARGET_HEIGHT = 720 | |
| 7 | + | TARGET_FPS = 24 | |
| 8 | + | ||
| 9 | + | input_folder = Path(__file__).parent | |
| 10 | + | output_folder = input_folder / "converted" | |
| 11 | + | output_folder.mkdir(exist_ok=True) | |
| 12 | + | ||
| 13 | + | mp4_files = list(input_folder.glob("*.mp4")) | |
| 14 | + | ||
| 15 | + | if not mp4_files: | |
| 16 | + | print("No MP4 files found.") | |
| 17 | + | input("Press Enter to exit...") | |
| 18 | + | quit() | |
| 19 | + | ||
| 20 | + | for video in mp4_files: | |
| 21 | + | output_file = output_folder / video.name | |
| 22 | + | ||
| 23 | + | print(f"Converting: {video.name}") | |
| 24 | + | ||
| 25 | + | cmd = [ | |
| 26 | + | "ffmpeg", | |
| 27 | + | "-y", | |
| 28 | + | "-i", str(video), | |
| 29 | + | "-vf", | |
| 30 | + | f"scale={TARGET_WIDTH}:{TARGET_HEIGHT}:force_original_aspect_ratio=decrease,pad={TARGET_WIDTH}:{TARGET_HEIGHT}:(ow-iw)/2:(oh-ih)/2", | |
| 31 | + | "-r", str(TARGET_FPS), | |
| 32 | + | "-c:v", "libx264", | |
| 33 | + | "-preset", "veryfast", | |
| 34 | + | "-crf", "25", | |
| 35 | + | "-pix_fmt", "yuv420p", | |
| 36 | + | "-c:a", "aac", | |
| 37 | + | "-b:a", "128k", | |
| 38 | + | str(output_file) | |
| 39 | + | ] | |
| 40 | + | ||
| 41 | + | result = subprocess.run(cmd) | |
| 42 | + | ||
| 43 | + | if result.returncode == 0: | |
| 44 | + | print(f"✓ Finished {video.name}") | |
| 45 | + | else: | |
| 46 | + | print(f"✗ Failed {video.name}") | |
| 47 | + | ||
| 48 | + | print("\nDone!") | |
| 49 | + | input("Press Enter to exit...") | |