From: Skullheadx <94652084+Skullheadx@users.noreply.github.com> Date: Mon, 14 Oct 2024 03:27:56 +0000 (-0400) Subject: thing i gpted X-Git-Url: http://git.skullheadx.com/nixos/static/gitweb.css?a=commitdiff_plain;h=0681ff947765e360b8b750404e155eb7efcc787e;p=youtube-downloader.git thing i gpted --- diff --git a/Diamond is unbreakable - Main Theme.mp4 b/Diamond is unbreakable - Main Theme.mp4 new file mode 100644 index 0000000..e4e8445 Binary files /dev/null and b/Diamond is unbreakable - Main Theme.mp4 differ diff --git a/ytdl/__main__.py b/ytdl/__main__.py index 0a6919e..7a60290 100644 --- a/ytdl/__main__.py +++ b/ytdl/__main__.py @@ -1,6 +1,6 @@ import sys -from .funcmodule import check_playlist, get_audio_metadata_streams, download_audio_streams - +from .funcmodule import check_playlist, get_audio_metadata_stream, download_audio_stream +import concurrent.futures def main(): @@ -27,19 +27,38 @@ def main(): links = check_playlist(links) assert len(links) > 0, "Should be at least one song in playlist" - print("Getting audio streams and metadata") - streams, metadata = get_audio_metadata_streams(links) - assert len(streams) > 0, "was not able to get audio streams / metadata" - assert len(metadata) == len(streams), "make sure metadata for every stream" + audio_streams = [] + metadata_list = [] + + for link in links: + stream, metadata = get_audio_metadata_stream(link) + assert stream is not None, "was not able to get audio stream" + assert metadata is not None, "no metadata found" + audio_streams.append(stream) + metadata_list.append(metadata) - if arg == "-d": + assert len(audio_streams) > 0, "no audio streams found" + assert len(metadata_list) > 0, "no metadata found" + + if mode == "-d": pass - elif arg == "-a": - print("Downloading audio streams") - download_audio_streams(streams, metadata) - elif arg == "-v": + elif mode == "-a": + # Use ThreadPoolExecutor to run downloads concurrently + with concurrent.futures.ThreadPoolExecutor() as executor: + # Schedule the download_audio_stream function for each audio stream + futures = {executor.submit(download_audio_stream, stream, metadata): stream for stream, metadata in + zip(audio_streams, metadata_list)} + + # Optionally, you can wait for completion and handle exceptions + for future in concurrent.futures.as_completed(futures): + stream = futures[future] + try: + future.result() # This will raise an exception if the function raised one + except Exception as e: + print(f"Error downloading {stream.title}: {e}") + elif mode == "-v": pass - elif arg == "-av": + elif mode == "-av": pass diff --git a/ytdl/funcmodule.py b/ytdl/funcmodule.py index f3a04b7..02fe6bd 100644 --- a/ytdl/funcmodule.py +++ b/ytdl/funcmodule.py @@ -1,4 +1,4 @@ -from pytubefix import YouTube, Playlist, extract +from pytubefix import YouTube, Playlist import requests import subprocess import os @@ -14,26 +14,19 @@ def check_playlist(links): return links -def get_audio_metadata_streams(links): - audio_streams = [] - metadata = [] - - for link in links: - yt = YouTube(link) - yt.check_availability() - print(f"Fetching stream for {yt.title}") - assert len(yt.streams.filter(only_audio=True)) > 0, "No available audio streams" - audio_streams.append(yt.streams.filter(only_audio=True).order_by("abr").last()) - metadata.append( - { - "title": yt.title, - "artist": yt.author, - "thumbnail_url": yt.thumbnail_url, - "publish_date": yt.publish_date, - "views": yt.views - } - ) - return audio_streams, metadata +def get_audio_metadata_stream(link): + yt = YouTube(link) + yt.check_availability() + print(f"Fetching stream for {yt.title}") + assert len(yt.streams.filter(only_audio=True)) > 0, "No available audio streams" + yield yt.streams.filter(only_audio=True).order_by("abr").last() + yield { + "title": yt.title, + "artist": yt.author, + "thumbnail_url": yt.thumbnail_url, + "publish_date": yt.publish_date, + "views": yt.views + } def big_num_format(num): # https://stackoverflow.com/a/579376 magnitude = 0 @@ -43,29 +36,31 @@ def big_num_format(num): # https://stackoverflow.com/a/579376 return '%.1f%s' % (num, ['', 'K', 'M', 'B'][magnitude]) -def download_audio_streams(audio_streams, metadata): - for audio_stream, md in zip(audio_streams, metadata): - print(f"Downloading audio stream for {audio_stream.title}") - audio_stream.download() - data = requests.get(md["thumbnail_url"]).content - f = open('thumbnail.jpg', 'wb') +def download_audio_stream(audio_stream, metadata): + print(f"Downloading audio stream for {audio_stream.title}") + audio_stream.download() + + # create thumbnail file + data = requests.get(metadata["thumbnail_url"]).content + thumbnail_filename = f'{audio_stream.title}.jpg' + with open(thumbnail_filename, 'wb') as f: f.write(data) - f.close() - command = [ - 'ffmpeg', - '-i', audio_stream.default_filename, - '-i', "thumbnail.jpg", - '-map', '0', - '-map', '1', - '-metadata', f'title={audio_stream.title}', - '-metadata', f'artist={md["artist"]}', - '-metadata', f'date={md["publish_date"]}', - '-metadata', f'comment={big_num_format(md["views"]) + " views"}', - audio_stream.title + ".mp4", - '-y' - ] + command = [ + 'ffmpeg', + '-i', audio_stream.default_filename, + '-i', thumbnail_filename, + '-map', '0', + '-map', '1', + '-metadata', f'title={audio_stream.title}', + '-metadata', f'artist={metadata["artist"]}', + '-metadata', f'date={metadata["publish_date"]}', + '-metadata', f'comment={big_num_format(metadata["views"]) + " views"}', + audio_stream.title + ".mp4", + '-y' + ] + subprocess.run(command) - subprocess.run(command) - os.remove("thumbnail.jpg") - os.remove(audio_stream.default_filename) + # clean up tmp files + os.remove(thumbnail_filename) + os.remove(audio_stream.default_filename)