fixed imports again

This commit is contained in:
pacnpal
2024-11-18 01:21:40 +00:00
parent d03e8dc8e8
commit fc06e54d8a
37 changed files with 879 additions and 882 deletions

View File

@@ -18,33 +18,33 @@ logging.basicConfig(
logger = logging.getLogger("VideoArchiver")
# Import components after logging is configured
try:
#try:
# Try relative imports first
from .ffmpeg_manager import FFmpegManager
from .video_analyzer import VideoAnalyzer
from .gpu_detector import GPUDetector
from .encoder_params import EncoderParams
from .ffmpeg_downloader import FFmpegDownloader
from .exceptions import (
FFmpegError,
DownloadError,
VerificationError,
EncodingError,
AnalysisError,
GPUError,
HardwareAccelerationError,
FFmpegNotFoundError,
FFprobeError,
CompressionError,
FormatError,
PermissionError,
TimeoutError,
ResourceError,
QualityError,
AudioError,
BitrateError,
)
except ImportError:
from .ffmpeg_manager import FFmpegManager
from .video_analyzer import VideoAnalyzer
from .gpu_detector import GPUDetector
from .encoder_params import EncoderParams
from .ffmpeg_downloader import FFmpegDownloader
from .exceptions import (
FFmpegError,
DownloadError,
VerificationError,
EncodingError,
AnalysisError,
GPUError,
HardwareAccelerationError,
FFmpegNotFoundError,
FFprobeError,
CompressionError,
FormatError,
PermissionError,
TimeoutError,
ResourceError,
QualityError,
AudioError,
BitrateError,
)
#except ImportError:
# Fall back to absolute imports if relative imports fail
# from videoarchiver.ffmpeg.ffmpeg_manager import FFmpegManager
# from videoarchiver.ffmpeg.video_analyzer import VideoAnalyzer
@@ -52,24 +52,24 @@ except ImportError:
# from videoarchiver.ffmpeg.encoder_params import EncoderParams
# from videoarchiver.ffmpeg.ffmpeg_downloader import FFmpegDownloader
# from videoarchiver.ffmpeg.exceptions import (
FFmpegError,
DownloadError,
VerificationError,
EncodingError,
AnalysisError,
GPUError,
HardwareAccelerationError,
FFmpegNotFoundError,
FFprobeError,
CompressionError,
FormatError,
PermissionError,
TimeoutError,
ResourceError,
QualityError,
AudioError,
BitrateError,
)
# FFmpegError,
# DownloadError,
# VerificationError,
# EncodingError,
# AnalysisError,
# GPUError,
# HardwareAccelerationError,
# FFmpegNotFoundError,
# FFprobeError,
# CompressionError,
# FormatError,
# PermissionError,
# TimeoutError,
# ResourceError,
# QualityError,
# AudioError,
# BitrateError,
# )
class FFmpeg:

View File

@@ -5,26 +5,26 @@ import os
from pathlib import Path
from typing import Dict, Optional
try:
#try:
# Try relative imports first
from .exceptions import (
FFmpegError,
DownloadError,
VerificationError,
PermissionError,
FFmpegNotFoundError
)
from .ffmpeg_downloader import FFmpegDownloader
from .verification_manager import VerificationManager
except ImportError:
from .exceptions import (
FFmpegError,
DownloadError,
VerificationError,
PermissionError,
FFmpegNotFoundError
)
from .ffmpeg_downloader import FFmpegDownloader
from .verification_manager import VerificationManager
#except ImportError:
# Fall back to absolute imports if relative imports fail
# from videoarchiver.ffmpeg.exceptions import (
FFmpegError,
DownloadError,
VerificationError,
PermissionError,
FFmpegNotFoundError
)
# FFmpegError,
# DownloadError,
# VerificationError,
# PermissionError,
# FFmpegNotFoundError
# )
# from videoarchiver.ffmpeg.ffmpeg_downloader import FFmpegDownloader
# from videoarchiver.ffmpeg.verification_manager import VerificationManager

View File

@@ -4,10 +4,10 @@ import os
import logging
from typing import Dict, Any
try:
#try:
# Try relative imports first
from .exceptions import CompressionError, QualityError, BitrateError
except ImportError:
from .exceptions import CompressionError, QualityError, BitrateError
#except ImportError:
# Fall back to absolute imports if relative imports fail
# from videoarchiver.ffmpeg.exceptions import CompressionError, QualityError, BitrateError

