Issues with downloading (Viewer Discretion is advised) videos on YouTube with PyTube - python

I have been creating a program to grab links from a YouTube playlist and download the individual links but I noticed if you try to download a video that has a "Viewer Discretion is Advised" warning label attached to the video I get an error that reads "Streaming Error"
from pytube import YouTube
from pytube import Playlist
import os
#---------------------------------------------
youtube = True
is_playlist = False
convert_to_mp3 = True
youtube_playlist_name = "Folder Name"
youtube_playlist_videos = [""]
#---------------------------------------------
spotify = False
spotify_playlist_name = ""
spotify_playlist = [""]
#---------------------------------------------
def download_and_convert_video(link, playlist_name, x, urls):
video = link.streams.get_audio_only()
out_file = video.download(output_path=f"audio/{playlist_name}")
base = os.path.splitext(out_file)
new_file = f"{base[0]}.mp3"
print(f"Downloading \"{new_file[new_file.find(playlist_name) + len(playlist_name) + 1:len(new_file)]}\" - {x+1}/{len(urls)}")
os.rename(out_file, new_file)
def obtain_urls(playlists):
urls, x = [], 0
print("Locating videos in playlist")
for playlist in playlists:
playlist_urls = Playlist(playlist)
for url in playlist_urls:
x += 1
urls.append(url)
print(f"{x} video(s) located")
return urls
def download_from_youtube(playlist, playlist_name, convert_to_mp3, is_playlist):
if is_playlist == True:
urls = obtain_urls(playlist)
if is_playlist == False:
urls = playlist
for x in range(len(urls)):
if convert_to_mp3 == True:
download_and_convert_video(YouTube(urls[x]), playlist_name, x, urls)
if convert_to_mp3 == False:
download_video(YouTube(urls[x]), playlist_name)
print(f"Successfully downloaded {len(urls)} video(s)")
def download_video(video, playlist_name):
video = video.streams.get_highest_resolution()
video.download(f"video/{playlist_name}")
if youtube == True:
download_from_youtube(youtube_playlist_videos, youtube_playlist_name, convert_to_mp3, is_playlist)

I found this video k8jw3JVfK0w with the The following content may contain suicide or self-harm topics.
Viewer discretion is advised. Learn more you mentioned, with youtube-dl downloading this video works fine, please give it a try.

Related

How to get user input for a python script and use it in another program?

I want to get user input used in another program as a input for url and path. But thats seems to be impossible.
#mymodule.py script
from pytube import YouTube
import pytube
# import check_avail
class vdodownload:
def __init__(self,url,path):
self.url = url
self.path = path
def link(self):
try:
print(f'Downloading video: {YouTube(self.url).title}')
# yt = check_avail.video(self.url,self.path)
YouTube(self.url).streams.first().download(self.path)
print(f'Downloaded video: {YouTube(self.url).title}')
except pytube.exceptions.ExtractError:
print(f'Video {self.url} is unavaialable, skipping.')
# else:
# print(f'Downloading video: {self.url}')
# yt.streams.first().download(self.path)
# print(f'Downloaded video: {self.url}')
url = input("Enter the video URL: ")
path = input("Enter the path: ")
t = vdodownload(url,path)
t.link()
#check_avail.py script
from pytube import YouTube
if __name__ == "__main__":
def video(url,path):
y = YouTube(url)
# video1 = YouTube(url).streams.first().download(path)
# print(f"title:{YouTube(url).title}, views:{YouTube(url).views}, Length:{YouTube(url).length}")
print("Successfully done")
return video
else:
def check(func):
def parameters(u,v):
print(f"title:{YouTube(u).title}, views:{YouTube(u).views}, Length:{YouTube(u).length}")
return func(u,v)
return parameters
# return check
def filtering(func):
def param(u,v):
check1 = YouTube(u).streams.filter(type='video',progressive=True,file_extension='mp4')
print(check1)
return func(u,v)
return param
# return filtering
#filtering
#check
def video(url,path):
y = YouTube(url)
# video1 = YouTube(url).streams.first().download(path)
print("Success")
return video
url = input("Enter input url here: ")
path = input("Enter path here: ")
video(url,path)
I want to get user input from another python script named mymodule.py for check_avail.py input for url and path. I have searched online but no good answer.
can anyone help me?
After so many search I found an answer.
If you are creating a class of methods in a python program and use user-defined variables from another python script you have to create a object in that python script from where you need to import it.
<--create scrpit1.py-->
from pytube import YouTube
def video(url,path):
y = YouTube(url)
video1 = YouTube(url).streams.first().download(path)
print("Success")
return video
url = input("Enter input url here: ")
path = input("Enter path here: ")
<---- Create a object here so that you can import and use anywhere-->
t = video(url,path)
script2.py
<---Use imported variables-->
from pytube import YouTube
import pytube
# import check_avail
class vdodownload:
<-- accessing it from another script and initialise to another variable-->
def __init__(self,url,path):
self.url = t.url
self.path = t.path
<-- or you can directly use it here by giving t.url -->
def link(self):
try:
print(f'Downloading video: {YouTube(t.url).title}')
# yt = check_avail.video(t.url,t.path)
YouTube(t.url).streams.first().download(t.path)
print(f'Downloaded video: {YouTube(t.url).title}')
This is one way of doing it. Pls correct it if any changes needed.

