fix: Update conversion service and UI to support MP4 files in conversion process
This commit is contained in:
BIN
dist/renamer-0.7.7-py3-none-any.whl
vendored
Normal file
BIN
dist/renamer-0.7.7-py3-none-any.whl
vendored
Normal file
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "renamer"
|
name = "renamer"
|
||||||
version = "0.7.6"
|
version = "0.7.7"
|
||||||
description = "Terminal-based media file renamer and metadata viewer"
|
description = "Terminal-based media file renamer and metadata viewer"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ class AppCommandProvider(Provider):
|
|||||||
("scan", "Scan Directory", "Scan current directory for media files (s)"),
|
("scan", "Scan Directory", "Scan current directory for media files (s)"),
|
||||||
("refresh", "Refresh File", "Refresh metadata for selected file (f)"),
|
("refresh", "Refresh File", "Refresh metadata for selected file (f)"),
|
||||||
("rename", "Rename File", "Rename the selected file (r)"),
|
("rename", "Rename File", "Rename the selected file (r)"),
|
||||||
("convert", "Convert to MKV", "Convert AVI/MPG/MPEG/WebM file to MKV container with metadata (c)"),
|
("convert", "Convert to MKV", "Convert AVI/MPG/MPEG/WebM/MP4 file to MKV container with metadata (c)"),
|
||||||
("delete", "Delete File", "Delete the selected file (d)"),
|
("delete", "Delete File", "Delete the selected file (d)"),
|
||||||
("toggle_mode", "Toggle Display Mode", "Switch between technical and catalog view (m)"),
|
("toggle_mode", "Toggle Display Mode", "Switch between technical and catalog view (m)"),
|
||||||
("expand", "Toggle Tree Expansion", "Expand or collapse all tree nodes (p)"),
|
("expand", "Toggle Tree Expansion", "Expand or collapse all tree nodes (p)"),
|
||||||
@@ -390,7 +390,7 @@ By Category:"""
|
|||||||
self.notify("Proposed name is the same as current name; no rename needed.", severity="information", timeout=3)
|
self.notify("Proposed name is the same as current name; no rename needed.", severity="information", timeout=3)
|
||||||
|
|
||||||
async def action_convert(self):
|
async def action_convert(self):
|
||||||
"""Convert AVI/MPG/MPEG/WebM file to MKV with metadata preservation."""
|
"""Convert AVI/MPG/MPEG/WebM/MP4 file to MKV with metadata preservation."""
|
||||||
tree = self.query_one("#file_tree", Tree)
|
tree = self.query_one("#file_tree", Tree)
|
||||||
node = tree.cursor_node
|
node = tree.cursor_node
|
||||||
|
|
||||||
@@ -403,7 +403,7 @@ By Category:"""
|
|||||||
|
|
||||||
# Check if file can be converted
|
# Check if file can be converted
|
||||||
if not conversion_service.can_convert(file_path):
|
if not conversion_service.can_convert(file_path):
|
||||||
self.notify("Only AVI, MPG, MPEG, and WebM files can be converted to MKV", severity="error", timeout=3)
|
self.notify("Only AVI, MPG, MPEG, WebM, and MP4 files can be converted to MKV", severity="error", timeout=3)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Create extractor for metadata
|
# Create extractor for metadata
|
||||||
|
|||||||
@@ -505,10 +505,13 @@ class ConvertConfirmScreen(Screen):
|
|||||||
def on_button_pressed(self, event):
|
def on_button_pressed(self, event):
|
||||||
if event.button.id == "convert_copy":
|
if event.button.id == "convert_copy":
|
||||||
self._do_conversion(encode_hevc=False)
|
self._do_conversion(encode_hevc=False)
|
||||||
|
event.stop() # Prevent key event from also triggering
|
||||||
elif event.button.id == "convert_hevc":
|
elif event.button.id == "convert_hevc":
|
||||||
self._do_conversion(encode_hevc=True)
|
self._do_conversion(encode_hevc=True)
|
||||||
|
event.stop() # Prevent key event from also triggering
|
||||||
elif event.button.id == "cancel":
|
elif event.button.id == "cancel":
|
||||||
self.app.pop_screen() # type: ignore
|
self.app.pop_screen() # type: ignore
|
||||||
|
event.stop() # Prevent key event from also triggering
|
||||||
|
|
||||||
def _do_conversion(self, encode_hevc: bool):
|
def _do_conversion(self, encode_hevc: bool):
|
||||||
"""Start conversion with the specified encoding mode."""
|
"""Start conversion with the specified encoding mode."""
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"""Conversion service for video to MKV remux with metadata preservation.
|
"""Conversion service for video to MKV remux with metadata preservation.
|
||||||
|
|
||||||
This service manages the process of converting AVI/MPG/MPEG/WebM files to MKV container:
|
This service manages the process of converting AVI/MPG/MPEG/WebM/MP4 files to MKV container:
|
||||||
- Fast stream copy (no re-encoding)
|
- Fast stream copy (no re-encoding)
|
||||||
- Audio language detection and mapping from filename
|
- Audio language detection and mapping from filename
|
||||||
- Subtitle file detection and inclusion
|
- Subtitle file detection and inclusion
|
||||||
@@ -24,7 +24,7 @@ class ConversionService:
|
|||||||
"""Service for converting video files to MKV with metadata preservation.
|
"""Service for converting video files to MKV with metadata preservation.
|
||||||
|
|
||||||
This service handles:
|
This service handles:
|
||||||
- Validating video files for conversion (AVI, MPG, MPEG, WebM)
|
- Validating video files for conversion (AVI, MPG, MPEG, WebM, MP4)
|
||||||
- Detecting nearby subtitle files
|
- Detecting nearby subtitle files
|
||||||
- Mapping audio languages from filename to tracks
|
- Mapping audio languages from filename to tracks
|
||||||
- Building ffmpeg command for fast remux or HEVC encoding
|
- Building ffmpeg command for fast remux or HEVC encoding
|
||||||
@@ -168,18 +168,18 @@ class ConversionService:
|
|||||||
return ':'.join(base_params + cpu_params)
|
return ':'.join(base_params + cpu_params)
|
||||||
|
|
||||||
def can_convert(self, file_path: Path) -> bool:
|
def can_convert(self, file_path: Path) -> bool:
|
||||||
"""Check if a file can be converted (is AVI, MPG, MPEG, or WebM).
|
"""Check if a file can be converted (is AVI, MPG, MPEG, WebM, or MP4).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
file_path: Path to the file to check
|
file_path: Path to the file to check
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if file is AVI, MPG, MPEG, or WebM and can be converted
|
True if file is AVI, MPG, MPEG, WebM, or MP4 and can be converted
|
||||||
"""
|
"""
|
||||||
if not file_path.exists() or not file_path.is_file():
|
if not file_path.exists() or not file_path.is_file():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return file_path.suffix.lower() in {'.avi', '.mpg', '.mpeg', '.webm'}
|
return file_path.suffix.lower() in {'.avi', '.mpg', '.mpeg', '.webm', '.mp4', '.m4v'}
|
||||||
|
|
||||||
def find_subtitle_files(self, video_path: Path) -> List[Path]:
|
def find_subtitle_files(self, video_path: Path) -> List[Path]:
|
||||||
"""Find subtitle files near the video file.
|
"""Find subtitle files near the video file.
|
||||||
@@ -280,7 +280,7 @@ class ConversionService:
|
|||||||
- Sets MKV title from filename
|
- Sets MKV title from filename
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
source_path: Source video file (AVI, MPG, MPEG, or WebM)
|
source_path: Source video file (AVI, MPG, MPEG, WebM, or MP4)
|
||||||
mkv_path: Destination MKV file
|
mkv_path: Destination MKV file
|
||||||
audio_languages: Language codes for each audio track
|
audio_languages: Language codes for each audio track
|
||||||
subtitle_files: List of subtitle files to include
|
subtitle_files: List of subtitle files to include
|
||||||
@@ -361,7 +361,7 @@ class ConversionService:
|
|||||||
"""Convert video file to MKV with metadata preservation.
|
"""Convert video file to MKV with metadata preservation.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
avi_path: Source video file path (AVI, MPG, MPEG, or WebM)
|
avi_path: Source video file path (AVI, MPG, MPEG, WebM, or MP4)
|
||||||
extractor: Optional MediaExtractor (creates new if None)
|
extractor: Optional MediaExtractor (creates new if None)
|
||||||
output_path: Optional output path (defaults to same name with .mkv)
|
output_path: Optional output path (defaults to same name with .mkv)
|
||||||
dry_run: If True, build command but don't execute
|
dry_run: If True, build command but don't execute
|
||||||
@@ -382,7 +382,7 @@ class ConversionService:
|
|||||||
"""
|
"""
|
||||||
# Validate input
|
# Validate input
|
||||||
if not self.can_convert(avi_path):
|
if not self.can_convert(avi_path):
|
||||||
error_msg = f"File is not a supported format (AVI/MPG/MPEG/WebM) or doesn't exist: {avi_path}"
|
error_msg = f"File is not a supported format (AVI/MPG/MPEG/WebM/MP4) or doesn't exist: {avi_path}"
|
||||||
logger.error(error_msg)
|
logger.error(error_msg)
|
||||||
return False, error_msg
|
return False, error_msg
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user