diff --git a/dist/renamer-0.7.6-py3-none-any.whl b/dist/renamer-0.7.6-py3-none-any.whl new file mode 100644 index 0000000..4342430 Binary files /dev/null and b/dist/renamer-0.7.6-py3-none-any.whl differ diff --git a/pyproject.toml b/pyproject.toml index 63dbd1c..e8e2fe6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "renamer" -version = "0.7.5" +version = "0.7.6" 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 053d4e0..32e9409 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 file to MKV container with metadata (c)"), + ("convert", "Convert to MKV", "Convert AVI/MPG/MPEG/WebM 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 file to MKV with metadata preservation.""" + """Convert AVI/MPG/MPEG/WebM 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, and MPEG files can be converted to MKV", severity="error", timeout=3) + self.notify("Only AVI, MPG, MPEG, and WebM files can be converted to MKV", severity="error", timeout=3) return # Create extractor for metadata diff --git a/renamer/services/conversion_service.py b/renamer/services/conversion_service.py index a9306d3..9664c44 100644 --- a/renamer/services/conversion_service.py +++ b/renamer/services/conversion_service.py @@ -1,6 +1,6 @@ -"""Conversion service for AVI to MKV remux with metadata preservation. +"""Conversion service for video to MKV remux with metadata preservation. -This service manages the process of converting AVI files to MKV container: +This service manages the process of converting AVI/MPG/MPEG/WebM files to MKV container: - Fast stream copy (no re-encoding) - Audio language detection and mapping from filename - Subtitle file detection and inclusion @@ -21,13 +21,13 @@ logger = logging.getLogger(__name__) class ConversionService: - """Service for converting AVI files to MKV with metadata preservation. + """Service for converting video files to MKV with metadata preservation. This service handles: - - Validating AVI files for conversion + - Validating video files for conversion (AVI, MPG, MPEG, WebM) - Detecting nearby subtitle files - Mapping audio languages from filename to tracks - - Building ffmpeg command for fast remux + - Building ffmpeg command for fast remux or HEVC encoding - Executing conversion with progress Example: @@ -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, or MPEG). + """Check if a file can be converted (is AVI, MPG, MPEG, or WebM). Args: file_path: Path to the file to check Returns: - True if file is AVI, MPG, or MPEG and can be converted + True if file is AVI, MPG, MPEG, or WebM 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'} + return file_path.suffix.lower() in {'.avi', '.mpg', '.mpeg', '.webm'} def find_subtitle_files(self, video_path: Path) -> List[Path]: """Find subtitle files near the video file. @@ -280,12 +280,13 @@ class ConversionService: - Sets MKV title from filename Args: - source_path: Source video file (AVI, MPG, or MPEG) + source_path: Source video file (AVI, MPG, MPEG, or WebM) mkv_path: Destination MKV file audio_languages: Language codes for each audio track subtitle_files: List of subtitle files to include encode_hevc: If True, encode video to HEVC instead of copying crf: Constant Rate Factor for HEVC (18=visually lossless, 23=high quality default) + preset: x265 preset (ultrafast, veryfast, faster, fast, medium, slow) Returns: List of command arguments for subprocess @@ -357,10 +358,10 @@ class ConversionService: crf: int = 18, preset: str = 'medium' ) -> Tuple[bool, str]: - """Convert AVI/MPG/MPEG file to MKV with metadata preservation. + """Convert video file to MKV with metadata preservation. Args: - avi_path: Source video file path (AVI, MPG, or MPEG) + avi_path: Source video file path (AVI, MPG, MPEG, or WebM) 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 @@ -381,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) or doesn't exist: {avi_path}" + error_msg = f"File is not a supported format (AVI/MPG/MPEG/WebM) or doesn't exist: {avi_path}" logger.error(error_msg) return False, error_msg diff --git a/uv.lock b/uv.lock index f44da92..64615f8 100644 --- a/uv.lock +++ b/uv.lock @@ -462,7 +462,7 @@ wheels = [ [[package]] name = "renamer" -version = "0.7.5" +version = "0.7.6" source = { editable = "." } dependencies = [ { name = "langcodes" },