YouTube categories in Python

I am new to categories in youtube api in Python and I'm encountering issues regarding the language of the videos after I select the region to find videos in.
The problem that I am encountering is that when I enter a region code, it comments on videos that aren't in English even though it's meant to be.
E.G: I enter the region code 'US' and the outcome is what I have attached. It comments on videos that are in a different language.
result [![enter image description here][1]][1]
I have tried to change the region_code="US" in the script but it has problems with 'US' not being defined.
Does anyone know how I can get around this problem or what I'm doing wrong? Thanks
API_KEY = "key"
# This function loads the comments in Comments.txt file
def load_comments(file):
comments = []
f = open(file, 'r', encoding='utf8')
for comment in f:
comments.append(comment)
return comments
def search_video(keyword, region_code, comments):
# Fucntion from Library
from apiclient.discovery import build
import datetime
import time
def get_category_id(youtube, cat):
req = youtube.videoCategories().list(part='snippet', regionCode=region_code)
response = req.execute()
items_list = response["items"]
for item in items_list:
video_category_id = item.get("id")
if video_category_id is not None:
return video_category_id
def search(youtube, video_category_id=None):
if video_category_id is None:
video_category_id = get_category_id(youtube, keyword)
req = youtube.search().list(videoCategoryId=video_category_id, order='date', maxResults=len(comments), # q=keyword,
publishedAfter=(datetime.datetime.utcnow() +
datetime.timedelta(minutes = -1)).isoformat('T')+'Z',
part='snippet',type='video')
return req, video_category_id
api_key = API_KEY
youtube = build('youtube', 'v3', developerKey=api_key)
req, video_category_id = search(youtube)
res = req.execute()
while len(res['items']) == 0:
time.sleep(10)
req, _ = search(youtube, video_category_id) # re-use category id if already found to prevent lag
res = req.execute()
videoid = [res['items'][i]['id']['videoId'] for i in range(len(res['items']))]
return videoid
(It asks what region to use btw)

How to remove "assets" error in pytube in python?

