]> Skullheadx's Git Forge - youtube-downloader.git/commitdiff
add force
authorSkullheadx <94652084+Skullheadx@users.noreply.github.com>
Mon, 14 Oct 2024 17:33:45 +0000 (13:33 -0400)
committerSkullheadx <94652084+Skullheadx@users.noreply.github.com>
Mon, 14 Oct 2024 17:33:45 +0000 (13:33 -0400)
README.md
requirements.txt
ytdl/__main__.py
ytdl/__pycache__/__main__.cpython-312.pyc
ytdl/__pycache__/funcmodule.cpython-312.pyc
ytdl/funcmodule.py

index ce4731c4b446b2c3dcb2d78a1138de4f30a6f6fc..e366830c3d277141849e83c3d834ed1bb7e23154 100644 (file)
--- a/README.md
+++ b/README.md
@@ -9,11 +9,11 @@ downloads the audio and video and stitches it together in the current directory.
 - `-a` - audio only
 - `-v` - video only
 - `-av` - audio + video separate
-
+- `-f` - force replace if file exists
 
 # TODO:
-- [ ] add video only
+- [x] add video only
 - [ ] add audio + video separate
 - [ ] add stitched together
-- [ ] add force replace
-- [ ] add album
\ No newline at end of file
+- [x] add force replace
+- [ ] add album name
index 4b5e95b854b9f3dd74992e3dcb3159ce178446b7..e28755497e2150ce6e148befd011e74642ab8bc6 100644 (file)
@@ -1,2 +1,3 @@
 pytubefix~=8.0.0
-ffmpeg-python
+requests~=2.32.3
+ffmpeg
\ No newline at end of file
index 5f299316ad15ef222370b6ecaa70ab7214ed857e..8c7b198d648ff7c6c8cea0274f8397ce7d59b3bc 100644 (file)
@@ -9,11 +9,13 @@ def main():
 
     links = []
     mode = "-d"
+    force = False
     assert len(args) > 0, "no args :("
     for arg in args:
         if arg in modes:
             mode = arg
-
+        if arg == '-f': # force
+            force = True
         if "youtube" in arg or "youtu.be" in arg:
             links.extend(arg.split(" "))
 
@@ -27,18 +29,10 @@ def main():
     links = check_playlist(links)
     assert len(links) > 0, "Should be at least one song in playlist"
 
-    if mode == "-d":
-        pass
-    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(get_and_download, link): link for link in links}
-
-    elif mode == "-v":
-        pass
-    elif mode == "-av":
-        pass
+    # 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(get_and_download, link, mode, force): link for link in links}
 
 
 if __name__ == '__main__':
index 446f645b253662be92cb07d522982f0eee3aa86d..500e48998f4c7f9e96dca406be80ceaf58a9cef1 100644 (file)
Binary files a/ytdl/__pycache__/__main__.cpython-312.pyc and b/ytdl/__pycache__/__main__.cpython-312.pyc differ
index f16f7650d8d95161ba2524f2a95014f40a41f79b..8d42a165efac31556f9e183f8406eb9620c507fb 100644 (file)
Binary files a/ytdl/__pycache__/funcmodule.cpython-312.pyc and b/ytdl/__pycache__/funcmodule.cpython-312.pyc differ
index b59bf318aa18108073135627d1e4e5fafe514020..bc52f5e6624f702d054a13a4897c86aee5265ceb 100644 (file)
@@ -30,44 +30,53 @@ def fix_filename(filename):
     return filename
 
 
-def get_and_download(link):
+def download_thumbnail(thumbnail_url, thumbnail_filename):
+    data = requests.get(thumbnail_url).content
+    with open(thumbnail_filename, 'wb') as f:
+        f.write(data)
+
+def get_and_download(link, mode, force=False):
     yt = YouTube(link)
-    if fix_filename(yt.title) + '.mp4' in glob.glob("*.mp4"):
+    filename = fix_filename(yt.title)
+    if (filename + '.mp4' in glob.glob("*.mp4")) and not force:
         print(f"{yt.title} is already downloaded")
         return
-
     yt.check_availability()
-    print(f"Fetching stream for {yt.title}")
 
-    assert len(yt.streams.filter(only_audio=True)) > 0, "No available audio streams"
-    audio_stream = yt.streams.filter(only_audio=True).order_by("abr").last()
+    print(f"Fetching stream for {yt.title}")
+    stream = None
+    if mode == "-a":
+        assert len(yt.streams.filter(only_audio=True)) > 0, "No available audio streams"
+        stream = yt.streams.filter(only_audio=True).order_by("abr").last()
+    if mode == "-v":
+        assert len(yt.streams.filter(only_video=True)) > 0, "No available video streams"
+        stream = yt.streams.filter(only_video=True).order_by("resolution").last()
 
-    print(f"Downloading audio stream for {yt.title}")
-    audio_stream.download(filename=fix_filename(audio_stream.default_filename), skip_existing=True)
+    assert stream is not None, "mode is not valid"
+    print(f"Downloading stream for {yt.title}")
+    default_filename = "default " + fix_filename(stream.default_filename)
+    stream.download(filename=default_filename, skip_existing=True)
 
-    # create thumbnail file
-    data = requests.get(yt.thumbnail_url).content
-    thumbnail_filename = f'{fix_filename(audio_stream.title)}.jpg'
-    with open(thumbnail_filename, 'wb') as f:
-        f.write(data)
+    thumbnail_filename = f'{filename}.jpg'
+    download_thumbnail(yt.thumbnail_url, thumbnail_filename)
 
     command = [
         'ffmpeg',
-        '-i', fix_filename(audio_stream.default_filename),
+        '-i', default_filename,
         '-i', thumbnail_filename,
         '-map', '1',
         '-map', '0',
         '-c', 'copy',
         '-disposition:v:0', 'attached_pic',
-        '-metadata', f'title={fix_filename(yt.title)}',
+        '-metadata', f'title={filename}',
         '-metadata', f'artist={yt.author}',
         '-metadata', f'comment={big_num_format(yt.views) + " views"}',
         '-metadata', f'date={yt.publish_date}',
-        fix_filename(audio_stream.title) + ".mp4",
+        filename + ".mp4",
         '-y'
     ]
     subprocess.run(command)
 
     # clean up tmp files
     os.remove(thumbnail_filename)
-    os.remove(fix_filename(audio_stream.default_filename))
+    os.remove(default_filename)