132 lines
5.6 KiB
Python
132 lines
5.6 KiB
Python
import os
|
|
import sys
|
|
import argparse
|
|
import subprocess
|
|
import time
|
|
from pathlib import Path
|
|
|
|
def count_files(source, extensions):
|
|
count = 0
|
|
if os.path.isfile(source):
|
|
if Path(source).suffix[1:].lower() in extensions:
|
|
count = 1
|
|
else:
|
|
for ext in extensions:
|
|
count += len(list(Path(source).rglob(f'*.{ext}')))
|
|
return count
|
|
|
|
def progress_bar(iteration, total, prefix='', suffix='', decimals=1, length=50, fill='█', print_end="\r"):
|
|
percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
|
|
filled_length = int(length * iteration // total)
|
|
bar = fill * filled_length + '-' * (length - filled_length)
|
|
print(f'\r{prefix} |{bar}| {percent}% {suffix}', end=print_end)
|
|
if iteration == total:
|
|
print()
|
|
|
|
def get_conversion_command(source_path, target_path, voice_mode=False):
|
|
ext = Path(source_path).suffix[1:].lower()
|
|
audio_extensions = ['mp3', 'wav', 'm4a', 'opus']
|
|
video_extensions = ['mp4', 'avi', 'mov', 'webm', 'mkv']
|
|
image_extensions = ['jpg', 'jpeg', 'png', 'gif']
|
|
|
|
if ext in video_extensions:
|
|
target_path = os.path.splitext(target_path)[0] + '.mp4'
|
|
elif ext in audio_extensions:
|
|
target_path = os.path.splitext(target_path)[0] + '.mp3'
|
|
elif ext in image_extensions:
|
|
target_path = os.path.splitext(target_path)[0] + '.jpeg'
|
|
|
|
if ext in audio_extensions:
|
|
if voice_mode:
|
|
return ['ffmpeg', '-i', source_path, '-vn', '-ar', '22050', '-ac', '1', '-b:a', '32k', '-c:a', 'libmp3lame', target_path]
|
|
else:
|
|
return ['ffmpeg', '-i', source_path, '-vn', '-ar', '44100', '-ac', '2', '-b:a', '128k', '-c:a', 'libmp3lame', target_path]
|
|
elif ext in video_extensions:
|
|
if ext == 'mkv':
|
|
return ['ffmpeg', '-i', source_path, '-c', 'copy', target_path]
|
|
else:
|
|
return ['ffmpeg', '-i', source_path, '-vf', "fps=30,scale='min(1280,iw)':min'(720,ih)':force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2", '-c:v', 'libx264', '-crf', '23', '-preset', 'medium', '-c:a', 'aac', '-b:a', '128k', target_path]
|
|
elif ext in image_extensions:
|
|
return ['ffmpeg', '-i', source_path, '-vf', "scale='min(1280,iw)':min'(720,ih)':force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2", '-q:v', '2', target_path]
|
|
else:
|
|
return None
|
|
|
|
def convert_files(source, target, dry_run=False, voice_mode=False, delete_original=False):
|
|
all_extensions = ['mp3', 'wav', 'm4a', 'opus', 'mp4', 'avi', 'mov', 'webm', 'mkv',
|
|
'jpg', 'jpeg', 'png', 'gif']
|
|
total_files = count_files(source, all_extensions)
|
|
|
|
if dry_run:
|
|
print(f"Dry run: {total_files} file(s) would be converted")
|
|
return
|
|
|
|
processed_files = 0
|
|
|
|
def process_file(source_path, target_path):
|
|
nonlocal processed_files
|
|
cmd = get_conversion_command(source_path, target_path, voice_mode)
|
|
if cmd:
|
|
print(f"Converting {source_path} to {target_path}")
|
|
if not dry_run:
|
|
try:
|
|
result = subprocess.run(cmd, check=True, capture_output=True,
|
|
text=True)
|
|
if delete_original:
|
|
os.remove(source_path)
|
|
print(f"Deleted original file: {source_path}")
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Erreur lors de la conversion : {e}")
|
|
print(f"Sortie d'erreur : {e.stderr}")
|
|
return
|
|
processed_files += 1
|
|
progress_bar(processed_files, total_files,
|
|
prefix='Progress:', suffix='Complete')
|
|
else:
|
|
print(f"Skipping unsupported file: {source_path}")
|
|
|
|
if os.path.isfile(source):
|
|
target_dir = os.path.dirname(target) if os.path.isfile(target) else target
|
|
os.makedirs(target_dir, exist_ok=True)
|
|
process_file(source, target)
|
|
else:
|
|
for root, _, files in os.walk(source):
|
|
for file in files:
|
|
source_path = os.path.join(root, file)
|
|
relative_path = os.path.relpath(source_path, source)
|
|
target_path = os.path.join(target, relative_path)
|
|
os.makedirs(os.path.dirname(target_path), exist_ok=True)
|
|
process_file(source_path, target_path)
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description='Convert audio, video, and image files.')
|
|
parser.add_argument('source',
|
|
help='Source file or directory containing files to convert')
|
|
parser.add_argument('target',
|
|
help='Target file (if source is a file) or directory for converted files')
|
|
parser.add_argument('--dry-run',
|
|
action='store_true',
|
|
help='Perform a dry run without actually converting files')
|
|
parser.add_argument('--voice-mode',
|
|
action='store_true',
|
|
help='Optimize audio encoding for voice')
|
|
parser.add_argument('--delete-original',
|
|
action='store_true',
|
|
help='Delete original files after successful conversion')
|
|
|
|
args = parser.parse_args()
|
|
|
|
if not os.path.exists(args.source):
|
|
print(f"Error: Source path '{args.source}' does not exist.")
|
|
sys.exit(1)
|
|
|
|
start_time = time.time()
|
|
convert_files(args.source, args.target,
|
|
args.dry_run,
|
|
args.voice_mode,
|
|
args.delete_original)
|
|
end_time = time.time()
|
|
|
|
print(f"\nTotal execution time: {end_time - start_time:.2f} seconds")
|
|
|
|
if __name__ == "__main__":
|
|
main() |