feat: Bump version to 0.2.9, enhance frame class extraction and add build script

This commit is contained in:
sha
2025-12-27 04:02:32 +00:00
parent a2d5fa8dde
commit 9877be17a3
8 changed files with 53 additions and 10 deletions
+15
View File
@@ -51,11 +51,21 @@ FRAME_CLASSES = {
"typical_widths": [640, 704, 720],
"description": "Standard Definition (SD) - DVD quality",
},
"480i": {
"nominal_height": 480,
"typical_widths": [640, 704, 720],
"description": "Standard Definition (SD) interlaced - NTSC quality",
},
"576p": {
"nominal_height": 576,
"typical_widths": [720, 768],
"description": "PAL Standard Definition (SD) - European DVD quality",
},
"576i": {
"nominal_height": 576,
"typical_widths": [720, 768],
"description": "PAL Standard Definition (SD) interlaced - European quality",
},
"720p": {
"nominal_height": 720,
"typical_widths": [1280],
@@ -66,6 +76,11 @@ FRAME_CLASSES = {
"typical_widths": [1920],
"description": "Full High Definition (FHD) - 1080p HD",
},
"1080i": {
"nominal_height": 1080,
"typical_widths": [1920],
"description": "Full High Definition (FHD) interlaced - 1080i HD",
},
"1440p": {
"nominal_height": 1440,
"typical_widths": [2560],
+10 -3
View File
@@ -11,7 +11,6 @@ class FilenameExtractor:
def __init__(self, file_path: Path):
self.file_path = file_path
self.file_name = file_path.name
self.file_name = self._normalize_cyrillic(self.file_name)
def _normalize_cyrillic(self, text: str) -> str:
"""Normalize Cyrillic characters to English equivalents for parsing"""
@@ -157,10 +156,18 @@ class FilenameExtractor:
def extract_frame_class(self) -> str | None:
"""Extract frame class from filename (480p, 720p, 1080p, 2160p, etc.)"""
# First check for specific numeric resolutions
match = re.search(r'(\d{3,4})[pi]', self.file_name, re.IGNORECASE)
# Normalize Cyrillic characters for resolution parsing
normalized_name = self._normalize_cyrillic(self.file_name)
# First check for specific numeric resolutions with p/i
match = re.search(r'(\d{3,4})([pi])', normalized_name, re.IGNORECASE)
if match:
height = int(match.group(1))
scan_type = match.group(2).lower()
frame_class = f"{height}{scan_type}"
if frame_class in FRAME_CLASSES:
return frame_class
# Fallback to height-based if not in constants
return self._get_frame_class_from_height(height)
# If no specific resolution found, check for quality indicators
+21 -1
View File
@@ -59,7 +59,27 @@ class MediaInfoExtractor:
return None
height = getattr(self.video_tracks[0], 'height', None)
if height:
return self._get_frame_class_from_height(height)
# Check if interlaced
interlaced = getattr(self.video_tracks[0], 'interlaced', None)
scan_type = 'i' if interlaced == 'Yes' else 'p'
# First try exact match
frame_class = f"{height}{scan_type}"
if frame_class in FRAME_CLASSES:
return frame_class
# Find closest height with same scan type
closest_height = None
min_diff = float('inf')
for fc, info in FRAME_CLASSES.items():
if fc.endswith(scan_type):
diff = abs(height - info['nominal_height'])
if diff < min_diff:
min_diff = diff
closest_height = info['nominal_height']
if closest_height and min_diff <= 50:
return f"{closest_height}{scan_type}"
return None
def extract_resolution(self) -> tuple[int, int] | None: