def get_random_start_point(): start_points = [...

Created on: May 8, 2025

Answered using O3 by Chat01

Question

def get_random_start_point():
start_points = [
'center', 'top_left', 'top_right', 'bottom_left', 'bottom_right',
'center_left', 'center_right', 'center_top', 'center_bottom'
]
start_point = random.choice(start_points)

text
if start_point == 'center': start_x = "iw/2-(iw/zoom/2)" start_y = "ih/2-(ih/zoom/2)" elif start_point == 'top_left': start_x = "0" start_y = "0" elif start_point == 'top_right': start_x = "iw-(iw/zoom)" start_y = "0" elif start_point == 'bottom_left': start_x = "0" start_y = "ih-(ih/zoom)" elif start_point == 'bottom_right': start_x = "iw-(iw/zoom)" start_y = "ih-(ih/zoom)" elif start_point == 'center_left': start_x = "0" start_y = "ih/2-(ih/zoom/2)" elif start_point == 'center_right': start_x = "iw-(iw/zoom)" start_y = "ih/2-(ih/zoom/2)" elif start_point == 'center_top': start_x = "iw/2-(iw/zoom/2)" start_y = "0" elif start_point == 'center_bottom': start_x = "iw/2-(iw/zoom/2)" start_y = "ih-(ih/zoom)" return start_x, start_y

def process_horizontal_image_fill(image_path, video_resolution, framerate, bitrate, bufsize, temp_video_folder,
filename, duration, zoom_time, center_zoom):
if center_zoom:
start_x = "iw/2-(iw/zoom/2)"
start_y = "ih/2-(ih/zoom/2)"
else:
start_x, start_y = get_random_start_point()

text
temp_video_file = os.path.join(temp_video_folder, f'temp_{filename}.mp4') subprocess.run( ['ffmpeg', '-y', '-i', image_path, '-lavfi', f'[0:v]scale={video_resolution[0]}:{video_resolution[1]},' f'boxblur=luma_radius=min(h\,w)/20:luma_power=1:chroma_radius=min(cw\,ch)/20:chroma_power=1[bg];' f'[bg]scale={video_resolution[0]}:{video_resolution[1]}[bg_scaled];' f'[0:v]scale=1920:1080[ov];' f'[ov]crop=1720:1080:100:0[zv];' f'[bg_scaled][zv]overlay=(W-w)/2:(H-h)/2[full];' f'[full]scale=12000:-1[scaled_full];' f'[scaled_full]zoompan=z=\'min(zoom+0.0005,1.5)\':x=\'{start_x}\':y=\'{start_y}\':d={zoom_time},trim=duration={duration},' f'scale={video_resolution[0]}:{video_resolution[1]}', '-r', str(framerate), '-c:v', 'libx264', '-preset', 'ultrafast', '-b:v', f'{bitrate}k', '-maxrate', f'{bitrate}k', '-bufsize', f'{bufsize}k', temp_video_file, '-pix_fmt', 'yuv420p'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) return temp_video_file

def process_vertical_image(image_path, video_resolution, framerate, bitrate, bufsize, temp_video_folder, filename,
duration, zoom_time, center_zoom):
if center_zoom:
start_x = "iw/2-(iw/zoom/2)"
start_y = "ih/2-(ih/zoom/2)"
else:
start_x, start_y = get_random_start_point()

text
temp_video_file = os.path.join(temp_video_folder, f'temp_{filename}.mp4') subprocess.run( ['ffmpeg', '-y', '-i', image_path, '-lavfi', f'[0:v]scale={video_resolution[0]}:{video_resolution[1]},' f'boxblur=luma_radius=min(h\,w)/20:luma_power=1:chroma_radius=min(cw\,ch)/20:chroma_power=1[bg];' f'[bg]scale={video_resolution[0]}:{video_resolution[1]}[bg_scaled];' f'[0:v]scale=-1:{video_resolution[1]}[ov];' f'[bg_scaled][ov]overlay=(W-w)/2:(H-h)/2[full];' f'[full]scale=12000:-1[scaled_full];' f'[scaled_full]zoompan=z=\'min(zoom+0.0005,1.5)\':x=\'{start_x}\':y=\'{start_y}\':d={zoom_time},trim=duration={duration},' f'scale={video_resolution[0]}:{video_resolution[1]}', '-r', str(framerate), '-c:v', 'libx264', '-preset', 'ultrafast', '-b:v', f'{bitrate}k', '-maxrate', f'{bitrate}k', '-bufsize', f'{bufsize}k', temp_video_file, '-pix_fmt', 'yuv420p'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) return temp_video_file

используя эти функции - напиши мне готовый код, который будет заходить в мою папку D:\Downloads\Cat - считывать все фотофайлы различных разрешений - и на основе моих выше функций создавать видео сегменты через ффмпег и сабпроцесс. длина 10 секунд. битрейт 8mbps. разрешение full hd
положение зума - рандомное
пиши полный код.

Thought

Writing Python Code for Video Generation

The user wants me to create functional Python code that will process images from the folder "D:\Downloads\Cat," detect whether each image is horizontal or vertical using its dimensions, and then use the provided functions to generate video segments using FFmpeg and subprocess. The video should be full HD, 10 seconds long, with a bitrate of 8mbps. I'll generate the full code for them by constructing appropriate image detection and processing steps within the request specifications.

Thought for 23 seconds

Answer

python
import os import glob import random import subprocess from pathlib import Path from PIL import Image def get_random_start_point() -> tuple[str, str]: """ Случайно выбирает стартовую точку для эффекта zoom‑pan в FFmpeg. Возвращает кортеж строк‑выражений (start_x, start_y), понятных FFmpeg‑фильтру. """ start_points = [ "center", "top_left", "top_right", "bottom_left", "bottom_right", "center_left", "center_right", "center_top", "center_bottom" ] start_point = random.choice(start_points) if start_point == "center": start_x = "iw/2-(iw/zoom/2)" start_y = "ih/2-(ih/zoom/2)" elif start_point == "top_left": start_x, start_y = "0", "0" elif start_point == "top_right": start_x, start_y = "iw-(iw/zoom)", "0" elif start_point == "bottom_left": start_x, start_y = "0", "ih-(ih/zoom)" elif start_point == "bottom_right": start_x, start_y = "iw-(iw/zoom)", "ih-(ih/zoom)" elif start_point == "center_left": start_x, start_y = "0", "ih/2-(ih/zoom/2)" elif start_point == "center_right": start_x, start_y = "iw-(iw/zoom)", "ih/2-(ih/zoom/2)" elif start_point == "center_top": start_x, start_y = "iw/2-(iw/zoom/2)", "0" elif start_point == "center_bottom": start_x, start_y = "iw/2-(iw/zoom/2)", "ih-(ih/zoom)" else: # на всякий случай start_x, start_y = "iw/2-(iw/zoom/2)", "ih/2-(ih/zoom/2)" return start_x, start_y def process_horizontal_image_fill( image_path: str, video_resolution: tuple[int, int], framerate: int, bitrate: int, bufsize: int, temp_video_folder: str, filename: str, duration: int, zoom_time: int, center_zoom: bool, ) -> str: """Создать видео из горизонтального изображения, заполнив фон блюром.""" if center_zoom: start_x = "iw/2-(iw/zoom/2)" start_y = "ih/2-(ih/zoom/2)" else: start_x, start_y = get_random_start_point() temp_video_file = os.path.join(temp_video_folder, f"{filename}.mp4") subprocess.run( [ "ffmpeg", "-y", "-i", image_path, "-lavfi", ( # 0:v → [bg] размытый фон f"[0:v]scale={video_resolution[0]}:{video_resolution[1]}," f"boxblur=luma_radius=min(h\\,w)/20:luma_power=1:" f"chroma_radius=min(cw\\,ch)/20:chroma_power=1[bg];" # фон до нужного разрешения f"[bg]scale={video_resolution[0]}:{video_resolution[1]}[bg_scaled];" # оригинал в Full HD f"[0:v]scale=1920:1080[ov];" # опционально кадрируем «лишнее» (пример crop) f"[ov]crop=1720:1080:100:0[zv];" # накладываем на фон f"[bg_scaled][zv]overlay=(W-w)/2:(H-h)/2[full];" # увеличиваем «полотно» для zoom‑pan (работает быстрее, когда исходник крупнее) f"[full]scale=12000:-1[scaled_full];" # сам зум‑пан + trim до указанной длительности f"[scaled_full]zoompan=" f"z='min(zoom+0.0005,1.5)':" f"x='{start_x}':y='{start_y}':" f"d={zoom_time}," f"trim=duration={duration}," f"scale={video_resolution[0]}:{video_resolution[1]}" ), "-r", str(framerate), "-c:v", "libx264", "-preset", "ultrafast", "-b:v", f"{bitrate}k", "-maxrate", f"{bitrate}k", "-bufsize", f"{bufsize}k", "-pix_fmt", "yuv420p", temp_video_file, ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, ) return temp_video_file def process_vertical_image( image_path: str, video_resolution: tuple[int, int], framerate: int, bitrate: int, bufsize: int, temp_video_folder: str, filename: str, duration: int, zoom_time: int, center_zoom: bool, ) -> str: """Создать видео из вертикального изображения, заполнив фон блюром.""" if center_zoom: start_x = "iw/2-(iw/zoom/2)" start_y = "ih/2-(ih/zoom/2)" else: start_x, start_y = get_random_start_point() temp_video_file = os.path.join(temp_video_folder, f"{filename}.mp4") subprocess.run( [ "ffmpeg", "-y", "-i", image_path, "-lavfi", ( # 0:v → [bg] размытый фон f"[0:v]scale={video_resolution[0]}:{video_resolution[1]}," f"boxblur=luma_radius=min(h\\,w)/20:luma_power=1:" f"chroma_radius=min(cw\\,ch)/20:chroma_power=1[bg];" # фон до нужного разрешения f"[bg]scale={video_resolution[0]}:{video_resolution[1]}[bg_scaled];" # оригинал доводим по высоте f"[0:v]scale=-1:{video_resolution[1]}[ov];" # накладываем на фон f"[bg_scaled][ov]overlay=(W-w)/2:(H-h)/2[full];" # увеличиваем «полотно» для zoom‑pan f"[full]scale=12000:-1[scaled_full];" # zoom‑pan + trim f"[scaled_full]zoompan=" f"z='min(zoom+0.0005,1.5)':" f"x='{start_x}':y='{start_y}':" f"d={zoom_time}," f"trim=duration={duration}," f"scale={video_resolution[0]}:{video_resolution[1]}" ), "-r", str(framerate), "-c:v", "libx264", "-preset", "ultrafast", "-b:v", f"{bitrate}k", "-maxrate", f"{bitrate}k", "-bufsize", f"{bufsize}k", "-pix_fmt", "yuv420p", temp_video_file, ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, ) return temp_video_file def create_videos_from_folder( image_folder: str, *, duration: int = 10, framerate: int = 30, bitrate_kbps: int = 8000, resolution: tuple[int, int] = (1920, 1080), ) -> None: """Проходит по всем изображениям в папке и создаёт видео‑сегменты.""" image_folder = os.path.abspath(image_folder) output_dir = os.path.join(image_folder, "videos") os.makedirs(output_dir, exist_ok=True) bufsize = bitrate_kbps * 2 # рекомендация: x2 относительно maxrate zoom_time = duration * framerate # FFmpeg ждёт количество кадров # поддерживаемые расширения patterns = ("*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.tif", "*.tiff", "*.webp") image_files: list[Path] = [] for pattern in patterns: image_files.extend(Path(image_folder).rglob(pattern)) if not image_files: print("В указанной папке не найдено изображений.") return for img_path in image_files: # Определяем ориентацию with Image.open(img_path) as img: width, height = img.size filename = img_path.stem try: if width >= height: result = process_horizontal_image_fill( str(img_path), resolution, framerate, bitrate_kbps, bufsize, output_dir, filename, duration, zoom_time, center_zoom=False, ) else: result = process_vertical_image( str(img_path), resolution, framerate, bitrate_kbps, bufsize, output_dir, filename, duration, zoom_time, center_zoom=False, ) print(f"✅ Создано видео: {result}") except subprocess.CalledProcessError as err: print(f"❌ Ошибка FFmpeg при обработке {img_path.name}:\n{err.stderr.decode('utf‑8')}") if __name__ == "__main__": # Папка с изображениями IMAGE_DIR = r"D:\Downloads\Cat" create_videos_from_folder(IMAGE_DIR)

Кратко о работе скрипта

  1. Сканирует D:\Downloads\Cat (вложенные папки тоже) на все популярные форматы изображений.
  2. Определяет ориентацию кадра через Pillow (ширина ≥ высота → горизонтальное).
  3. Вызывает соответствующую функцию (process_horizontal_image_fill или process_vertical_image).
  4. FFmpeg создаёт 10‑секундный ролик Full HD, битрейт ≈ 8 Mbps, с плавным zoom‑pan из случайной точки.
  5. Готовые видео складываются в подпапку videos внутри исходной директории.

Важно: убедитесь, что FFmpeg доступен в PATH, и установлен пакет Pillow
(pip install pillow).

Share this Q&A