-# youtube-downloader
+# Youtube Downloader - ytdl
+
+## usage
+```shell
+ytdl "https://music.youtube.com/watch?v=lYBUbBu4W08&si=z03FVSmqqyxKZFmZ"
+```
+downloads the audio and video and stitches it together in the current directory. Automatically detects playlists.
+
+- `-a` - audio only
+- `-v` - video only
+- `-av` - audio + video separate
-HOW TO USE
-- Enter links into the links_file.txt file each on a new line.
- - You can even put links to playlists too!
-- Run the main.py file using python
-- Enjoy your newly downloaded videos in the "downloaded" folder. (audio and video streams are available in the respective folders in downloaded)
--- /dev/null
+pip install -e .
\ No newline at end of file
-https://www.youtube.com/watch?app=desktop&v=lW4KseyDqcY
-https://www.youtube.com/watch?v=nJ7ZCN0m14A
-https://www.youtube.com/watch?app=desktop&v=VvWX3vRRLME
-https://www.youtube.com/watch?v=iCx2nBfu54I
-https://www.youtube.com/watch?app=desktop&v=V2hrTDS4Ml4
-https://www.youtube.com/watch?app=desktop&v=_Sd11FWbvZ8
-https://www.youtube.com/watch?v=HDOIQZZoABg
-https://www.youtube.com/watch?v=j-ttaqEzXKM
-https://www.youtube.com/watch?app=desktop&v=UMiW3G1USHg#dialog
-https://www.youtube.com/watch?v=uPG77Gtn0Ws
-https://www.youtube.com/watch?app=desktop&v=7cKGmeTY9eg
-https://www.youtube.com/watch?app=desktop&v=Pfs9yAsRbaU
-https://www.youtube.com/watch?v=WxKbU98GLRY
-https://www.youtube.com/watch?v=9MzCxt1QpWg
-https://www.youtube.com/watch?v=jCaug9SkKEI
-https://www.youtube.com/watch?v=V19v3oNPixQ
-https://www.youtube.com/watch?v=NscXXbmAggI
-https://www.youtube.com/watch?v=iCx2nBfu54I
-https://www.youtube.com/watch?v=9pq-G57iSEQ
-https://www.youtube.com/watch?v=XVRno3Y1TX8
-https://www.youtube.com/watch?v=codyY_-AiXc
-https://www.youtube.com/watch?v=qZ2yWvholHw
-https://www.youtube.com/watch?v=wodcSTIxZtw
-https://www.youtube.com/watch?v=btKTE4eMPf4
-https://www.youtube.com/watch?v=kW-WE5zrJsg
-https://www.youtube.com/watch?v=i5M-WHDhQ4c
+https://music.youtube.com/watch?v=lYBUbBu4W08&si=z03FVSmqqyxKZFmZ
+++ /dev/null
-from pytubefix import YouTube, Playlist
-from pytubefix.exceptions import VideoUnavailable
-import ffmpeg
-
-
-RES = ["1440p", "1080p", "720p", "480p", "360p", "240p", "144p"]
-ABR = ["160kbps", "128kbps", "70kbps", "50kbps", "48kbps"]
-target_res = 0
-target_abr=0
-
-failed_download = set()
-
-if __name__ == "__main__":
-
- # get list of links from file
- links = []
- with open('links.txt', 'r') as f:
- links = f.read().split('\n')
- if links[-1] == "":
- links = links[:-1]
-
- for link in links:
- if "playlist" in link:
- p = Playlist(link)
- for url in p.video_urls:
- links.append(url)
- links.remove(link)
-
-
- # download links one by one
- for link in links:
- target_res = 0
- target_abr = 0
- video_success = True
- audio_success = True
-
- try:
- yt = YouTube(link)
- yt.streams
-
- except VideoUnavailable:
- print(f'Video {link} is unavaialable, skipping.')
- failed_download.add(((yt.title, link)))
- else:
- video_streams = []
- while len(video_streams) == 0:
- video_streams = yt.streams.filter(file_extension='mp4', res=RES[target_res]) # find available streams
- if target_res + 1 < len(RES):
- target_res = target_res + 1
- else:
- video_success = False
- break
- if not video_success:
- print(f"Unable to find video stream for {yt.title}")
- failed_download.add(((yt.title, link)))
-
- break
- vstream = video_streams[0]
-
- # audio
- audio_streams = []
- while len(audio_streams) == 0:
- audio_streams = yt.streams.filter(only_audio=True, abr=ABR[target_abr]) # find available streams
-
- if target_abr + 1 < len(RES):
- target_abr = target_abr + 1
- else:
- audio_success = False
- break
- if not audio_success:
- print(f"Unable to find audio stream for {yt.title}")
- failed_download.add(((yt.title, link)))
-
- break
- astream = audio_streams[0]
-
- vstream.download(output_path="downloaded/video_only")
- astream.download(output_path="downloaded/audio_only")
-
- input_video = ffmpeg.input(f"downloaded/video_only/{vstream.default_filename}")
- input_audio = ffmpeg.input(f"downloaded/audio_only/{astream.default_filename}")
-
- ffmpeg.concat(input_video, input_audio, v=1, a=1).output(f'downloaded/{yt.title}.mp4').run()
-
-print("Failed Downloading:")
-print(failed_download)
-
--- /dev/null
+from setuptools import setup
+setup(
+ name = 'ytdl',
+ version = '0.1.0',
+ packages = ['ytdl'],
+ entry_points = {
+ 'console_scripts': [
+ 'ytdl = ytdl.__main__:main'
+ ]
+ })
\ No newline at end of file
--- /dev/null
+Metadata-Version: 2.1
+Name: ytdl
+Version: 0.1.0
+License-File: LICENSE
--- /dev/null
+LICENSE
+README.md
+setup.py
+ytdl/__init__.py
+ytdl/__main__.py
+ytdl/classmodule.py
+ytdl/funcmodule.py
+ytdl/main.py
+ytdl.egg-info/PKG-INFO
+ytdl.egg-info/SOURCES.txt
+ytdl.egg-info/dependency_links.txt
+ytdl.egg-info/entry_points.txt
+ytdl.egg-info/top_level.txt
\ No newline at end of file
--- /dev/null
+[console_scripts]
+ytdl = ytdl.__main__:main
--- /dev/null
+modes = ["-d", "-a", "-v", "-av"]
+
+ABR = ["160kbps", "128kbps", "70kbps", "50kbps", "48kbps"]
+
--- /dev/null
+from .__init__ import *
+import sys
+from .classmodule import MyClass
+from .funcmodule import check_playlist, links_work, download_audio
+
+def main():
+ args = sys.argv[1:]
+
+ links = []
+ mode = "-d"
+ for arg in args:
+ print('passed argument :: {}'.format(arg))
+ if arg in modes:
+ mode = arg
+
+ if "youtube.com" in arg:
+ links.extend(arg.split(" "))
+
+
+ assert len(links) > 0, "Should pass at least one link as arg"
+ assert mode in modes, f"Mode should be one of {modes}"
+
+ # remove empty strings
+ links = list(filter(None, links))
+ assert len(links) > 0, "Should not remove all links"
+
+ links = check_playlist(links)
+ assert len(links) > 0, "Should be at least one song in playlist"
+
+ #assert links_work(links), "Links don't work :("
+
+ if arg == "-d":
+ pass
+ elif arg == "-a":
+ download_audio(links)
+ elif arg == "-v":
+ pass
+ elif arg == "-av":
+ pass
+
+
+if __name__ == '__main__':
+ main()
+
+
--- /dev/null
+class MyClass():
+ def __init__(self, name):
+ self.name = name
+
+ def say_name(self):
+ print('name is {}'.format(self.name))
--- /dev/null
+from .__init__ import *
+from pytube import YouTube, Playlist
+from pytube.exceptions import VideoUnavailable
+import ffmpeg
+
+
+
+def check_playlist(links):
+ for link in links:
+ if "playlist" in link:
+ p = Playlist(link)
+ for url in p.video_urls:
+ links.append(url)
+ links.remove(link)
+ return links
+
+def links_work(links):
+ for link in links:
+ YouTube(link).check_availability()
+ return True
+
+
+def download_audio(links, target_abr="160kbps"):
+ print(links, ABR)
+ print('a')
+ for link in links:
+ yt = YouTube(link)
+ # assert yt.includes_audio_track()
+ print(yt.streams.filter(only_audio=True))
+ print(yt.streams)
+
+
+
+
+
+
+
+
+
+
+# RES = ["1440p", "1080p", "720p", "480p", "360p", "240p", "144p"]
+# ABR = ["160kbps", "128kbps", "70kbps", "50kbps", "48kbps"]
+# target_res = 0
+# target_abr=0
+
+# get list of links from file
+# links = []
+# with open('links.txt', 'r') as f:
+# links = f.read().split('\n')
+# if links[-1] == "":
+# links = links[:-1]
+# print(links)
+
+
+
+# # download links one by one
+# for link in links:
+# target_res = 0
+# target_abr = 0
+# video_success = True
+# audio_success = True
+
+# try:
+# yt = YouTube(link)
+# yt.streams
+
+# except VideoUnavailable:
+# print(f'Video {link} is unavaialable, skipping.')
+# failed_download.add(((yt.title, link)))
+# else:
+# video_streams = []
+# while len(video_streams) == 0:
+# video_streams = yt.streams.filter(file_extension='mp4', res=RES[target_res]) # find available streams
+# if target_res + 1 < len(RES):
+# target_res = target_res + 1
+# else:
+# video_success = False
+# break
+# if not video_success:
+# print(f"Unable to find video stream for {yt.title}")
+# failed_download.add(((yt.title, link)))
+
+# break
+# vstream = video_streams[0]
+
+# # audio
+# audio_streams = []
+# while len(audio_streams) == 0:
+# audio_streams = yt.streams.filter(only_audio=True, abr=ABR[target_abr]) # find available streams
+
+# if target_abr + 1 < len(RES):
+# target_abr = target_abr + 1
+# else:
+# audio_success = False
+# break
+# if not audio_success:
+# print(f"Unable to find audio stream for {yt.title}")
+# failed_download.add(((yt.title, link)))
+
+# break
+# astream = audio_streams[0]
+
+# vstream.download(output_path="downloaded/video_only")
+# astream.download(output_path="downloaded/audio_only")
+
+# input_video = ffmpeg.input(f"downloaded/video_only/{vstream.default_filename}")
+# input_audio = ffmpeg.input(f"downloaded/audio_only/{astream.default_filename}")
+
+# ffmpeg.concat(input_video, input_audio, v=1, a=1).output(f'downloaded/{yt.title}.mp4').run()
+
+# print("Failed Downloading:")
+# print(failed_download)