FEATURE: Implement force re-processing
All checks were successful
Publish Python Package to PyPI / deploy (push) Successful in 15s
All checks were successful
Publish Python Package to PyPI / deploy (push) Successful in 15s
Adds a `--force-reprocess` flag to override the new default behavior of skipping existing files. The README has been updated accordingly.
This commit is contained in:
30
README.md
30
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.
|
* 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:**
|
* **Flexible Output:**
|
||||||
|
|
||||||
* Save processed files alongside originals or in a specified output directory, maintaining the source folder structure if applicable.
|
* 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`
|
`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
|
## Command-Line Options
|
||||||
|
|
||||||
**Usage:**
|
**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.
|
An advanced video transcoder that processes files to use E-AC3 for specific audio tracks, filters by language, and can process entire folders.
|
||||||
|
|
||||||
**Options:**
|
**Options:**
|
||||||
@ -129,15 +137,23 @@ An advanced video transcoder that processes files to use E-AC3 for specific audi
|
|||||||
* `--dry-run`
|
* `--dry-run`
|
||||||
**(Optional)** Analyze files and report actions without executing ffmpeg. No files will be modified.
|
**(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
|
## How It Works
|
||||||
|
|
||||||
1. **File Discovery:** The script scans the input path for `.mkv` and `.mp4` files.
|
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.
|
* 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.
|
* **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.
|
* **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.
|
* 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..."**:
|
* **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:**
|
* **Permission Errors:**
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[metadata]
|
[metadata]
|
||||||
name = surround-to-eac3
|
name = surround-to-eac3
|
||||||
version = 0.3.3
|
version = 0.3.4
|
||||||
author = Jonathan Rampersad
|
author = Jonathan Rampersad
|
||||||
author_email = jonathan@jono-rams.work
|
author_email = jonathan@jono-rams.work
|
||||||
description = A CLI tool to transcode 5.1 audio in video files to E-AC3.
|
description = A CLI tool to transcode 5.1 audio in video files to E-AC3.
|
||||||
|
@ -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
|
output_dir_for_this_file = args.output_directory_base
|
||||||
|
|
||||||
final_output_filepath = os.path.join(output_dir_for_this_file, output_filename)
|
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
|
# Check for identical paths before starting
|
||||||
if os.path.abspath(filepath) == os.path.abspath(final_output_filepath):
|
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
|
action="store_true", # Makes it a flag, e.g., --dry-run
|
||||||
help="Analyze files and report actions without executing ffmpeg."
|
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()
|
args = parser.parse_args()
|
||||||
|
|
||||||
@ -403,6 +417,7 @@ def main():
|
|||||||
"skipped_no_ops": 0,
|
"skipped_no_ops": 0,
|
||||||
"skipped_no_transcode": 0,
|
"skipped_no_transcode": 0,
|
||||||
"skipped_identical_path": 0,
|
"skipped_identical_path": 0,
|
||||||
|
"skipped_existing": 0,
|
||||||
"failed": 0
|
"failed": 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,11 +466,12 @@ def main():
|
|||||||
print(f"\n{summary_title}")
|
print(f"\n{summary_title}")
|
||||||
print(f"Total files checked: {len(files_to_process_paths)}")
|
print(f"Total files checked: {len(files_to_process_paths)}")
|
||||||
print(f"✅ {processed_label}: {stats['processed']}")
|
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}")
|
print(f"⏭️ Total Skipped: {total_skipped}")
|
||||||
if total_skipped > 0:
|
if total_skipped > 0:
|
||||||
print(f" - No target audio operations: {stats['skipped_no_ops']}")
|
print(f" - No target audio operations: {stats['skipped_no_ops']}")
|
||||||
print(f" - No transcoding required (all copy): {stats['skipped_no_transcode']}")
|
print(f" - No transcoding required (all copy): {stats['skipped_no_transcode']}")
|
||||||
print(f" - Identical input/output path: {stats['skipped_identical_path']}")
|
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(f"🚨 Failed to process: {stats['failed']}")
|
||||||
print("--------------------------")
|
print("--------------------------")
|
||||||
|
Reference in New Issue
Block a user