mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 17:24:32 +02:00
refactor video file create and save
Signed-off-by: Vladimir Mandic <mandic00@live.com>
This commit is contained in:
+1
-70
@@ -15,6 +15,7 @@ from modules import sd_samplers, shared, script_callbacks, errors, paths
|
||||
from modules.images_grid import image_grid, get_grid_size, split_grid, combine_grid, check_grid_size, get_font, draw_grid_annotations, draw_prompt_matrix, GridAnnotation, Grid # pylint: disable=unused-import
|
||||
from modules.images_resize import resize_image # pylint: disable=unused-import
|
||||
from modules.images_namegen import FilenameGenerator, get_next_sequence_number # pylint: disable=unused-import
|
||||
from modules.video import save_video # pylint: disable=unused-import
|
||||
|
||||
|
||||
debug = errors.log.trace if os.environ.get('SD_PATH_DEBUG', None) is not None else lambda *args, **kwargs: None
|
||||
@@ -190,76 +191,6 @@ def save_image(image,
|
||||
return params.filename, filename_txt, exifinfo
|
||||
|
||||
|
||||
def save_video_atomic(images, filename, video_type: str = 'none', duration: float = 2.0, loop: bool = False, interpolate: int = 0, scale: float = 1.0, pad: int = 1, change: float = 0.3):
|
||||
try:
|
||||
import cv2
|
||||
except Exception as e:
|
||||
shared.log.error(f'Save video: cv2: {e}')
|
||||
return
|
||||
os.makedirs(os.path.dirname(filename), exist_ok=True)
|
||||
if video_type.lower() == 'mp4':
|
||||
frames = images
|
||||
if interpolate > 0:
|
||||
try:
|
||||
import modules.rife
|
||||
frames = modules.rife.interpolate(images, count=interpolate, scale=scale, pad=pad, change=change)
|
||||
except Exception as e:
|
||||
shared.log.error(f'RIFE interpolation: {e}')
|
||||
errors.display(e, 'RIFE interpolation')
|
||||
video_frames = [np.array(frame) for frame in frames]
|
||||
fourcc = "mp4v"
|
||||
h, w, _c = video_frames[0].shape
|
||||
video_writer = cv2.VideoWriter(filename, fourcc=cv2.VideoWriter_fourcc(*fourcc), fps=len(frames)/duration, frameSize=(w, h))
|
||||
for i in range(len(video_frames)):
|
||||
img = cv2.cvtColor(video_frames[i], cv2.COLOR_RGB2BGR)
|
||||
video_writer.write(img)
|
||||
size = os.path.getsize(filename)
|
||||
shared.log.info(f'Save video: file="{filename}" frames={len(frames)} duration={duration} fourcc={fourcc} size={size}')
|
||||
if video_type.lower() == 'gif' or video_type.lower() == 'png':
|
||||
append = images.copy()
|
||||
image = append.pop(0)
|
||||
if loop:
|
||||
append += append[::-1]
|
||||
frames=len(append) + 1
|
||||
image.save(
|
||||
filename,
|
||||
save_all = True,
|
||||
append_images = append,
|
||||
optimize = False,
|
||||
duration = 1000.0 * duration / frames,
|
||||
loop = 0 if loop else 1,
|
||||
)
|
||||
size = os.path.getsize(filename)
|
||||
shared.log.info(f'Save video: file="{filename}" frames={len(append) + 1} duration={duration} loop={loop} size={size}')
|
||||
|
||||
|
||||
def save_video(p, images, filename = None, video_type: str = 'none', duration: float = 2.0, loop: bool = False, interpolate: int = 0, scale: float = 1.0, pad: int = 1, change: float = 0.3, sync: bool = False):
|
||||
if images is None or len(images) < 2 or video_type is None or video_type.lower() == 'none':
|
||||
return None
|
||||
image = images[0]
|
||||
if p is not None:
|
||||
seed = p.all_seeds[0] if getattr(p, 'all_seeds', None) is not None else p.seed
|
||||
prompt = p.all_prompts[0] if getattr(p, 'all_prompts', None) is not None else p.prompt
|
||||
namegen = FilenameGenerator(p, seed=seed, prompt=prompt, image=image)
|
||||
else:
|
||||
namegen = FilenameGenerator(None, seed=0, prompt='', image=image)
|
||||
if filename is None and p is not None:
|
||||
filename = namegen.apply(shared.opts.samples_filename_pattern if shared.opts.samples_filename_pattern and len(shared.opts.samples_filename_pattern) > 0 else "[seq]-[prompt_words]")
|
||||
filename = os.path.join(shared.opts.outdir_video, filename)
|
||||
filename = namegen.sequence(filename, shared.opts.outdir_video, '')
|
||||
else:
|
||||
if os.pathsep not in filename:
|
||||
filename = os.path.join(shared.opts.outdir_video, filename)
|
||||
if not filename.lower().endswith(video_type.lower()):
|
||||
filename += f'.{video_type.lower()}'
|
||||
filename = namegen.sanitize(filename)
|
||||
if not sync:
|
||||
threading.Thread(target=save_video_atomic, args=(images, filename, video_type, duration, loop, interpolate, scale, pad, change)).start()
|
||||
else:
|
||||
save_video_atomic(images, filename, video_type, duration, loop, interpolate, scale, pad, change)
|
||||
return filename
|
||||
|
||||
|
||||
def safe_decode_string(s: bytes):
|
||||
remove_prefix = lambda text, prefix: text[len(prefix):] if text.startswith(prefix) else text # pylint: disable=unnecessary-lambda-assignment
|
||||
for encoding in ['utf-8', 'utf-16', 'ascii', 'latin_1', 'cp1252', 'cp437']: # try different encodings
|
||||
|
||||
Reference in New Issue
Block a user