Spaces:
Paused
Paused
import os | |
import re | |
import textwrap | |
import aiofiles | |
import aiohttp | |
from PIL import Image, ImageDraw, ImageEnhance, ImageFilter, ImageFont | |
from unidecode import unidecode | |
from youtubesearchpython.__future__ import VideosSearch | |
from DragMusic import app | |
from DragMusic.core.mongo import mongodb | |
from config import YOUTUBE_IMG_URL | |
from DragMusic.logging import LOGGER | |
def changeImageSize(maxWidth, maxHeight, image): | |
widthRatio = maxWidth / image.size[0] | |
heightRatio = maxHeight / image.size[1] | |
newWidth = int(widthRatio * image.size[0]) | |
newHeight = int(heightRatio * image.size[1]) | |
newImage = image.resize((newWidth, newHeight)) | |
return newImage | |
def clear(text): | |
list = text.split(" ") | |
title = "" | |
for i in list: | |
if len(title) + len(i) < 60: | |
title += " " + i | |
return title.strip() | |
async def get_thumb(videoid): | |
if os.path.isfile(f"/tmp/cache/{videoid}.png"): | |
return f"/tmp/cache/{videoid}.png" | |
url = f"https://www.youtube.com/watch?v={videoid}" | |
try: | |
results = VideosSearch(url, limit=1) | |
for result in (await results.next())["result"]: | |
try: | |
title = result["title"] | |
title = re.sub("\\W+", " ", title) | |
title = title.title() | |
except: | |
title = "Unsupported Title" | |
try: | |
duration = result["duration"] | |
except: | |
duration = "Unknown Mins" | |
thumbnail = result["thumbnails"][0]["url"].split("?")[0] | |
try: | |
views = result["viewCount"]["short"] | |
except: | |
views = "Unknown Views" | |
try: | |
channel = result["channel"]["name"] | |
except: | |
channel = "Unknown Channel" | |
async with aiohttp.ClientSession() as session: | |
async with session.get(thumbnail) as resp: | |
if resp.status == 200: | |
f = await aiofiles.open(f"/tmp/cache/thumb{videoid}.png", mode="wb") | |
await f.write(await resp.read()) | |
await f.close() | |
youtube = Image.open(f"/tmp/cache/thumb{videoid}.png") | |
image1 = changeImageSize(1280, 720, youtube) | |
image2 = image1.convert("RGBA") | |
background = image2.filter(filter=ImageFilter.BoxBlur(10)) | |
enhancer = ImageEnhance.Brightness(background) | |
background = enhancer.enhance(0.5) | |
draw = ImageDraw.Draw(background) | |
arial = ImageFont.truetype("DragMusic/assets/font2.ttf", 30) | |
font = ImageFont.truetype("DragMusic/assets/font.ttf", 30) | |
draw.text((1110, 8), unidecode(app.name), fill="white", font=arial) | |
draw.text( | |
(55, 560), | |
f"{channel} | {views[:23]}", | |
(255, 255, 255), | |
font=arial, | |
) | |
draw.text( | |
(57, 600), | |
clear(title), | |
(255, 255, 255), | |
font=font, | |
) | |
draw.line( | |
[(55, 660), (1220, 660)], | |
fill="white", | |
width=5, | |
joint="curve", | |
) | |
draw.ellipse( | |
[(918, 648), (942, 672)], | |
outline="white", | |
fill="white", | |
width=15, | |
) | |
draw.text( | |
(36, 685), | |
"00:00", | |
(255, 255, 255), | |
font=arial, | |
) | |
draw.text( | |
(1185, 685), | |
f"{duration[:23]}", | |
(255, 255, 255), | |
font=arial, | |
) | |
try: | |
os.remove(f"/tmp/cache/thumb{videoid}.png") | |
except: | |
pass | |
background.save(f"/tmp/cache/{videoid}.png") | |
return f"/tmp/cache/{videoid}.png" | |
except Exception as e: | |
print(e) | |
return YOUTUBE_IMG_URL | |
async def gen_thumb(videoid: str, user_id: int) -> str: | |
if os.path.isfile(f"/tmp/cache/{videoid}.png"): | |
return f"/tmp/cache/{videoid}.png" | |
url = f"https://www.youtube.com/watch?v={videoid}" | |
try: | |
results = VideosSearch(url, limit=1) | |
for result in (await results.next())["result"]: | |
try: | |
title = result["title"] | |
title = re.sub("\\W+", " ", title) | |
title = title.title() | |
except: | |
title = "Unsupported Title" | |
try: | |
duration = result["duration"] | |
except: | |
duration = "Unknown Mins" | |
thumbnail = result["thumbnails"][0]["url"].split("?")[0] | |
try: | |
views = result["viewCount"]["short"] | |
except: | |
views = "Unknown Views" | |
try: | |
channel = result["channel"]["name"] | |
except: | |
channel = "Unknown Channel" | |
async with aiohttp.ClientSession() as session: | |
async with session.get(thumbnail) as resp: | |
if resp.status == 200: | |
ctitle = (await app.get_chat(user_id)).title | |
ctitle = await crop_title(ctitle) | |
try: | |
f = await aiofiles.open(f"/tmp/cache/thumb{videoid}.png", mode="wb") | |
await f.write(await resp.read()) | |
await f.close() | |
youtube = Image.open(f"/tmp/cache/thumb{videoid}.png") | |
image1 = changeImageSize(1280, 720, youtube) | |
image2 = image1.convert("RGBA") | |
background = image2.filter(filter=ImageFilter.BoxBlur(30)) | |
enhancer = ImageEnhance.Brightness(background) | |
background = enhancer.enhance(0.5) | |
draw = ImageDraw.Draw(background) | |
arial = ImageFont.truetype("DragMusic/assets/font2.ttf", 40) | |
font = ImageFont.truetype("DragMusic/assets/font.ttf", 30) | |
draw.text((1110, 8), unidecode(app.name), fill="white", font=arial) | |
draw.text( | |
(55, 560), | |
f"{channel} | {views[:23]}", | |
(255, 255, 255), | |
font=arial, | |
) | |
draw.text( | |
(57, 600), | |
clear(title), | |
(255, 255, 255), | |
font=font, | |
) | |
draw.line( | |
[(55, 660), (1220, 660)], | |
fill="white", | |
width=5, | |
joint="curve", | |
) | |
draw.ellipse( | |
[(918, 648), (942, 672)], | |
outline="white", | |
fill="white", | |
width=15, | |
) | |
draw.text( | |
(36, 685), | |
"00:00", | |
(255, 255, 255), | |
font=arial, | |
) | |
draw.text( | |
(1185, 685), | |
f"{duration[:23]}", | |
(255, 255, 255), | |
font=arial, | |
) | |
except Exception: | |
pass | |
circle = Image.open("DragMusic/assets/circle.png") | |
try: | |
pfp = Image.open( | |
await app.download_media( | |
(await app.get_chat(user_id)).photo.big_file_id, | |
file_name=f"pfp{user_id}.png", | |
) | |
) | |
except Exception: | |
pfp = Image.open("DragMusic/assets/profile.png") | |
pfp = pfp.resize((450, 450)) | |
pfp = crop_center(pfp, 450, 450) | |
pfp = mask_circle_solid(pfp, (0, 0, 0, 0), 225) | |
# | |
image3 = Image.new("RGBA", (1280, 720)) | |
image3.paste(background, (0, 0)) | |
image3.paste(youtube, (200, 70), mask=youtube) | |
image3.paste(pfp, (410, 420), mask=pfp) | |
image3.paste(circle, (410, 420), mask=circle) | |
# Drawing with Impact Font | |
draw = ImageDraw.Draw(image3) | |
font = ImageFont.truetype("DragMusic/assets/font.ttf", 60) | |
font2 = ImageFont.truetype("DragMusic/assets/font2.ttf", 70) | |
arial = ImageFont.truetype("DragMusic/assets/font2.ttf", 40) | |
gfont = ImageFont.truetype("DragMusic/assets/font2.ttf", 40) | |
para = textwrap.wrap(title, width=32) | |
j = 0 | |
try: | |
if para[0]: | |
draw.text( | |
(5, 5), | |
f"{para[0]}", | |
fill="white", | |
stroke_width=3, | |
stroke_fill="black", | |
font=font, | |
) | |
if para[1]: | |
draw.text( | |
(5, 70), | |
f"{para[1]}", | |
fill="white", | |
stroke_width=3, | |
stroke_fill="black", | |
font=font, | |
) | |
except: | |
pass | |
text_w, text_h = draw.textsize(f"Playing on: {ctitle}", font=gfont) | |
draw.text( | |
((1280 - text_w) / 2, 615), | |
f"Playing on: {ctitle}", | |
fill="white", | |
font=gfont, | |
) | |
draw.text((740, 480), "Duration:", fill="white", font=arial) | |
draw.text( | |
(915, 480), | |
f"{duration} Mins", | |
fill="white", | |
font=arial, | |
) | |
draw.text( | |
(740, 530), | |
f"Views : {views}", | |
(255, 255, 255), | |
font=arial, | |
) | |
try: | |
os.remove(f"/tmp/cache/thumb{videoid}.png") | |
except: | |
pass | |
background.save(f"/tmp/cache/{videoid}.png") | |
return f"/tmp/cache/{videoid}.png" | |
except Exception as e: | |
LOGGER(__name__).error(e) | |
return "" | |
def crop_center(pil_img, crop_width, crop_height): | |
img_width, img_height = pil_img.size | |
return pil_img.crop( | |
( | |
(img_width - crop_width) // 2, | |
(img_height - crop_height) // 2, | |
(img_width + crop_width) // 2, | |
(img_height + crop_height) // 2, | |
) | |
) | |
def mask_circle_solid(im, a, size): | |
output = Image.new("RGBA", (size, size), (0, 0, 0, 0)) | |
draw = ImageDraw.Draw(output) | |
draw.ellipse((0, 0, size, size), fill=a) | |
output.putalpha(220) | |
return output | |
async def crop_title(title): | |
if len(title) > 20: | |
return f"{title[:20]}..." | |
else: | |
return title | |