Created
December 12, 2024 13:44
-
-
Save alex0x08/e74e27f09336670c8c69c3ffa74d46db to your computer and use it in GitHub Desktop.
This script converts webp to mp4
This file contains hidden or 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 shutil | |
import tempfile | |
import argparse | |
from moviepy.video.io.ImageSequenceClip import ImageSequenceClip | |
import PIL.Image | |
def analyse_image(path): | |
im = PIL.Image.open(path) | |
results = { | |
'size': im.size, | |
'mode': 'full', | |
} | |
try: | |
while True: | |
if im.tile: | |
tile = im.tile[0] | |
update_region = tile[1] | |
update_region_dimensions = update_region[2:] | |
if update_region_dimensions != im.size: | |
results['mode'] = 'partial' | |
break | |
im.seek(im.tell() + 1) | |
except EOFError: | |
pass | |
return results | |
def process_image(path, temp_dir): | |
images = [] | |
mode = analyse_image(path)['mode'] | |
im = PIL.Image.open(path) | |
i = 0 | |
p = im.getpalette() | |
last_frame = im.convert('RGBA') | |
try: | |
while True: | |
basename = os.path.basename(path) | |
output_folder = temp_dir | |
frame_file_name = os.path.join(output_folder, f'{os.path.splitext(basename)[0]}-{i}.png') | |
print(f"saving {path} ({mode}) frame {i}, {im.size} {im.tile} to {frame_file_name}") | |
if '.gif' in path: | |
if not im.getpalette(): | |
im.putpalette(p) | |
new_frame = PIL.Image.new('RGBA', im.size) | |
if mode == 'partial': | |
new_frame.paste(last_frame) | |
new_frame.paste(im, (0, 0), im.convert('RGBA')) | |
new_frame.save(frame_file_name, 'PNG') | |
images.append(frame_file_name) | |
i += 1 | |
last_frame = new_frame | |
im.seek(im.tell() + 1) | |
except EOFError: | |
pass | |
return images | |
def webp_mp4(input_file, output_file=None, fps=20): | |
temp_dir = tempfile.mkdtemp() | |
try: | |
images = process_image(input_file, temp_dir) | |
if output_file is None: | |
output_file = os.path.splitext(input_file)[0] + '.mp4' | |
clip = ImageSequenceClip(images, fps=fps) | |
clip.write_videofile(output_file) | |
return [output_file] | |
finally: | |
shutil.rmtree(temp_dir) | |
def parse_arguments(): | |
parser = argparse.ArgumentParser(description="Convert WEBP to MP4") | |
parser.add_argument("input_file", help="Input file name (.webp)") | |
parser.add_argument("-o", "--output_file", help="Output file name (optional)") | |
parser.add_argument("--fps", type=int, default=20, help="Frames per second (default: 20)") | |
return parser.parse_args() | |
if __name__ == "__main__": | |
args = parse_arguments() | |
from pathlib import Path | |
folder = args.input_file | |
for f in Path(folder).glob('*.webp'): | |
if f.is_file(): | |
webp_mp4(str(f), args.output_file, args.fps) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment