Created
April 5, 2023 03:46
-
-
Save dmoruzzi/2414f3edbee0331b13b55b3e3c2b608b to your computer and use it in GitHub Desktop.
Convert MP4 to PDF
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import subprocess | |
import argparse | |
import logging | |
from PIL import Image | |
from pathlib import Path | |
# Define command line arguments | |
parser = argparse.ArgumentParser(description="Convert MP4 to PDF") | |
parser.add_argument( | |
"input_file", | |
nargs="?", | |
default="input.mp4", | |
help="path to input video file (default: input.mp4)", | |
) | |
parser.add_argument( | |
"output_file", | |
nargs="?", | |
default="output.pdf", | |
help="path to output PDF file (default: output.pdf)", | |
) | |
args = parser.parse_args() | |
# Manage logging | |
logger = logging.getLogger(__name__) | |
logger.setLevel(logging.INFO) | |
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s") | |
file_handler = logging.FileHandler("conversion.log") | |
file_handler.setLevel(logging.DEBUG) | |
file_handler.setFormatter(formatter) | |
logger.addHandler(file_handler) | |
# Check if ffmpeg is installed | |
try: | |
subprocess.check_call( | |
["ffmpeg", "-version"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL | |
) | |
except subprocess.CalledProcessError: | |
logger.error("Please install ffmpeg and add it to your PATH environment variable") | |
exit(1) | |
# Make sure input file exists | |
if not os.path.exists(args.input_file): | |
logger.error("Input file does not exist") | |
exit(1) | |
# Make sure input file is an MP4 | |
if not args.input_file.endswith(".mp4"): | |
logger.error("Input file is not an MP4") | |
exit(1) | |
# Make sure input file is not empty | |
if os.path.getsize(args.input_file) == 0: | |
logger.error("Input file is empty") | |
exit(1) | |
# Create frames directory if it doesn't exist | |
output_folder: str = "frames" | |
os.makedirs(output_folder, exist_ok=True) | |
# Convert MP4 to PNG frames | |
try: | |
subprocess.check_call( | |
[ | |
"ffmpeg", | |
"-hide_banner", | |
"-loglevel", | |
"error", | |
"-i", | |
args.input_file, | |
"-vf", | |
"scale=595:-1", | |
f"{output_folder}/frame-%03d.png", | |
] | |
) | |
except subprocess.CalledProcessError as e: | |
logger.error(f"Error converting MP4 to PNG frames: {e}") | |
exit(1) | |
# Create a list of PIL Image objects from PNG files in frames directory | |
frames: list = [] | |
for frame_file in Path("frames").glob("*.png"): | |
try: | |
frame = Image.open(frame_file) | |
frames.append(frame) | |
except IOError as e: | |
logger.warning(f"Error opening frame file {frame_file}: {e}") | |
# Save frames as pages in a new PDF file | |
try: | |
frames[0].save( | |
args.output_file, | |
save_all=True, | |
append_images=frames[1:], | |
optimize=False, | |
quality=100, | |
) | |
except Exception as e: | |
logger.error(f"Error saving PDF file: {e}") | |
exit(1) | |
# Delete each PNG file and the frames directory | |
for file in os.listdir(output_folder): | |
try: | |
os.remove(os.path.join(output_folder, file)) | |
except OSError as e: | |
logger.warning(f"Error deleting file {os.path.join(output_folder, file)}: {e}") | |
try: | |
os.rmdir(output_folder) | |
except OSError as e: | |
logger.warning(f"Error deleting directory {output_folder}: {e}") | |
# Open PDF document | |
if os.name == "nt": | |
os.startfile(args.output_file) | |
elif os.name == "posix": | |
subprocess.check_call(["xdg-open", args.output_file]) | |
else: | |
logger.warning(f"Could not open {args.output_file} automatically") | |
print(f"Please open {args.output_file}.") | |
# Exit program | |
exit(0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment