#pip install git+https://github.com/JuanBindez/pytubefix.git # This works as of 02/01/2026 # This application accepts the name of a file the contents of which contain URL links to YouTube Videos. # An example of a line in such file might be https://www.youtube.com/watch?v=OmbWAsQaxzA&list=RDwCBfk8ZCMOU&index=12 # The program can download the video and also audio only # Since I am most interested in the audio that is what I have adopted below. # NOTE: The Video section below works and is left as an example to further develop as needed # Also. The files are downloaded from youtube in m4a format. I invoke ffmpeg to convert to mp3 # https://github.com/JuanBindez/pytubefix # Activate thge environment #.venv/scripts/activate from pytubefix import YouTube import os import traceback import subprocess ffmpeg_pathfile="c:\\download\\ffmpeg\\bin\\ffmpeg" download_folder = "./downloads" pathInputFileName = "C:\Python\DownloadYouTube\LIST.txt" class YouTubeDownloader: def __init__(self, pathUrlList): self.pathUrlList=pathUrlList self.urlList=[] def downloadMedia(self, audioOnly): self.readFile(self.pathUrlList) if None is self.urlList: return for item in self.urlList: self.getItem(item,audioOnly) def getItem(self, url, audioOnly): try: # Create a YouTube object yt = YouTube(url) if audioOnly: audio_stream = yt.streams.get_audio_only() # If you need more control, you could use filter(only_audio=True).first() to get the first available audio stream if audio_stream: print(f"Downloading audio: {yt.title} in {audio_stream.mime_type} format...") # 4. Download the file. The file is usually downloaded in m4a. out_file = audio_stream.download(output_path=download_folder) # Download to the downloads folder base, ext = os.path.splitext(out_file) # we convert the m4a into mp3 mp3file = base + '.mp3' processname = ffmpeg_pathfile+" -y -i \""+out_file+"\" -ab 320k -map_metadata 0 -id3v2_version 3 \""+mp3file+"\"" subprocess.run(processname, check=True) os.remove(out_file) print(f"Successfully downloaded and saved as: {os.path.basename(mp3file)}") else: print("No audio-only streams found.") return # Optional: Print the video title to confirm it's working print(f"Downloading video: {yt.title}") # Get the highest resolution progressive stream (contains both video and audio) # The get_highest_resolution() method simplifies this process video_stream = yt.streams.get_highest_resolution() video_stream.download() print("Download completed successfully!") except Exception as e: print(f"Error downloading {url}") print(f"Exception was : {e}") def readFile(self,pathFileName): try: with open(pathFileName,"r",encoding='utf-8') as inputStream: for line in inputStream: if None != line and 0!=len(line): strippedLine = line.strip() if 0!= len(strippedLine): self.urlList.append(strippedLine) inputStream.close() print(f"Read {len(self.urlList)} itemns from {pathFileName}") except: print(traceback.format_exc()) return(None) youTubeDownloader = YouTubeDownloader(pathInputFileName) youTubeDownloader.downloadMedia(True)