v1 milestone

This commit is contained in:
YOLANDO
2026-03-25 11:20:05 +07:00
commit 4ec369c18e
7307 changed files with 873141 additions and 0 deletions

108
yt_engine.py Normal file
View File

@@ -0,0 +1,108 @@
import yt_dlp
import os
import asyncio
# Buat folder penampungan sementara jika belum ada
DOWNLOAD_DIR = "downloads"
os.makedirs(DOWNLOAD_DIR, exist_ok=True)
def generate_netscape_cookies():
"""
Mengubah data tabel cookie (copy-paste dari tab Application browser)
menjadi format baku Netscape HTTP Cookie agar bisa dibaca yt-dlp.
"""
if not os.path.exists("raw_cookie.txt"):
print("⚠️ raw_cookie.txt tidak ditemukan. Lanjut tanpa cookies.")
return False
try:
with open("raw_cookie.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
with open("cookies.txt", "w", encoding="utf-8") as f:
f.write("# Netscape HTTP Cookie File\n")
f.write("# This is a generated file! Do not edit.\n\n")
for line in lines:
# Pisahkan kolom berdasarkan tombol Tab (\t) bawaan copy-paste tabel
parts = line.split('\t')
# Pastikan baris tersebut valid (minimal punya Nama dan Value)
if len(parts) >= 2:
name = parts[0].strip()
value = parts[1].strip()
# Abaikan jika yang ter-copy adalah Header tabelnya ("Name", "Value")
if name.lower() == "name" or not name:
continue
# Format baku Netscape: domain, subdomains, path, secure, expiration, name, value
# Kita paksa domainnya .youtube.com agar yt-dlp bisa membacanya
f.write(f".youtube.com\tTRUE\t/\tTRUE\t2147483647\t{name}\t{value}\n")
print("✅ Cookies berhasil di-generate dari raw_cookie.txt")
return True
except Exception as e:
print(f"❌ Error saat memproses cookies: {e}")
return False
def search_and_download(query_or_url: str):
"""
Fungsi utama untuk mencari dan mengunduh audio dari YouTube.
Berjalan secara sinkronus.
"""
# 1. Konversi cookie setiap kali mau download
has_cookies = generate_netscape_cookies()
# 2. Pengaturan yt-dlp
ydl_opts = {
'format': 'bestaudio/best/m4a/mp3',
'outtmpl': f'{DOWNLOAD_DIR}/%(id)s.%(ext)s',
'max_filesize': 45000000, # Batas aman Telegram 45MB
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '128',
}],
'quiet': True,
'noplaylist': True,
'default_search': 'ytsearch1',
'js_runtimes': {'node': {}},
# 'extractor_args': {'youtube': ['player_client=android,ios']},
}
# 3. Sisipkan cookie jika berhasil digenerate
if has_cookies and os.path.exists("cookies.txt"):
ydl_opts['cookiefile'] = 'cookies.txt'
try:
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
# Mulai proses ekstraksi & download
info = ydl.extract_info(query_or_url, download=True)
# Jika hasil berupa playlist/pencarian, ambil item pertama
if 'entries' in info:
info = info['entries'][0]
video_id = info.get('id')
title = info.get('title')
duration = info.get('duration')
file_path = f"{DOWNLOAD_DIR}/{video_id}.mp3"
return {
"status": "success",
"video_id": video_id,
"title": title,
"duration": duration,
"file_path": file_path if os.path.exists(file_path) else None
}
except Exception as e:
return {"status": "error", "message": str(e)}
async def process_youtube_request(query: str):
"""
Bungkus (Wrapper) Async agar bot Telegram tidak nge-hang
saat menunggu proses download selesai.
"""
return await asyncio.to_thread(search_and_download, query)