View File

@@ -16,12 +16,13 @@ from typing import Optional, Dict, List
import time
import lzma
try:
# Try relative imports first
from .exceptions import DownloadError
except ImportError:
# Fall back to absolute imports if relative imports fail
# from videoarchiver.ffmpeg.exceptions import DownloadError
# try:
# Try relative imports first
from .exceptions import DownloadError
# except ImportError:
# Fall back to absolute imports if relative imports fail
# from videoarchiver.ffmpeg.exceptions import DownloadError
logger = logging.getLogger("VideoArchiver")
@@ -249,14 +250,16 @@ class FFmpegDownloader:
binary_files = [
f
for f in zip_ref.namelist()
if f.endswith(f"/bin/{binary_name}") or f.endswith(f"\\bin\\{binary_name}")
if f.endswith(f"/bin/{binary_name}")
or f.endswith(f"\\bin\\{binary_name}")
]
if not binary_files:
# Fallback to old structure
binary_files = [
f
for f in zip_ref.namelist()
if f.endswith(f"/{binary_name}") or f.endswith(f"\\{binary_name}")
if f.endswith(f"/{binary_name}")
or f.endswith(f"\\{binary_name}")
]
if not binary_files:
raise DownloadError(f"{binary_name} not found in archive")
@@ -271,10 +274,10 @@ class FFmpegDownloader:
"""Extract from tar archive (Linux/macOS)"""
try:
# First decompress the .xz file in chunks to prevent blocking
decompressed_path = archive_path.with_suffix('')
decompressed_path = archive_path.with_suffix("")
chunk_size = 1024 * 1024 # 1MB chunks
with lzma.open(archive_path, 'rb') as compressed:
with open(decompressed_path, 'wb') as decompressed:
with lzma.open(archive_path, "rb") as compressed:
with open(decompressed_path, "wb") as decompressed:
while True:
chunk = compressed.read(chunk_size)
if not chunk:
@@ -289,12 +292,16 @@ class FFmpegDownloader:
for binary_name in binary_names:
# BtbN's builds have binaries in bin directory
binary_files = [
f for f in tar_ref.getnames() if f.endswith(f"/bin/{binary_name}")
f
for f in tar_ref.getnames()
if f.endswith(f"/bin/{binary_name}")
]
if not binary_files:
# Fallback to old structure
binary_files = [
f for f in tar_ref.getnames() if f.endswith(f"/{binary_name}")
f
for f in tar_ref.getnames()
if f.endswith(f"/{binary_name}")
]
if not binary_files:
raise DownloadError(f"{binary_name} not found in archive")
@@ -304,9 +311,11 @@ class FFmpegDownloader:
tar_ref.extract(member, temp_dir)
extracted_path = Path(temp_dir) / binary_files[0]
target_path = self.base_dir / binary_name
# Copy file in chunks
with open(extracted_path, 'rb') as src, open(target_path, 'wb') as dst:
with open(extracted_path, "rb") as src, open(
target_path, "wb"
) as dst:
while True:
chunk = src.read(chunk_size)
if not chunk:
@@ -314,7 +323,7 @@ class FFmpegDownloader:
dst.write(chunk)
# Allow other tasks to run
time.sleep(0)
logger.info(f"Extracted {binary_name} to {target_path}")
# Clean up decompressed file
@@ -350,7 +359,7 @@ class FFmpegDownloader:
timeout=5,
text=True,
check=False, # Don't raise on non-zero return code
env={"PATH": os.environ.get("PATH", "")} # Ensure PATH is set
env={"PATH": os.environ.get("PATH", "")}, # Ensure PATH is set
)
except subprocess.TimeoutExpired:
logger.error("FFmpeg verification timed out")
@@ -368,7 +377,7 @@ class FFmpegDownloader:
timeout=5,
text=True,
check=False, # Don't raise on non-zero return code
env={"PATH": os.environ.get("PATH", "")} # Ensure PATH is set
env={"PATH": os.environ.get("PATH", "")}, # Ensure PATH is set
)
except subprocess.TimeoutExpired:
logger.error("FFprobe verification timed out")

View File

