Greatly simplified things by doing palettegen and paletteuse in the same command; I also don't think ewa scaling was working, so I changed to plain old lanc
This commit is contained in:
parent
b804f628ae
commit
01c31ae17d
|
@ -1,6 +1,6 @@
|
||||||
# video-to-gif
|
# video-to-gif
|
||||||
```
|
```
|
||||||
usage: video_to_gif.py [-h] -i INPUT [-w WIDTH] [-r FRAMERATE] [-t TAG] [-f] [-c]
|
usage: video_to_gif.py [-h] -i INPUT [-w WIDTH] [-r FRAMERATE] [-t TAG]
|
||||||
|
|
||||||
Use ffmpeg to make GIFs from videos
|
Use ffmpeg to make GIFs from videos
|
||||||
|
|
||||||
|
@ -13,8 +13,6 @@ options:
|
||||||
-r FRAMERATE, --framerate FRAMERATE
|
-r FRAMERATE, --framerate FRAMERATE
|
||||||
Framerate of GIF
|
Framerate of GIF
|
||||||
-t TAG, --tag TAG Optional tag included in file name
|
-t TAG, --tag TAG Optional tag included in file name
|
||||||
-f, --force_palette Force regeneration of GIF color palettes
|
|
||||||
-c, --clean_up Delete color palettes after finishing GIFs
|
|
||||||
|
|
||||||
— Be gay and do crime
|
— Be gay and do crime
|
||||||
```
|
```
|
|
@ -1,7 +1,6 @@
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import glob
|
import glob
|
||||||
import os
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import random
|
import random
|
||||||
import string
|
import string
|
||||||
|
@ -22,10 +21,6 @@ def get_args() -> Dict[str, Any]:
|
||||||
default='12', help='Framerate of GIF')
|
default='12', help='Framerate of GIF')
|
||||||
parser.add_argument('-t', '--tag', type=str, default=get_tag(),
|
parser.add_argument('-t', '--tag', type=str, default=get_tag(),
|
||||||
help='Optional tag included in file name')
|
help='Optional tag included in file name')
|
||||||
parser.add_argument('-f', '--force_palette', action='store_const',
|
|
||||||
const=True, help='Force regeneration of GIF color palettes')
|
|
||||||
parser.add_argument('-c', '--clean_up', action='store_const',
|
|
||||||
const=True, help='Delete color palettes after finishing GIFs')
|
|
||||||
return vars(parser.parse_args())
|
return vars(parser.parse_args())
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,62 +32,30 @@ def get_inputs(args: Dict[str, Any]) -> List[str]:
|
||||||
return glob.glob(args['input'])
|
return glob.glob(args['input'])
|
||||||
|
|
||||||
|
|
||||||
def clean_up_palette_files(palette_map: Dict[str, str]) -> None:
|
|
||||||
for input in palette_map:
|
|
||||||
os.remove(palette_map[input])
|
|
||||||
|
|
||||||
|
|
||||||
def call_ffmpeg(command: str) -> str:
|
def call_ffmpeg(command: str) -> str:
|
||||||
print("ffmpeg", *command.split(' '))
|
print("ffmpeg", *command.split(' '))
|
||||||
return str(subprocess.run(["ffmpeg", '-hide_banner', '-loglevel', 'error', *command.split(' ')]))
|
return str(subprocess.run(["ffmpeg", '-hide_banner', '-loglevel', 'error', *command.split(' ')]))
|
||||||
|
|
||||||
|
|
||||||
def generate_palette_files_and_map(inputs: List[str], args: Dict[str, Any]) -> Dict[str, str]:
|
def generate_gif_files(inputs: List[str], args: Dict[str, Any]) -> Dict[str, str]:
|
||||||
force_palette = args['force_palette']
|
|
||||||
width = args['width']
|
|
||||||
tag = args['tag']
|
|
||||||
|
|
||||||
palette_map = {}
|
|
||||||
for input in inputs:
|
|
||||||
file_name = f"{Path(input).stem}_{tag}_palette.png"
|
|
||||||
full_path = f"{Path(input).parent}/{file_name}"
|
|
||||||
if force_palette or not os.path.exists(full_path):
|
|
||||||
call_ffmpeg(
|
|
||||||
f"-i {input} -lavfi scale={width}:-1,palettegen -sws_flags ewa_lanczos -y {full_path}")
|
|
||||||
else:
|
|
||||||
print(f"Skipped regenerating palette file {file_name}...")
|
|
||||||
palette_map[input] = full_path
|
|
||||||
|
|
||||||
return palette_map
|
|
||||||
|
|
||||||
|
|
||||||
def generate_gif_files(palette_map: Dict[str, str], args: Dict[str, Any]) -> Dict[str, str]:
|
|
||||||
tag = args['tag']
|
tag = args['tag']
|
||||||
width = args['width']
|
width = args['width']
|
||||||
framerate = args['framerate']
|
framerate = args['framerate']
|
||||||
|
|
||||||
output_map = {}
|
output_map = {}
|
||||||
for input in palette_map:
|
for input in inputs:
|
||||||
palette = palette_map[input]
|
|
||||||
file_name = f"{Path(input).stem}_{tag}.gif"
|
file_name = f"{Path(input).stem}_{tag}.gif"
|
||||||
full_path = f"{Path(input).parent}/{file_name}"
|
full_path = f"{Path(input).parent}/{file_name}"
|
||||||
call_ffmpeg(f"-i {input} -i {palette} -f gif -r {framerate} -lavfi scale={ \
|
call_ffmpeg(f"-i {input} -f gif -r {framerate} -filter_complex scale={ \
|
||||||
width}:-1,paletteuse -sws_flags ewa_lanczos {full_path}")
|
width}:-1:flags=lanczos,split[v1][v2];[v1]palettegen[plt];[v2][plt]paletteuse {full_path}")
|
||||||
output_map[input] = full_path
|
output_map[input] = full_path
|
||||||
|
|
||||||
return output_map
|
return output_map
|
||||||
|
|
||||||
|
|
||||||
def make_gifs(args: Dict[str, Any]) -> None:
|
def make_gifs(args: Dict[str, Any]) -> None:
|
||||||
clean_up = args['clean_up']
|
|
||||||
inputs = get_inputs(args)
|
inputs = get_inputs(args)
|
||||||
|
output_map = generate_gif_files(inputs, args)
|
||||||
palette_map = generate_palette_files_and_map(inputs, args)
|
|
||||||
output_map = generate_gif_files(palette_map, args)
|
|
||||||
|
|
||||||
if clean_up:
|
|
||||||
clean_up_palette_files(palette_map)
|
|
||||||
|
|
||||||
for input in output_map:
|
for input in output_map:
|
||||||
print(f"Created {output_map[input]} from {input}")
|
print(f"Created {output_map[input]} from {input}")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue