diff --git a/README.md b/README.md index 7785b14..f2c119e 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,10 @@ This tool is perfect for users who want to standardize their media library's aud * Files are skipped entirely if no audio streams in the target languages meet the criteria for transcoding, preventing empty or unnecessary output files. +* **Efficient Processing:** + + * The script automatically skips processing a file if an output file with the target name already exists. This allows you to safely re-run the script on the same directory to only process new files. Use the `--force-reprocess` flag to override this behavior. + * **Flexible Output:** * Save processed files alongside originals or in a specified output directory, maintaining the source folder structure if applicable. @@ -99,11 +103,15 @@ __*This will use all available CPU cores for maximum speed.*__ `eac3-transcode --input "video.mkv" --langs "eng,spa" --bitrate "640k" --jobs 4` +5. **Force the script to re-process all files, even those that already exist:** + +`eac3-transcode --input "/path/to/your/video_folder/" --force-reprocess` + ## Command-Line Options **Usage:** -`eac3-transcode [-h] -i INPUT_PATH [-o OUTPUT_DIRECTORY_BASE] [-br AUDIO_BITRATE] [-l LANGUAGES] [-j JOBS] [--dry-run]` +`eac3-transcode [-h] -i INPUT_PATH [-o OUTPUT_DIRECTORY_BASE] [-br AUDIO_BITRATE] [-l LANGUAGES] [-j JOBS] [--dry-run] [--force-reprocess]` An advanced video transcoder that processes files to use E-AC3 for specific audio tracks, filters by language, and can process entire folders. **Options:** @@ -129,15 +137,23 @@ An advanced video transcoder that processes files to use E-AC3 for specific audi * `--dry-run` **(Optional)** Analyze files and report actions without executing ffmpeg. No files will be modified. +* `--force-reprocess` + **(Optional)** Force reprocessing of all files, even if an output file with the target name already exists. + + ## How It Works 1. **File Discovery:** The script scans the input path for `.mkv` and `.mp4` files. -2. **Stream Analysis (using `ffprobe`):** For each file: +2. **Pre-flight Checks:** + + * **Existence Check:** The script first determines the final output filename. If that file already exists and `--force-reprocess` is NOT used, the script skips the file and moves to the next one. + +3. **Stream Analysis (using `ffprobe`):** For each file: * It extracts information about all audio streams: codec, channels, and language tags. -3. **Decision Logic:** +4. **Decision Logic:** * **Language Filter:** Only audio streams matching the languages provided with the `-l LANGUAGES, --langs LANGUAGES` option are considered for keeping. **This defaults to `eng,jpn`**. Others are marked to be dropped. @@ -147,7 +163,7 @@ An advanced video transcoder that processes files to use E-AC3 for specific audi * **File Skipping:** If no audio streams are marked for 'transcode', the entire file is skipped. -4. **Processing (using `ffmpeg`):** +5. **Processing (using `ffmpeg`):** * If not in `--dry-run` mode, a new FFmpeg command is constructed. This processing is done in parallel for multiple files, with a progress bar updating you on the status of the batch. @@ -171,7 +187,11 @@ An advanced video transcoder that processes files to use E-AC3 for specific audi * **No files processed / "Skipping 'filename': No audio streams in the desired languages... meet criteria..."**: - * This is expected behavior if the files scanned do not contain any audio tracks in the target languages that require transcoding to E-AC3. This message reflects the default languages (`eng,jpn`) or the ones you specified with `--langs`. Use `--dry-run` to confirm the logic without waiting for processing. + * This is expected if files don't meet the criteria. Check the log message: + + * **"Output file already exists.":** This is the default behavior. The script will not re-process a file if the output (`filename_eac3.mkv`) is already present. Use `--force-reprocess` if you want to overwrite it. + + * **"No audio streams... meet criteria":** This means no audio tracks in the target languages require transcoding to E-AC3. This reflects the default languages (`eng,jpn`) or the ones you specified with `--langs`. * **Permission Errors:** diff --git a/setup.cfg b/setup.cfg index a0931d5..556aec5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = surround-to-eac3 -version = 0.3.3 +version = 0.3.4 author = Jonathan Rampersad author_email = jonathan@jono-rams.work description = A CLI tool to transcode 5.1 audio in video files to E-AC3. diff --git a/src/surround_to_eac3/main.py b/src/surround_to_eac3/main.py index 81e20d4..ed3d361 100644 --- a/src/surround_to_eac3/main.py +++ b/src/surround_to_eac3/main.py @@ -257,6 +257,15 @@ def process_single_file(filepath: str, pbar_position: int, args: argparse.Namesp output_dir_for_this_file = args.output_directory_base final_output_filepath = os.path.join(output_dir_for_this_file, output_filename) + + # Check if the output file already exists and we are NOT forcing reprocessing. + if os.path.exists(final_output_filepath) and not args.force_reprocess: + file_specific_logs.append(f" ⏭️ Skipping: Output file already exists. Use --force-reprocess to override.") + with tqdm_lock: + for log_msg in file_specific_logs: + tqdm.write(log_msg) + final_status = "skipped_existing" + return final_status # Check for identical paths before starting if os.path.abspath(filepath) == os.path.abspath(final_output_filepath): @@ -365,6 +374,11 @@ def main(): action="store_true", # Makes it a flag, e.g., --dry-run help="Analyze files and report actions without executing ffmpeg." ) + parser.add_argument( + "--force-reprocess", + action="store_true", + help="Force reprocessing of all files, even if an output file with the target name already exists." + ) args = parser.parse_args() @@ -403,6 +417,7 @@ def main(): "skipped_no_ops": 0, "skipped_no_transcode": 0, "skipped_identical_path": 0, + "skipped_existing": 0, "failed": 0 } @@ -451,11 +466,12 @@ def main(): print(f"\n{summary_title}") print(f"Total files checked: {len(files_to_process_paths)}") print(f"✅ {processed_label}: {stats['processed']}") - total_skipped = stats['skipped_no_ops'] + stats['skipped_no_transcode'] + stats['skipped_identical_path'] + total_skipped = stats['skipped_no_ops'] + stats['skipped_no_transcode'] + stats['skipped_identical_path'] + stats['skipped_existing'] print(f"⏭️ Total Skipped: {total_skipped}") if total_skipped > 0: print(f" - No target audio operations: {stats['skipped_no_ops']}") print(f" - No transcoding required (all copy): {stats['skipped_no_transcode']}") print(f" - Identical input/output path: {stats['skipped_identical_path']}") + print(f" - Output file already exists: {stats['skipped_existing']}") print(f"🚨 Failed to process: {stats['failed']}") print("--------------------------")