I had made a youtube video downloader using pytube in python. It previously works fine but during sometime it gives an error of "assets". I had tried a lot but I can't solve it. I had also tried to search error solution but I can't found anything like that.
Here is my code
def startDownload(url):
global file_size
path_to_save = askdirectory()
if path_to_save is None:
return
try:
global MaxFileSize, fileSizeInBytes
choice = youtubeChoicesLabel.get()
url=urlField.get()
yt = YouTube(url)
nome = yt.title
if (choice == download_choices[1]):
print("720p video is downloading")
selectVideo = yt.streams.filter(progressive=True, file_extension='mp4').first()
elif (choice == download_choices[2]):
print("144 video is downloading")
selectVideo = yt.streams.filter(progressive=True, file_extension='mp4').last()
selectVideo = yt.streams.filter(only_audio=True).first()
elif (choice == download_choices[0]):
return
fileSizeInBytes = selectVideo.filesize
MaxFileSize = fileSizeInBytes/1024000
MB =str(MaxFileSize)+ "MB"
print("File Size = : {:00.000f}".format (MaxFileSize))
st= selectVideo
yt.register_on_complete_callback(complete_download)
yt.register_on_progress_callback(progress_download)
file_size=st.filesize
st.download(output_path=path_to_save)
except Exception as e:
print(e)
download_choices = ["----Download Type----",
"Mp4 720p",
"Mp4 144p",
# "Video 3gp",
"Audio Mp3"]
def btnClicked():
try:
downloadBtn['text'] = "Please wait....."
downloadBtn["bg"] = "red"
downloadBtn["fg"] ="white"
downloadBtn['state']= 'disabled'
url=urlField.get()
if url == '':
showinfo("Message","Please input a url of the video.....")
return
print(url)
thread= Thread(target=startDownload,args=(url,))
thread.start()
except Exception as e:
print(e)
Here is my error
soham#LAPTOP-FJLV55TK MINGW64 ~
y"python "e:/python projects/YOUTUBE VIDEO DOWNLOADER/YOUTUBE_VIDEO_DOWNLOADER.py
e:/python projects/YOUTUBE VIDEO DOWNLOADER/YOUTUBE_VIDEO_DOWNLOADER.py
https://www.youtube.com/watch?v=rTuxUAuJRyY
'assets'
I had the same problem and updating pytube to the latest version available currently the problem disappeared.
pip install pytube==10.0.0
or
pip install --upgrade pytube
Similar question.

Youtube V3 API doesn't sort video

So I have been using youtube api to scrape a channel. Everything was working fine until 3 days ago (03/15/2019) when the result isn't sorted anymore. It seems that no matter what I put in the order parameter, the results are all the same. Can anyone tell me why it isn't working? Here's the code snippet:
import re
import os
import json
import MySQLdb
from pytube import YouTube
import urllib
import isodate
import sys
def get_all_video_in_channel(channel_id):
api_key = '<MY KEY>'
video_url = 'https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails&id={}&key={}'
first_url = 'https://www.googleapis.com/youtube/v3/search?key={}&channelId={}&part=snippet,id&order=date&maxResults=50'.format(api_key, channel_id) #order by date but won't work
res = []
url = first_url
while True:
inp = urllib.urlopen(url)
resp = json.load(inp)
vidIds = []
for jobject in resp['items']:
if jobject['id']['kind'] == "youtube#video":
vidIds.append(jobject['id']['videoId'])
vidreq = urllib.urlopen(video_url.format(",".join(vidIds),api_key))
vidres = json.load(vidreq)
for vidjson in vidres['items']:
res.append(vidjson)
if (len(res) >= 50):
break
try:
next_page_token = resp['nextPageToken']
url = first_url + '&pageToken={}'.format(next_page_token)
except:
break
return res
c_id = 'UCycyxZMoPwg9cuRDMyQE7PQ'
episodes = get_all_video_in_channel(c_id)
Edit: I did some more research and people say that the API indeed is not working properly due to Youtube doing something with deleting the New Zealand shooting video and it will soon be working properly again.
I recommend you to see the answer https://stackoverflow.com/a/55220182/8327971. This is a known and acknowledged issue by Google: https://issuetracker.google.com/issues/128673552.

creating multiple audio streams of an icecast2 server using python-shout

