import os import subprocess import re def download(video_url, output_file_name, dest_dir='./', audio_only=False, progress_callback=None): # Ensure the destination directory exists if not os.path.exists(dest_dir): os.makedirs(dest_dir) # Prepare the command to predict filename extension if audio_only: predict_command = ['yt-dlp', '--newline', '-x', '--audio-format', 'mp3', '--get-filename', '-o', f'{output_file_name}.%(ext)s', video_url] else: predict_command = ['yt-dlp', '--newline', '--get-filename', '-o', f'{output_file_name}.%(ext)s', video_url] try: # Using yt-dlp with --get-filename to predict the output filename result = subprocess.check_output(predict_command) file_extension = os.path.splitext(result.decode('utf-8').strip())[1] except Exception as e: print(f'Unexpected error when getting filename: {e}') return # Prepare the command to download the media if audio_only: download_command = [ 'yt-dlp', '-x', '--audio-format', 'mp3', '-o', f'{dest_dir}/{output_file_name}{file_extension}', video_url ] else: download_command = [ 'yt-dlp', '-o', f'{dest_dir}/{output_file_name}{file_extension}', video_url ] try: # Execute the download command and capture stdout in real-time process = subprocess.Popen(download_command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) while True: line = process.stdout.readline() if not line: break if '[download]' in line: # Parse the progress from the output match = re.search(r'\[download\]\s+(\d+\.\d+|\d+)%', line) if match: percentage = int(float(match.group(1))) if progress_callback: progress_callback(percentage) # Call the callback with the parsed progress value process.communicate() # Wait for the process to finish if it hasn't yet except subprocess.CalledProcessError: print('Error occurred while downloading the video/audio.') except Exception as e: print(f'Unexpected error: {e}') if __name__ == '__main__': def update_progress_bar(percentage): print(percentage) download('https://www.youtube.com/watch?v=ON7QQtF-RNA', 'Khonsu - A Jhator Ascension', progress_callback=update_progress_bar)