Random error when loading YouTube object
See original GitHub issueAfter fixing the issue at https://github.com/nficano/pytube/issues/723, I started receiving the following error randomly.
Enter the url of the video or playlist: https://www.youtube.com/watch?v=hyfV0GBe18w&
Traceback (most recent call last): File “D:\Documents\Programming\Python-YT-Downloader\Python-YT-Downloader\main.py”, line 106, in <module> video = YouTube(url) File “C:\Users\leowa\AppData\Local\Programs\Python\Python37\lib\site-packages\pytube_main_.py”, line 102, in init self.prefetch() File “C:\Users\leowa\AppData\Local\Programs\Python\Python37\lib\site-packages\pytube_main_.py”, line 203, in prefetch self.js_url = extract.js_url(self.watch_html) File “C:\Users\leowa\AppData\Local\Programs\Python\Python37\lib\site-packages\pytube\extract.py”, line 154, in js_url base_js = get_ytplayer_config(html)[“assets”][“js”] File “C:\Users\leowa\AppData\Local\Programs\Python\Python37\lib\site-packages\pytube\extract.py”, line 211, in get_ytplayer_config return json.loads(yt_player_config) File “C:\Users\leowa\AppData\Local\Programs\Python\Python37\lib\json_init_.py”, line 348, in loads return _default_decoder.decode(s) File “C:\Users\leowa\AppData\Local\Programs\Python\Python37\lib\json\decoder.py”, line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File “C:\Users\leowa\AppData\Local\Programs\Python\Python37\lib\json\decoder.py”, line 353, in raw_decode obj, end = self.scan_once(s, idx) json.decoder.JSONDecodeError: Unterminated string starting at: line 1 column 440 (char 439)
This error seems almost random, happening on almost any video and only happening sometimes.
Code:
# main.py
import subprocess
import sys
import get_pip
import re
def install(package):
subprocess.call([sys.executable, "-m", "pip", "install", package])
try:
from pytube import YouTube
from pytube import Playlist
except:
print('Import Error: PyTube3 not installed')
print('Attempting to install PyTube3 using pip')
try:
import pip
install('pytube3')
print('PyTube3 has been installed')
except:
print('Import Error: pip not installed')
print('Attempting to install pip')
get_pip.main()
print('Pip has been installed')
try:
print('Attempting to install PyTube3 using pip')
import pip
install('pytube3')
print('PyTube3 has been installed')
except:
print('PyTube3 could not be installed')
from pytube import YouTube
from pytube import Playlist
import pytube
def convert_time(seconds: int):
'''
Returns a string of the time in the most optimal units
Form: hours, minutes, seconds
'''
if seconds < 60:
return str(seconds) + ' seconds'
elif seconds < 3600:
return str(seconds // 60) + ' minutes ' + str(seconds % 60) + ' seconds'
else:
return str(seconds // 3600) + ' hours ' + str(seconds // 60) + ' minutes ' + str(seconds % 60) + ' seconds'
#####################################
# EDIT THESE
#####################################
download_dir = 'C:\\Users\\leowa\\Music'
audio_itag = 140 # streams have a specific identifying tag, 140 is 128kbps audio only
while True:
url = input('Enter the url of the video or playlist: ').rstrip()
print()
video = None
if 'list' in url:
video = []
playlist = Playlist(url)
playlist._video_regex = re.compile(r"\"url\":\"(/watch\?v=[\w-]*)")
# print(playlist.video_urls)
for v in playlist.video_urls:
try:
yt = YouTube(v)
video.append(yt)
print("Title :", yt.title)
print("Length :", convert_time(int(yt.length)))
print("Channel:", yt.author)
print()
except:
print("Error: Failed to load video at:", v)
print()
else:
#try:
video = YouTube(url)
#except:
#print("Couldn't find video at url:", url)
if video is not None:
# if its a playlist
if str(type(video)) == "<class 'list'>":
print("Videos :", len(video))
print()
if input("Download this playlist (Y or N): ").lower() == 'y':
print()
dl = input("Download video or audio: ")
print()
while dl.lower() != 'video' and dl.lower() != 'audio':
dl = input("Enter video or audio as download options: ")
print()
if dl.lower() == 'video':
res = input("Enter desired resolution (or high for highest avaliable): ")
if res.lower() == 'high':
for v in video:
stream = v.streams.get_highest_resolution()
if stream is None:
print("Failed to get stream for", v.title)
else:
print("Downloading:", v.title)
stream.download(output_path=download_dir, filename=v.title)
else:
for v in video:
stream = v.streams.get_by_resolution(res)
if stream is None:
print("Failed to get stream for", v.title)
else:
print("Downloading:", v.title)
stream.download(output_path=download_dir, filename=v.title)
elif dl.lower() == 'audio':
for v in video:
stream = v.streams.get_by_itag(audio_itag)
if stream is None:
print("Failed to get stream for", v.title)
else:
print("Downloading:", v.title)
stream.download(output_path=download_dir, filename=v.title)
print("Download complete at", download_dir)
# if its just a video
else:
print("Title : ", video.title)
print("Length : ", convert_time(int(video.length)))
print("Channel: ", video.author)
print()
# Uncomment this to see all stream types for a given video
'''
for s in video.streams:
print(s)
'''
if input("Download this video (Y or N): ").lower() == 'y':
dl = input("Download video or audio: ")
while dl.lower() != 'video' and dl.lower() != 'audio':
dl = input("Enter video or audio as download options: ")
print()
if dl.lower() == 'video':
res = input("Enter desired resolution (or high for highest avaliable): ")
if res.lower() == 'high':
stream = video.streams.get_highest_resolution()
else:
stream = video.streams.get_by_resolution(res)
elif dl.lower() == 'audio':
stream = video.streams.get_by_itag(audio_itag)
if stream is None:
print("Error: Unable to find given stream quality or resolution (make sure resolution is in the form xxxxp, example 1080p)")
else:
print("Downloading...")
stream.download(output_path=download_dir, filename=video.title)
print("Download complete at", download_dir)
print()
Issue Analytics
- State:
- Created 3 years ago
- Comments:11 (3 by maintainers)
Top GitHub Comments
I think I found the issue, see the commit message of the pull request for a short explanation
I’m currently having the same issue while trying to download a couple videos, but found it’s somehow related to youtube advertising policy.
Only thing that worked out for me was going to the video and skip the ad, then run the script again. Another workaround might be using a selenium bot to skip the ad when an error pops out.