diff --git a/dist/renamer-0.7.7-py3-none-any.whl b/dist/renamer-0.7.7-py3-none-any.whl new file mode 100644 index 0000000..34ae66c Binary files /dev/null and b/dist/renamer-0.7.7-py3-none-any.whl differ diff --git a/pyproject.toml b/pyproject.toml index e8e2fe6..531e1f9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "renamer" -version = "0.7.6" +version = "0.7.7" description = "Terminal-based media file renamer and metadata viewer" readme = "README.md" requires-python = ">=3.11" diff --git a/renamer/app.py b/renamer/app.py index 32e9409..f6a0a86 100644 --- a/renamer/app.py +++ b/renamer/app.py @@ -69,7 +69,7 @@ class AppCommandProvider(Provider): ("scan", "Scan Directory", "Scan current directory for media files (s)"), ("refresh", "Refresh File", "Refresh metadata for selected file (f)"), ("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)"), ("toggle_mode", "Toggle Display Mode", "Switch between technical and catalog view (m)"), ("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) 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) node = tree.cursor_node @@ -403,7 +403,7 @@ By Category:""" # Check if file can be converted 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 # Create extractor for metadata diff --git a/renamer/screens.py b/renamer/screens.py index 41fde92..429cf52 100644 --- a/renamer/screens.py +++ b/renamer/screens.py @@ -505,10 +505,13 @@ class ConvertConfirmScreen(Screen): def on_button_pressed(self, event): if event.button.id == "convert_copy": self._do_conversion(encode_hevc=False) + event.stop() # Prevent key event from also triggering elif event.button.id == "convert_hevc": self._do_conversion(encode_hevc=True) + event.stop() # Prevent key event from also triggering elif event.button.id == "cancel": self.app.pop_screen() # type: ignore + event.stop() # Prevent key event from also triggering def _do_conversion(self, encode_hevc: bool): """Start conversion with the specified encoding mode.""" diff --git a/renamer/services/conversion_service.py b/renamer/services/conversion_service.py index 9664c44..e8df176 100644 --- a/renamer/services/conversion_service.py +++ b/renamer/services/conversion_service.py @@ -1,6 +1,6 @@ """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) - Audio language detection and mapping from filename - Subtitle file detection and inclusion @@ -24,7 +24,7 @@ class ConversionService: """Service for converting video files to MKV with metadata preservation. 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 - Mapping audio languages from filename to tracks - Building ffmpeg command for fast remux or HEVC encoding @@ -168,18 +168,18 @@ class ConversionService: return ':'.join(base_params + cpu_params) 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: file_path: Path to the file to check 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(): 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]: """Find subtitle files near the video file. @@ -280,7 +280,7 @@ class ConversionService: - Sets MKV title from filename 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 audio_languages: Language codes for each audio track subtitle_files: List of subtitle files to include @@ -361,7 +361,7 @@ class ConversionService: """Convert video file to MKV with metadata preservation. 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) output_path: Optional output path (defaults to same name with .mkv) dry_run: If True, build command but don't execute @@ -382,7 +382,7 @@ class ConversionService: """ # Validate input 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) return False, error_msg diff --git a/uv.lock b/uv.lock index 64615f8..d018a74 100644 --- a/uv.lock +++ b/uv.lock @@ -462,7 +462,7 @@ wheels = [ [[package]] name = "renamer" -version = "0.7.6" +version = "0.7.7" source = { editable = "." } dependencies = [ { name = "langcodes" },