with open("venv/lib/python3.8/site-packages/pytube/innertube.py", "r+") as file:
data = file.read()
if not "headers.update(self.header)" in data:
data = data.split("\n")
data[240] += "\n\n headers.update(self.header)"
data = "\n".join(data)
if "self.api_key" in data.split("\n")[89]:
data = data.split("\n")
data[89] += "\n self.header = _default_clients[client]['header']"
data = "\n".join(data)
if "__init__(self, client='ANDROID'" in data.split("\n")[77]:
data = data.split("\n")
data[77] = data[77].replace("'ANDROID'", "'ANDROID_MUSIC'")
data = "\n".join(data)
if data.split("\n")[68] == " }":
data = data.split("\n")
data[68] = """ },
'ANDROID_MUSIC': {
'context': {
'client': {
'clientName': 'ANDROID_MUSIC',
'clientVersion': '5.16.51',
'androidSdkVersion': 30
}
},
'header': {
'User-Agent': 'com.google.android.apps.youtube.music/'
},
'api_key': 'AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8'
},"""
data = "\n".join(data)
file.seek(0)
file.write(data)
file.truncate()
with open("venv/lib/python3.8/site-packages/pytube/request.py", "r+") as file:
data = file.read()
if "e.s" in data.split("\n")[180]:
data = data.split("\n")
data[180] = ""
data[179] = """
resp = _execute_request(
url + f"&range={0}-{99999999999}",
method="GET",
timeout=timeout
)
content_range = resp.info()["Content-Length"]
file_size = int(content_range)"""
data = "\n".join(data)
if not "range" in data.split("\n")[157]:
data = data.split("\n")
data[157] = data[157].replace("url,", 'url + f"&range={downloaded}-{stop_pos}",')
data = "\n".join(data)
file.seek(0)
file.write(data)
file.truncate()
from twitchrealtimehandler import TwitchImageGrabber
import xml.etree.ElementTree as ElementTree
from moviepy.editor import VideoFileClip
from skimage.transform import resize
from getkey import getkey, keys
from replit import clear, audio
from pytube import YouTube
from html import unescape
import threading
import requests
import datetime
import math
import glob
import time
import os
isOwner = os.path.exists("/tmp/audioStatus.json")
# thx @hecker40
def fg(r, g, b):
return f"\033[38;2;{int(r)};{int(g)};{int(b)}m"
def bg(r, g, b):
return f"\033[48;2;{int(r)};{int(g)};{int(b)}m"
reset = "\033[0m"
# thx @ColoredHue
def hide_cursor():
print("\033[?25l", end="", flush=True)
def show_cursor():
print("\033[?25h", end="", flush=True)
for file in glob.glob("*.mp3"):
os.remove(file)
for file in glob.glob("*.mp4"):
os.remove(file)
show_cursor()
print("How would you like to calculate screen size?")
print("1: The Automatic Way")
print("2: The Cool Way")
option = input("> ")
if option == "1":
size = os.get_terminal_size()
width = size.columns
height = size.lines
else:
clear()
print("You're about to be asked questions so we can get the correct screen size. You may be asked to see which character appears in the corner, but oftern this is obscured by buttons. To remove them, click off the screen")
print()
input("Press enter to continue > ")
clear()
chars = "0123456789abcdef"
msg = "Which character appears in the top right corner of the screen? > "
print(chars*len(chars))
print()
c = input(msg).lower()
clear()
for x in chars:
print(" "*chars.find(c)+x+" "*(len(chars)-chars.find(c)-1), end="", flush=False)
print("\n", flush=True)
c2 = input(msg).lower()
clear()
width = chars.find(c2)*len(chars)+chars.find(c)+1
for x in chars:
for y in chars:
print(" "*(width-1), y, sep="", flush=False)
print(flush=True)
c = input(msg).lower()
clear()
i = 0
for x in chars:
for y in chars:
if y == c:
print(" "*(width-1), chars[i], sep="", flush=False)
i += 1
else:
print(flush=False)
print(flush=True)
c2 = input(msg).lower()
height = len(chars)**2 - (chars.find(c2) * len(chars) + chars.find(c)) + math.ceil((len(msg) + 1) / width) + 1
clear()
print("Choose an option")
print("1: Download from YouTube")
print("2: Livestream from Twitch")
if isOwner:
print("3: Custom MP4s")
option = input("> ")
youtube = option != "2" and option != "3"
twitch = option == "2"
custom = option == "3"
else:
option = input("> ")
youtube = option != "2"
twitch = option == "2"
custom = False
clear()
today = datetime.date.today()
aprilfools = today.month == 4 and today.day == 1
if youtube:
url = input("Enter a YouTube video url > ")
if aprilfools:
url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
elif custom:
print("Upload an mp4 file to continue")
while len(glob.glob("*.mp4")) == 0:
time.sleep(3)
else:
url = input("Enter a Twitch livestream url > ")
contents = requests.get(url).content.decode("utf-8")
if not "isLiveBroadcast" in contents:
clear()
print("This channel is not currently live. Please try again with a different channel")
while True:
pass
if isOwner and not twitch:
clear()
playAudio = input("Do you want audio? y/n > ") == "y"
if playAudio:
audio.play_tone(0.01, 262, 0)
input("Press enter to continue > ")
else:
playAudio = False
if youtube:
clear()
enableCaptions = input("Do you want captions? y/n > ") == "y" or aprilfools
else:
enableCaptions = False
clear()
print("Choose a quality")
print("1: 1x Resolution")
print("2: 4x Resolution (Warning: Glitchy)")
option = input("> ")
fourRes = option == "2"
pixWidth = width
pixHeight = height
if not fourRes:
pixWidth //= 2
pixHeight -= 1
else:
pixHeight *= 2
pixWidth -= 12
pixHeight -= 4
# This fixes a bug and also lets me download in a very easy format
# adapted from https://stackoverflow.com/a/69004322/17766761
def xml_caption_to_dict(xml):
segments = []
root = ElementTree.fromstring(xml)
count_line = 0
for i, child in enumerate(list(root.findall("body/p"))):
text = "".join(child.itertext()).strip()
if not text:
continue
count_line += 1
caption = unescape(text.replace("\n", " ").replace(" ", " "),)
try:
duration = float(child.attrib["d"])
except KeyError:
duration = 0.0
start = float(child.attrib["t"])
try:
end2 = float(root.findall("body/p")[i+2].attrib["t"])
except:
end2 = float(root.findall("body/p")[i].attrib["t"]) + duration
line = {
"start": start / 1000,
"end": end2 / 1000,
"text": caption,
}
segments.append(line)
return segments
def getFrame():
global currentFrame
while True:
start = time.time()
currentFrame = imageGrabber.grab()
duration = time.time()-start
time.sleep(max(1/fps-duration, 0))
if not twitch:
if youtube:
clear()
print("Downloading Video...")
yt = YouTube(url)
vid = yt.streams.filter(file_extension="mp4").first()
vid.download()
clear()
print("Opening Video...")
filename = glob.glob("*.mp4")[0]
os.replace(filename, "video.mp4")
vid = VideoFileClip("video.mp4")
clear()
print("Resizing Video...")
vidWidth, vidHeight = vid.size
ratio = min(pixWidth / vidWidth, pixHeight / vidHeight)
vid = vid.resize(ratio)
if playAudio:
clear()
print("Extracting Audio...")
vidAudio = vid.audio
vidAudio.write_audiofile("audio.mp3", logger=None)
if enableCaptions:
clear()
print("Downloading Captions...")
captions = yt.captions
if "en" in captions:
captions = captions.get_by_language_code("en")
elif "a.en" in captions:
captions = captions.get_by_language_code("a.en")
else:
enableCaptions = False
if enableCaptions:
captions = xml_caption_to_dict(captions.xml_captions)
hide_cursor()
clear()
if playAudio:
source = audio.play_file("audio.mp3")
else:
clear()
print("Connecting...")
fps = 4
try:
imageGrabber = TwitchImageGrabber(
twitch_url = url,
quality = "160p",
blocking = True,
rate = fps,
)
except ValueError:
imageGrabber = TwitchImageGrabber(
twitch_url = url,
quality = "480p",
blocking = True,
rate = fps,
)
currentFrame = None
threading.Thread(target=getFrame).start()
while currentFrame is None:
time.sleep(0.1)
start = time.time()
paused = False
stop = False
def controls():
global paused, start, playAudio, source
while stop is False:
key = getkey()
if key == " " or key == "k":
paused = not paused
if not twitch:
if key == keys.LEFT:
start += 10
if playAudio:
source.paused = True
playAudio = False
elif key == keys.RIGHT:
start -= 10
if playAudio:
source.paused = True
playAudio = False
elif key == "r":
if playAudio:
source.paused = True
source = audio.play_file("audio.mp3")
start = time.time()
if playAudio:
if key == "+" or key == "=":
source.volume += 0.1
elif key == "-":
if source.volume - 0.1 > 0:
source.volume -= 0.1
thread = threading.Thread(target=controls)
thread.start()
try:
while True:
if not twitch:
t = time.time() - start
frame = vid.make_frame(t=t)
else:
frame = currentFrame
vidWidth = len(frame[0])
vidHeight = len(frame)
ratio = min(pixWidth / vidWidth, pixHeight / vidHeight)*2
frame = resize(frame, (pixHeight*ratio, pixWidth*ratio))
for column in range(len(frame)):
for row in range(len(frame[column])):
frame[column][row] = [x*255 for x in frame[column][row]]
text = "\033c"
if fourRes:
for column in range(0, len(frame), 2):
for row in range(len(frame[column])):
try:
text += bg(*frame[column][row])+fg(*frame[column + 1][row])+"▄"
except IndexError:
text += reset+fg(*frame[column][row])+"▀"
text += "\n"
else:
for column in frame:
for pixel in column:
text += bg(*pixel)+" "
text += "\n"
text += reset
if enableCaptions:
for caption in captions:
if caption["start"] < t and caption["end"] > t:
text += "\n"
if not aprilfools:
text += caption["text"].center(width)
else:
text += "April Fools!".center(width)
print(text, end="", flush=True)
time.sleep(0.25)
if paused:
if not twitch:
if playAudio:
source.paused = True
pauseStart = time.time()
while paused:
pass
if not twitch:
start += time.time() - pauseStart
if playAudio:
source.paused = False
except OSError:
clear()
print("Video Finished! Don't forget to like and subscribe!")
stop = True
except KeyboardInterrupt:
stop = True