I am trying to create a web radio server to stream 3 sources at once. I am using python to create a source client for icecast2 using the python-shout library. I am not too familiar with the language (python). however, i got a sample program which does what i need to and more and i have tweaked it for my need. However, I can only create two streams, and after that, i get the error message shown below. I don't know what i'm doing wrong so i hope you guys can help me figure that out.
hostname ="localhost"
port= 8000
password = "password"
import shout
import sys
import threading
from glob import glob
from random import shuffle,choice
class RunStream (threading.Thread):
def __init__ (self, channel_mount, music_directory, station_url, genre,name, description, bitrate="128", samplerate="44100", channels="5",music_format="mp3", ogv=0):
#connection to icecast
global hostname,port,password
self.song_conter= 0
self.s = shout.Shout()
self.s.audio_info = {shout.SHOUT_AI_BITRATE:bitrate, shout.SHOUT_AI_SAMPLERATE:samplerate, shout.SHOUT_AI_CHANNELS:channels}
self.s.name = name
self.s.url = station_url
self.s.mount = channel_mount
self.s.port = port
self.ogv = ogv
self.s.password = password
self.s.genre = genre
self.music_directory = music_directory
self.s.description = description
self.s.host = hostname
self.s.format = music_format #using mp3 but it can also be ogg vorbis
print self.s.open()
threading.Thread.__init__ (self)
#checking directories for files to stream
def scan_directories(self):
self.files_array = glob(self.music_directory+"/*.[mM][Pp]3") + glob(self.music_directory+"/*/*.[mM][Pp]3") + glob(self.music_directory+"/*/*/*.[mM][Pp]3") #checks the specified directory down to the third depth
print str(len(self.files_array))+" files" #display number of matching files found
shuffle(self.files_array) # randomize playlist
def run (self):
while 1: #infinity
self.scan_directories() # rescan dir, maybe in time you add some new songs
self.song_counter = 0
for e in self.files_array:
self.write_future()
self.sendfile(e)
self.song_counter = self.song_counter + 1
def format_songname(self,song): # format song name - on filename (strip "mp3", change _ to " ". Formatting name of song for writing into a text file
result = song.split("/")[-1].split(".")
result = ".".join(result[:len(result)-1]).replace("_"," ").replace("-"," - ")
return result
def write_future(self): #write playlist
filename = self.s.mount.replace("/","")+"-current.txt"
fa = open(filename,"w")
aid = self.song_counter
pos = 7 # CHANGE if you want more songs in future playlist
for s in self.files_array[aid:]:
fa.write(self.format_songname(s)+"\n")
pos = pos - 1
if (pos==0):
break
if (pos>0):
for s in self.files_array[:pos+1]:
fa.write(self.format_songname(s)+"\n")
fa.close()
def sendfile(self,fa):
print "opening file %s" % fa
f = open(fa)
self.s.set_metadata({'song': self.format_songname(fa)})
nbuf = f.read(4096)
while 1:
buf = nbuf
nbuf = f.read(4096)
if len(buf) == 0:
break
self.s.send(buf)
self.s.sync()
f.close()
#running the first stream
RunStream(channel_mount = "/stream", music_directory = "/home/CUWebRadio1/music_one", station_url = "http://webradio.com", genre = "new",name = "Web Radio Channel2", description = "bla bla bla").start()
#running the second stream
RunStream(channel_mount = "/stream_2", music_directory = "/home/CUWebRadio1/music_twos", station_url = "http://webradio.com", genre = "music",name = "Web Radio Music", description = "bla bla bla").start()
#running the Third Stream
RunStream(channel_mount = "/stream_3", music_directory = "/home/CUWebRadio1/music_three", station_url = "http://webradio.com", genre = "Music",name = "CU Web Radio Music3", description = "bla bla bla").start()
the Error message i get
Traceback (most recent call last):
File "new_threads.py", line 96, in <module>
RunStream(channel_mount = "/stream_3", music_directory = "/home/CUWebRadio1/music_three", station_url = "http://webradio.com", genre = Music",name = "CU Web Radio Music3", description = "bla bla bla").start()
File "new_threads.py", line 37, in __init__
print self.s.open()
shout.ShoutException: Login failed
Any help would be greatly appreciated.
So, it turns out that my code is correct. The problem was in the configuration for Icecast. By default, only two streams can be created. after editing that in the icecast config file, It all worked perfectly. Thanks.

Categories