updates and backlog
This commit is contained in:
@@ -13,6 +13,7 @@ import psutil
|
||||
from tqdm import tqdm
|
||||
|
||||
video_extensions: list[str] = ["mp4", "mkv", "avi", "wmv", "mov", "m4v", "ts", "flv", "mpg", "webm"]
|
||||
embedded_sub_extensions: list[str] = ["mkv"]
|
||||
|
||||
total_files: int = 0
|
||||
|
||||
@@ -111,6 +112,38 @@ def ffmpeg_command(input: pathlib.Path, output: pathlib.Path, nice: int = 20) ->
|
||||
str(output)
|
||||
]
|
||||
|
||||
def extract_sub_command(input: pathlib.Path, output: pathlib.Path) -> list[str]:
|
||||
return [
|
||||
"ffmpeg",
|
||||
"-progress", "pipe:1", # Send progress info to stdout
|
||||
"-i", str(input),
|
||||
"-map", "0:s:0",
|
||||
str(output)
|
||||
]
|
||||
|
||||
def has_subs(input: pathlib.Path) -> bool:
|
||||
cmd = [
|
||||
"ffprobe",
|
||||
"-loglevel", "error",
|
||||
"-select_streams", "s",
|
||||
"-show_entries", "stream=index:stream_tags=language",
|
||||
"-of", "csv=p=0",
|
||||
str(input)
|
||||
]
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
|
||||
print(input)
|
||||
print(result.stdout)
|
||||
print("---")
|
||||
if result.stdout:
|
||||
return True
|
||||
return False
|
||||
except (subprocess.CalledProcessError, ValueError) as e:
|
||||
logging.error(f"Error getting subs for {input}: {e}")
|
||||
return False
|
||||
except:
|
||||
return False
|
||||
|
||||
def clean_directory(directory_path: pathlib.Path) -> None:
|
||||
"""Yeet all files and directories from a directory."""
|
||||
for item in directory_path.iterdir():
|
||||
@@ -122,6 +155,9 @@ def clean_directory(directory_path: pathlib.Path) -> None:
|
||||
def is_video(path: pathlib.Path) -> bool:
|
||||
return path.suffix.lower()[1:] in video_extensions
|
||||
|
||||
def is_video_with_embedded_subs(path: pathlib.Path) -> bool:
|
||||
return path.suffix.lower()[1:] in embedded_sub_extensions
|
||||
|
||||
def get_video_duration(input_file: pathlib.Path) -> float:
|
||||
cmd = [
|
||||
"ffprobe",
|
||||
@@ -313,6 +349,26 @@ def process_directory(
|
||||
logging.info(f"Processed {count} files, {successful} successful")
|
||||
return count
|
||||
|
||||
def process_subtitles(
|
||||
*,
|
||||
source_dir: pathlib.Path,
|
||||
destination_dir: pathlib.Path,
|
||||
temp_dir: pathlib.Path):
|
||||
for dirpath, _dirnames, filenames in os.walk(source_dir):
|
||||
for filename in filenames:
|
||||
filepath = pathlib.Path(dirpath) / filename
|
||||
# File might have been deleted since starting script
|
||||
if not filepath.exists() or not is_video_with_embedded_subs(filepath):
|
||||
logging.debug(f"Skipping {filepath}: not a video file or doesn't exist")
|
||||
continue
|
||||
if has_subs(filepath):
|
||||
target_path = destination_dir / filepath.relative_to(source_dir)
|
||||
target_path = target_path.with_suffix(".cmp.en.srt")
|
||||
if target_path.exists():
|
||||
logging.debug(f"Skipping {filepath}: target already exists")
|
||||
continue
|
||||
cmd = extract_sub_command(filepath, target_path)
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
@@ -332,6 +388,7 @@ def main():
|
||||
help='Remove source files after successful compression')
|
||||
parser.add_argument('-v', '--verbose', action='store_true',
|
||||
help='Enable verbose logging output')
|
||||
parser.add_argument('--sub', action='store_true', help='Process files for subtitle extraction first')
|
||||
parser.add_argument('-n', '--nice', type=lambda x: int(x) if 0 <= int(x) <= 39 else exec('raise ValueError("Nice value must be between 0 and 39")'),
|
||||
default=20,
|
||||
help='Nice value for process priority (default: 20). Valid values are 0 (highest priority) to 39 (lowest priority). Lower values use more system resources.')
|
||||
@@ -352,22 +409,27 @@ def main():
|
||||
global ignore_busy
|
||||
ignore_busy = bool(args.ignore_busy)
|
||||
|
||||
logging.info(f"Starting video compression from {source_dir} to {destination_dir}")
|
||||
|
||||
global total_files
|
||||
total_files = process_directory(
|
||||
source_dir=source_dir,
|
||||
if args.sub:
|
||||
process_subtitles(source_dir=source_dir,
|
||||
destination_dir=destination_dir,
|
||||
temp_dir=temp_dir,
|
||||
count_only=True
|
||||
)
|
||||
temp_dir=temp_dir)
|
||||
else:
|
||||
logging.info(f"Starting video compression from {source_dir} to {destination_dir}")
|
||||
|
||||
process_directory(
|
||||
source_dir=source_dir,
|
||||
destination_dir=destination_dir,
|
||||
temp_dir=temp_dir,
|
||||
remove_source=args.remove_source,
|
||||
nice=args.nice
|
||||
)
|
||||
global total_files
|
||||
total_files = process_directory(
|
||||
source_dir=source_dir,
|
||||
destination_dir=destination_dir,
|
||||
temp_dir=temp_dir,
|
||||
count_only=True
|
||||
)
|
||||
|
||||
process_directory(
|
||||
source_dir=source_dir,
|
||||
destination_dir=destination_dir,
|
||||
temp_dir=temp_dir,
|
||||
remove_source=args.remove_source,
|
||||
nice=args.nice
|
||||
)
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user