90 lines
4.6 KiB
Python
90 lines
4.6 KiB
Python
# ffmpeg_path_resolver.py
|
|
import os
|
|
import subprocess
|
|
import configparser
|
|
from .node_logger import log_node_info, log_node_success, log_node_warning, log_node_error, log_node_debug
|
|
|
|
_CACHED_FFMPEG_PATH = None
|
|
_CACHED_FFMPEG_SOURCE_TYPE = None # Тип джерела: "config", "local_bin", "system_path", "fallback"
|
|
|
|
# Використовуємо фіксований префікс для логів цього модуля
|
|
RESOLVER_LOG_PREFIX = "FFmpegPathResolver"
|
|
|
|
def _test_ffmpeg_executable(path_to_test):
|
|
if not path_to_test: return False
|
|
try:
|
|
log_node_debug(RESOLVER_LOG_PREFIX, f"Testing ffmpeg at: {path_to_test}")
|
|
subprocess.run([path_to_test, '-version'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=5, check=True)
|
|
return True
|
|
except Exception:
|
|
return False
|
|
|
|
def initialize_ffmpeg_path_and_log(package_root_directory):
|
|
global _CACHED_FFMPEG_PATH, _CACHED_FFMPEG_SOURCE_TYPE
|
|
if _CACHED_FFMPEG_PATH is not None: # Вже ініціалізовано
|
|
return
|
|
|
|
ffmpeg_command_name = "ffmpeg"
|
|
determined_path = None
|
|
source_type = "unknown"
|
|
|
|
# 1. Config file
|
|
config_file_path = os.path.join(package_root_directory, "ffmpeg_config.ini")
|
|
path_from_config_ini = None
|
|
if os.path.exists(config_file_path):
|
|
try:
|
|
config = configparser.ConfigParser(); config.read(config_file_path)
|
|
if 'FFMPEG' in config and 'custom_ffmpeg_path' in config['FFMPEG']:
|
|
configured_value = config['FFMPEG']['custom_ffmpeg_path'].strip()
|
|
if configured_value: path_from_config_ini = configured_value
|
|
except Exception as e_cfg:
|
|
log_node_warning(RESOLVER_LOG_PREFIX, f"Error reading ffmpeg_config.ini: {e_cfg}.")
|
|
|
|
if path_from_config_ini:
|
|
abs_path = os.path.abspath(os.path.join(package_root_directory, path_from_config_ini) if not os.path.isabs(path_from_config_ini) else path_from_config_ini)
|
|
potential_path = None
|
|
if os.path.isdir(abs_path): potential_path = os.path.join(abs_path, ffmpeg_command_name)
|
|
elif os.path.isfile(abs_path) and abs_path.lower().endswith(ffmpeg_command_name): potential_path = abs_path
|
|
|
|
if _test_ffmpeg_executable(potential_path):
|
|
determined_path = potential_path
|
|
source_type = "config"
|
|
log_node_success(RESOLVER_LOG_PREFIX, f"Using ffmpeg from configured path: {determined_path}")
|
|
else:
|
|
log_node_warning(RESOLVER_LOG_PREFIX, f"ffmpeg not working at configured path '{potential_path or abs_path}'. Checking other locations.")
|
|
# source_type залишається "unknown", щоб логіка нижче визначила його правильно
|
|
|
|
# 2. Local node directory (if not found via config or config path was empty/invalid)
|
|
if not determined_path:
|
|
local_path = os.path.join(package_root_directory, "ffmpeg_bin", ffmpeg_command_name)
|
|
if _test_ffmpeg_executable(local_path):
|
|
determined_path = local_path
|
|
source_type = "local_bin"
|
|
log_node_success(RESOLVER_LOG_PREFIX, f"Using ffmpeg from local 'ffmpeg_bin': {determined_path}")
|
|
else:
|
|
log_node_info(RESOLVER_LOG_PREFIX, f"ffmpeg not in local 'ffmpeg_bin' or not working. Checking system PATH.")
|
|
# source_type залишається "unknown" або попереднім, якщо config був, але не спрацював
|
|
|
|
# 3. System PATH (if not found yet)
|
|
if not determined_path:
|
|
if _test_ffmpeg_executable(ffmpeg_command_name):
|
|
determined_path = ffmpeg_command_name
|
|
source_type = "system_path"
|
|
log_node_info(RESOLVER_LOG_PREFIX, f"Using ffmpeg from system PATH: '{determined_path}'")
|
|
else:
|
|
log_node_error(RESOLVER_LOG_PREFIX, f"ffmpeg ('{ffmpeg_command_name}') also not found or not working in system PATH.")
|
|
determined_path = ffmpeg_command_name # Fallback
|
|
source_type = "fallback"
|
|
|
|
_CACHED_FFMPEG_PATH = determined_path
|
|
_CACHED_FFMPEG_SOURCE_TYPE = source_type
|
|
|
|
|
|
def get_ffmpeg_path():
|
|
global _CACHED_FFMPEG_PATH
|
|
if _CACHED_FFMPEG_PATH is None:
|
|
# Ця ситуація не повинна виникати, якщо initialize_ffmpeg_path_and_log викликано з __init__.py пакету
|
|
log_node_error("FFmpegPath", "FATAL: get_ffmpeg_path() called before path was initialized!")
|
|
# Повертаємо дефолт, але це ознака проблеми в порядку ініціалізації
|
|
return "ffmpeg"
|
|
return _CACHED_FFMPEG_PATH |