I'm been fighting with this for a while. I wrote a small front end for a YouTube downloader using pytube. For some reason, I get a 'streamingData' error every time I try to download a video. I tried several different ways of getting streams, but can't get it to work. I put in a few print statements and basically, the YouTube link is correct, but then it doesn't get to the if statement on line 14 and bombs out at the video = yt_object.streams.get_highest_resolution()
on line 13 throwing the exception error of 'streamingData'. I'm running the latest version of pytube
(12.1.3)
. My source code is:
import os
import tkinter
import customtkinter
from pytube import YouTube
def start_download():
try:
yt_link = link.get()
print(yt_link)
yt_object = YouTube(yt_link, on_progress_callback=on_progress)
print(1)
video = yt_object.streams.get_highest_resolution()
if video:
print(2)
title.configure(text=yt_object.title, text_color="white")
print(3)
finish_label.configure(text="")
print(4)
video.download(output_path=f"{os.environ['UserProfile']}/Downloads")
print(5)
finish_label.configure(text='Download complete.')
else:
print("No highest resolution stream available.")
except Exception as e:
finish_label.configure(text=f"An error occurred: {e}", text_color="red")
def on_progress(stream, chunk, bytes_remaining):
total_size = stream.filesize
bytes_downloaded = total_size - bytes_remaining
percentage_of_completion = bytes_downloaded / total_size * 100
per = str(int(percentage_of_completion))
progress_percentage.configure(text=f"{per}%")
# Update progress bar
progress_bar.set(float(percentage_of_completion / 100))
# System Settings
customtkinter.set_appearance_mode("Dark")
customtkinter.set_default_color_theme("blue")
# Create the app frame
app = customtkinter.CTk()
app.geometry("720x480")
app.title("YouTube Downloader")
# Adding UI elements
title = customtkinter.CTkLabel(app, text="Insert a YouTube link:")
title.pack(padx=10, pady=10)
# Link input
url_var = tkinter.StringVar()
link = customtkinter.CTkEntry(app, width=350, height=40, textvariable=url_var)
link.pack()
# Finished downloading
finish_label = customtkinter.CTkLabel(app, text="")
finish_label.pack()
# Progress percentage
progress_percentage = customtkinter.CTkLabel(app, text="0%")
progress_percentage.pack()
progress_bar = customtkinter.CTkProgressBar(app, width=400)
progress_bar.set(0)
progress_bar.pack(padx=10, pady=10)
# Download button
download = customtkinter.CTkButton(app, text="Download", command=start_download)
download.pack(padx=10, pady=10)
# Run app
app.mainloop()
Any thoughts or suggestions would be welcome! I even asked ChatGPT for help to no avail.
In following ewokx's recommendations, it throws this error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Robert\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "C:\Users\Robert\PycharmProjects\YouTubeDownloader\venv\Lib\site-packages\customtkinter\windows\widgets\ctk_button.py", line 553, in _clicked
self._command()
File "C:\Users\Robert\PycharmProjects\YouTubeDownloader\main.py", line 12, in start_download
video = yt_object.streams.get_highest_resolution()
^^^^^^^^^^^^^^^^^
File "C:\Users\Robert\PycharmProjects\YouTubeDownloader\venv\Lib\site-packages\pytube\__main__.py", line 296, in streams
return StreamQuery(self.fmt_streams)
^^^^^^^^^^^^^^^^
File "C:\Users\Robert\PycharmProjects\YouTubeDownloader\venv\Lib\site-packages\pytube\__main__.py", line 176, in fmt_streams
stream_manifest = extract.apply_descrambler(self.streaming_data)
^^^^^^^^^^^^^^^^^^^
File "C:\Users\Robert\PycharmProjects\YouTubeDownloader\venv\Lib\site-packages\pytube\__main__.py", line 161, in streaming_data
return self.vid_info['streamingData']
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
KeyError: 'streamingData'
I was able to figure it out. Basically, YouTube (well, the channel uploaders) mark most videos as 18+ and that causes PyTube to crap the bed. So, you need to set up authorization for the app to allow it to work. To fix this issue, I needed to add/change the following line:
yt_object = YouTube(yt_link, on_progress_callback=on_progress, use_oauth=True, allow_oauth_cache=True)
Now, the problem is that it send the auth dialog to the console and I can't figure out how to capture the code and display it in the GUI so I can make it a stand alone program...but that's another battle.
Thanks to ewokx for trying to help!