update addons (for 5.2)

This commit is contained in:
Nathan
2026-07-14 14:44:58 -06:00
parent a232ea1c9c
commit e3310263f3
246 changed files with 21097 additions and 9607 deletions
@@ -0,0 +1,166 @@
"""Locate an ffmpeg executable for BasedPlayblast."""
from __future__ import annotations
import os
import shutil
import subprocess
import sys
import tempfile
import urllib.request
import zipfile
_FFMPEG_BOOTSTRAP_ATTEMPTED = False
# Official Windows essentials build recommended for Blender-adjacent tooling.
_FFMPEG_ESSENTIALS_URL = (
"https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip"
)
def addon_root() -> str:
return os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
def bundled_ffmpeg_path() -> str:
return os.path.join(addon_root(), "tools", "ffmpeg.exe")
def iter_blender_bundled_ffmpeg_paths():
"""Yield likely paths to ffmpeg shipped with this Blender install."""
try:
import bpy # type: ignore
binary = bpy.app.binary_path
if not binary:
return
binary_dir = os.path.dirname(binary)
version = f"{bpy.app.version[0]}.{bpy.app.version[1]}"
names = ("ffmpeg.exe", "ffmpeg") if sys.platform == "win32" else ("ffmpeg",)
roots = [binary_dir]
parent = os.path.dirname(binary_dir)
if parent:
roots.append(parent)
if sys.platform == "darwin":
resources = os.path.join(os.path.dirname(binary_dir), "Resources")
if os.path.isdir(resources):
roots.append(resources)
roots.append(os.path.join(resources, version))
subdirs = (
"",
version,
"ffmpeg",
os.path.join(version, "ffmpeg"),
os.path.join(version, "ffmpeg", "bin"),
os.path.join("ffmpeg", "bin"),
)
seen = set()
for root in roots:
for sub in subdirs:
for name in names:
path = os.path.normpath(
os.path.join(root, sub, name) if sub else os.path.join(root, name)
)
if path not in seen:
seen.add(path)
yield path
except Exception:
return
def _bootstrap_bundled_ffmpeg() -> str | None:
"""Download ffmpeg essentials into addon tools/ when no executable is found."""
global _FFMPEG_BOOTSTRAP_ATTEMPTED
if _FFMPEG_BOOTSTRAP_ATTEMPTED or sys.platform != "win32":
return None
_FFMPEG_BOOTSTRAP_ATTEMPTED = True
target = bundled_ffmpeg_path()
if os.path.isfile(target):
return target
tools_dir = os.path.dirname(target)
os.makedirs(tools_dir, exist_ok=True)
print("[BasedPlayblast] No ffmpeg found; downloading essentials build to addon tools/...")
try:
with tempfile.TemporaryDirectory(prefix="basedplayblast_ffmpeg_") as tmp_dir:
zip_path = os.path.join(tmp_dir, "ffmpeg-essentials.zip")
with urllib.request.urlopen(_FFMPEG_ESSENTIALS_URL, timeout=120) as response:
with open(zip_path, "wb") as handle:
shutil.copyfileobj(response, handle)
with zipfile.ZipFile(zip_path) as archive:
member = next(
(name for name in archive.namelist() if name.endswith("/bin/ffmpeg.exe")),
None,
)
if not member:
print("[BasedPlayblast] ffmpeg bootstrap failed: ffmpeg.exe not found in archive")
return None
archive.extract(member, tmp_dir)
extracted = os.path.join(tmp_dir, member.replace("/", os.sep))
shutil.copy2(extracted, target)
if os.path.isfile(target):
print(f"[BasedPlayblast] Installed bundled ffmpeg: {target}")
return target
except Exception as exc:
print(f"[BasedPlayblast] ffmpeg bootstrap failed: {exc}")
return None
def resolve_ffmpeg_path() -> str:
"""Resolve ffmpeg: addon override, addon bundle, Blender, bootstrap, then PATH."""
try:
import bpy # type: ignore
for addon_name in (
"BasedPlayblast",
"basedplayblast",
"bl_ext.basedplayblast",
"bl_ext.user_local.basedplayblast",
):
prefs = bpy.context.preferences.addons.get(addon_name)
if not prefs or not prefs.preferences:
continue
if hasattr(prefs.preferences, "ffmpeg_path"):
custom = getattr(prefs.preferences, "ffmpeg_path", "").strip()
if custom and os.path.isfile(custom):
return custom
except Exception:
pass
bundled = bundled_ffmpeg_path()
if os.path.isfile(bundled):
return bundled
for candidate in iter_blender_bundled_ffmpeg_paths():
if os.path.isfile(candidate):
return candidate
bootstrapped = _bootstrap_bundled_ffmpeg()
if bootstrapped and os.path.isfile(bootstrapped):
return bootstrapped
exe = shutil.which("ffmpeg")
if exe:
print(
f"[BasedPlayblast] Warning: no addon-bundled ffmpeg; falling back to PATH: {exe}"
)
return exe
for candidate in (
r"C:\ProgramData\chocolatey\bin\ffmpeg.exe",
r"C:\Program Files\ffmpeg\bin\ffmpeg.exe",
r"C:\Program Files (x86)\ffmpeg\bin\ffmpeg.exe",
r"C:\ffmpeg\bin\ffmpeg.exe",
):
if candidate and os.path.isfile(candidate):
return candidate
return "ffmpeg"