@@ -6,32 +6,29 @@ import multiprocessing
from pathlib import Path
from typing import Dict, Any, Optional
try:
# Try relative imports first
from .exceptions import (
FFmpegError,
AnalysisError,
FFmpegNotFoundError
)
from .gpu_detector import GPUDetector
from .video_analyzer import VideoAnalyzer
from .encoder_params import EncoderParams
from .process_manager import ProcessManager
from .verification_manager import VerificationManager
from .binary_manager import BinaryManager
except ImportError:
# Fall back to absolute imports if relative imports fail
# from videoarchiver.ffmpeg.exceptions import (
FFmpegError,
AnalysisError,
FFmpegNotFoundError
)
# from videoarchiver.ffmpeg.gpu_detector import GPUDetector
# from videoarchiver.ffmpeg.video_analyzer import VideoAnalyzer
# from videoarchiver.ffmpeg.encoder_params import EncoderParams
# from videoarchiver.ffmpeg.process_manager import ProcessManager
# from videoarchiver.ffmpeg.verification_manager import VerificationManager
# from videoarchiver.ffmpeg.binary_manager import BinaryManager
# try:
# Try relative imports first
from .exceptions import FFmpegError, AnalysisError, FFmpegNotFoundError
from .gpu_detector import GPUDetector
from .video_analyzer import VideoAnalyzer
from .encoder_params import EncoderParams
from .process_manager import ProcessManager
from .verification_manager import VerificationManager
from .binary_manager import BinaryManager
# except ImportError:
# Fall back to absolute imports if relative imports fail
# from videoarchiver.ffmpeg.exceptions import (
# FFmpegError,
# AnalysisError,
# FFmpegNotFoundError
# )
# from videoarchiver.ffmpeg.gpu_detector import GPUDetector
# from videoarchiver.ffmpeg.video_analyzer import VideoAnalyzer
# from videoarchiver.ffmpeg.encoder_params import EncoderParams
# from videoarchiver.ffmpeg.process_manager import ProcessManager
# from videoarchiver.ffmpeg.verification_manager import VerificationManager
# from videoarchiver.ffmpeg.binary_manager import BinaryManager
logger = logging.getLogger("VideoArchiver")
@@ -45,7 +42,7 @@ class FFmpegManager:
module_dir = Path(__file__).parent.parent
self.base_dir = module_dir / "bin"
logger.info(f"FFmpeg base directory: {self.base_dir}")
# Initialize managers
self.process_manager = ProcessManager()
self.verification_manager = VerificationManager(self.process_manager)
@@ -53,15 +50,15 @@ class FFmpegManager:
base_dir=self.base_dir,
system=platform.system(),
machine=platform.machine(),
verification_manager=self.verification_manager
verification_manager=self.verification_manager,
)
# Initialize components
self.gpu_detector = GPUDetector(self.get_ffmpeg_path)
self.video_analyzer = VideoAnalyzer(self.get_ffmpeg_path)
self._gpu_info = self.gpu_detector.detect_gpu()
self._cpu_cores = multiprocessing.cpu_count()
# Initialize encoder params
self.encoder_params = EncoderParams(self._cpu_cores, self._gpu_info)
@@ -87,22 +84,24 @@ class FFmpegManager:
raise
raise AnalysisError(f"Failed to analyze video: {e}")
def get_compression_params(self, input_path: str, target_size_mb: int) -> Dict[str, str]:
def get_compression_params(
self, input_path: str, target_size_mb: int
) -> Dict[str, str]:
"""Get optimal compression parameters for the given input file"""
try:
# Analyze video first
video_info = self.analyze_video(input_path)
if not video_info:
raise AnalysisError("Failed to analyze video")
# Convert target size to bytes
target_size_bytes = target_size_mb * 1024 * 1024
# Get encoding parameters
params = self.encoder_params.get_params(video_info, target_size_bytes)
logger.info(f"Generated compression parameters: {params}")
return params
except Exception as e:
logger.error(f"Failed to get compression parameters: {e}")
if isinstance(e, AnalysisError):
@@ -113,7 +112,7 @@ class FFmpegManager:
"preset": "medium",
"crf": "23",
"c:a": "aac",
"b:a": "128k"
"b:a": "128k",
}
def get_ffmpeg_path(self) -> str:

View File

@@ -6,22 +6,23 @@ import subprocess
from pathlib import Path
from typing import Dict, List, Optional
try:
# Try relative imports first
from .exceptions import (
TimeoutError,
VerificationError,
EncodingError,
handle_ffmpeg_error
)
except ImportError:
# Fall back to absolute imports if relative imports fail
# from videoarchiver.ffmpeg.exceptions import (
TimeoutError,
VerificationError,
EncodingError,
handle_ffmpeg_error
)
# try:
# Try relative imports first
from .exceptions import (
TimeoutError,
VerificationError,
EncodingError,
handle_ffmpeg_error,
)
# except ImportError:
# Fall back to absolute imports if relative imports fail
# from videoarchiver.ffmpeg.exceptions import (
# TimeoutError,
# VerificationError,
# EncodingError,
# handle_ffmpeg_error
# )
logger = logging.getLogger("FFmpegVerification")
@@ -33,18 +34,15 @@ class VerificationManager:
self.process_manager = process_manager
def verify_ffmpeg(
self,
ffmpeg_path: Path,
ffprobe_path: Path,
gpu_info: Dict[str, bool]
self, ffmpeg_path: Path, ffprobe_path: Path, gpu_info: Dict[str, bool]
) -> None:
"""Verify FFmpeg functionality with comprehensive checks
Args:
ffmpeg_path: Path to FFmpeg binary
ffprobe_path: Path to FFprobe binary
gpu_info: Dictionary of GPU availability
Raises:
VerificationError: If verification fails
TimeoutError: If verification times out
@@ -53,13 +51,13 @@ class VerificationManager:
try:
# Check FFmpeg version
self._verify_ffmpeg_version(ffmpeg_path)
# Check FFprobe version
self._verify_ffprobe_version(ffprobe_path)
# Check FFmpeg capabilities
self._verify_ffmpeg_capabilities(ffmpeg_path, gpu_info)
logger.info("FFmpeg verification completed successfully")
except Exception as e:
@@ -72,8 +70,7 @@ class VerificationManager:
"""Verify FFmpeg version"""
try:
result = self._execute_command(
[str(ffmpeg_path), "-version"],
"FFmpeg version check"
[str(ffmpeg_path), "-version"], "FFmpeg version check"
)
logger.info(f"FFmpeg version: {result.stdout.split()[2]}")
except Exception as e:
@@ -83,34 +80,32 @@ class VerificationManager:
"""Verify FFprobe version"""
try:
result = self._execute_command(
[str(ffprobe_path), "-version"],
"FFprobe version check"
[str(ffprobe_path), "-version"], "FFprobe version check"
)
logger.info(f"FFprobe version: {result.stdout.split()[2]}")
except Exception as e:
raise VerificationError(f"FFprobe version check failed: {e}")
def _verify_ffmpeg_capabilities(
self,
ffmpeg_path: Path,
gpu_info: Dict[str, bool]
self, ffmpeg_path: Path, gpu_info: Dict[str, bool]
) -> None:
"""Verify FFmpeg capabilities and encoders"""
try:
result = self._execute_command(
[str(ffmpeg_path), "-hide_banner", "-encoders"],
"FFmpeg capabilities check"
"FFmpeg capabilities check",
)
# Verify required encoders
required_encoders = self._get_required_encoders(gpu_info)
available_encoders = result.stdout.lower()
missing_encoders = [
encoder for encoder in required_encoders
encoder
for encoder in required_encoders
if encoder not in available_encoders
]
if missing_encoders:
logger.warning(f"Missing encoders: {', '.join(missing_encoders)}")
if "libx264" in missing_encoders:
@@ -122,17 +117,12 @@ class VerificationManager:
raise VerificationError(f"FFmpeg capabilities check failed: {e}")
def _execute_command(
self,
command: List[str],
operation: str,
timeout: int = 10
self, command: List[str], operation: str, timeout: int = 10
) -> subprocess.CompletedProcess:
"""Execute a command with proper error handling"""
try:
result = self.process_manager.execute_command(
command,
timeout=timeout,
check=False
command, timeout=timeout, check=False
)
if result.returncode != 0:
@@ -152,14 +142,14 @@ class VerificationManager:
def _get_required_encoders(self, gpu_info: Dict[str, bool]) -> List[str]:
"""Get list of required encoders based on GPU availability"""
required_encoders = ["libx264"]
if gpu_info["nvidia"]:
required_encoders.append("h264_nvenc")
elif gpu_info["amd"]:
required_encoders.append("h264_amf")
elif gpu_info["intel"]:
required_encoders.append("h264_qsv")
return required_encoders
def verify_binary_permissions(self, binary_path: Path) -> None: