FEATURE: Added support for configuration files, documentation updated
All checks were successful
Publish Python Package to PyPI / deploy (push) Successful in 18s

This commit is contained in:
2025-06-06 22:21:01 -04:00
parent 99b501daec
commit e7537eb16e
3 changed files with 86 additions and 6 deletions

View File

@ -16,6 +16,9 @@ This tool is perfect for users who want to standardize their media library's aud
* Processes multiple files simultaneously to dramatically speed up batch jobs, automatically using the optimal number of CPU cores. * Processes multiple files simultaneously to dramatically speed up batch jobs, automatically using the optimal number of CPU cores.
* **User-Friendly Configuration:**
* Automatically creates a default `options.json` file on the first run for easy customization. Command-line options always override the config file.
* **Interactive Progress Bar:** * **Interactive Progress Bar:**
* A clean `tqdm` progress bar shows you the overall progress, ETA, and processing speed. * A clean `tqdm` progress bar shows you the overall progress, ETA, and processing speed.
@ -88,7 +91,7 @@ The primary command is `eac3-transcode`.
`eac3-transcode --input "/path/to/your/video_folder/" --dry-run ` `eac3-transcode --input "/path/to/your/video_folder/" --dry-run `
__*This is the safest way to start, to confirm the script's logic matches your expectations.*__ __*This is the safest way to start, to confirm the script's logic matches your expectations.*__
2. **Process** all videos in a folder (output saved in the same directory as **originals):** 2. **Process** all videos in a folder (using defaults or your config file):**
`eac3-transcode --input "/path/to/your/video_folder/"` `eac3-transcode --input "/path/to/your/video_folder/"`
__*This will use all available CPU cores for maximum speed.*__ __*This will use all available CPU cores for maximum speed.*__
@ -107,6 +110,45 @@ __*This will use all available CPU cores for maximum speed.*__
`eac3-transcode --input "/path/to/your/video_folder/" --force-reprocess` `eac3-transcode --input "/path/to/your/video_folder/" --force-reprocess`
## Configuration
For convenience, the script supports a `options.json` file to set your preferred defaults.
### How it Works
1. **Automatic Creation:** The **first time** you run the script, it will automatically create a default `options.json` file in your user's configuration directory. It will print a message showing you where the file was created.
2. **Search Order:** When you run the command, it looks for a `options.json` file in this order:
* **1. Current Directory:** A `options.json` in the folder you are running the command from (for project-specific settings).
* **2. User Config Directory:** The global config file it created on the first run.
3. **Overrides:** Any option you provide on the command line (e.g., `--bitrate 640k`) will always take precedence over the setting in the config file for that specific run.
### Config File Location
The global config file is located in the standard directory for your operating system:
* Windows: `C:\Users\<YourUser>\AppData\Roaming\eac3-transcode\options.json`
* macOS: `/Users/<YourUser>/Library/Application Support/eac3-transcode/options.json`
* Linux: `/home/<YourUser>/.config/eac3-transcode/options.json`
**Example `options.json`**
You can edit this JSON file ot change your default settings.
```
{
"output_directory_base": null,
"audio_bitrate": "640k",
"languages": "eng,jpn",
"jobs": 8,
"dry_run": false,
"force_reprocess": false
}
```
## Command-Line Options ## Command-Line Options
**Usage:** **Usage:**

View File

@ -1,6 +1,6 @@
[metadata] [metadata]
name = surround-to-eac3 name = surround-to-eac3
version = 0.3.4 version = 0.4.0
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.
@ -19,6 +19,7 @@ packages = find:
python_requires = >=3.10 python_requires = >=3.10
install_requires = install_requires =
tqdm tqdm
platformdirs
[options.packages.find] [options.packages.find]
where=src where=src

View File

@ -5,9 +5,14 @@ import shutil
import argparse import argparse
import json import json
import threading import threading
import queue import queue
from functools import partial
from tqdm import tqdm from tqdm import tqdm
from platformdirs import user_config_dir
# --- Constants for Configuration ---
APP_NAME = "eac3-transcode"
APP_AUTHOR = "eac3-transcode"
CONFIG_FILENAME = "options.json"
# Global lock for TQDM writes to prevent interleaving from multiple threads # Global lock for TQDM writes to prevent interleaving from multiple threads
tqdm_lock = threading.Lock() tqdm_lock = threading.Lock()
@ -380,15 +385,47 @@ def main():
help="Force reprocessing of all files, even if an output file with the target name already exists." help="Force reprocessing of all files, even if an output file with the target name already exists."
) )
# --- Configuration File Logic ---
config = {}
user_config_dir_path = user_config_dir(APP_NAME, APP_AUTHOR)
user_config_file_path = os.path.join(user_config_dir_path, CONFIG_FILENAME)
if not os.path.exists(user_config_file_path):
try:
defaults = {action.dest: action.default for action in parser._actions if action.dest != "help" and not action.required}
os.makedirs(user_config_dir_path, exist_ok=True)
with open(user_config_file_path, 'w') as f:
json.dump(defaults, f, indent=4)
print(f"✅ Created default configuration at: {user_config_file_path}")
except Exception as e:
print(f"⚠️ Warning: Could not create default config at '{user_config_file_path}': {e}")
potential_paths = [os.path.join(os.getcwd(), CONFIG_FILENAME), user_config_file_path]
loaded_config_path = None
for path in potential_paths:
if os.path.exists(path):
try:
with open(path, 'r') as f:
config = json.load(f)
loaded_config_path = path
break
except (json.JSONDecodeError, IOError) as e:
print(f"⚠️ Warning: Could not read or parse config at '{path}': {e}")
break
parser.set_defaults(**config)
args = parser.parse_args() args = parser.parse_args()
if loaded_config_path:
print(f"✅ Loaded configuration from: {loaded_config_path}")
if args.dry_run: if args.dry_run:
print("--- DRY RUN MODE ENABLED: No files will be modified. ---") print("--- DRY RUN MODE ENABLED: No files will be modified. ---")
# --- File Discovery ---
input_path_abs = os.path.abspath(args.input_path) input_path_abs = os.path.abspath(args.input_path)
files_to_process_paths = [] files_to_process_paths = []
# Collect all files to process
if os.path.isdir(input_path_abs): if os.path.isdir(input_path_abs):
print(f"📁 Scanning folder: {input_path_abs}") print(f"📁 Scanning folder: {input_path_abs}")
for root, _, filenames in os.walk(input_path_abs): for root, _, filenames in os.walk(input_path_abs):