Spaces:
Running
Running
File size: 5,062 Bytes
0f6ad68 ae8378a 0f6ad68 ae8378a 0f6ad68 ae8378a 0f6ad68 615503a 0f6ad68 615503a 0f6ad68 ae8378a 0f6ad68 ae8378a abed419 0f6ad68 ae8378a 0f6ad68 ae8378a 0f6ad68 ae8378a 0f6ad68 ae8378a 615503a 0f6ad68 abed419 0f6ad68 abed419 ae8378a 0f6ad68 ae8378a 0f6ad68 abed419 0f6ad68 abed419 0f6ad68 ae8378a 0f6ad68 ae8378a 0f6ad68 ae8378a 0f6ad68 ae8378a 0f6ad68 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | import os
import re
import asyncio
from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import StreamingResponse, JSONResponse
from pyrogram import Client
import uvicorn
from contextlib import asynccontextmanager
# --- Config ---
API_ID = os.getenv("API_ID")
API_HASH = os.getenv("API_HASH")
STRING_SESSION = os.getenv("STRING_SESSION")
ACCESS_KEY = os.getenv("ACCESS_KEY", "0000")
@asynccontextmanager
async def lifespan(app: FastAPI):
# Bot ကို စတင်ခြင်း
user_bot = Client(
"tg_streamer",
api_id=API_ID,
api_hash=API_HASH,
session_string=STRING_SESSION,
in_memory=True,
workers=16
)
await user_bot.start()
app.state.tg = user_bot
print("🚀 Ultimate Smooth Streamer is Online!")
# --- Entity Cache ပြဿနာဖြေရှင်းရန် (Warm-up လုပ်ခြင်း) ---
print("🔄 Warming up Entity Cache (Fetching Dialogs)...")
try:
# အကောင့်ထဲရှိ Group/Channel ၁၀၀ ခုကို အရင်ဖတ်ခိုင်းပြီး မှတ်ထားစေပါသည်
async for dialog in user_bot.get_dialogs(limit=100):
pass
print("✅ Warm-up complete! Entity Cache is ready.")
except Exception as e:
print(f"⚠️ Warm-up တွင် အခက်အခဲရှိနေပါသည်: {e}")
yield
# Bot ကို ပိတ်ခြင်း
await user_bot.stop()
app = FastAPI(lifespan=lifespan)
# --- Health Check Endpoint ---
@app.get("/")
async def health_check():
return JSONResponse(content={"status": "running", "message": "Server is alive!"})
def parse_tg_link(link: str):
match = re.search(r't\.me/(?:c/)?([^/]+)/(\d+)', link)
if match:
chat_id = match.group(1)
if chat_id.isdigit():
chat_id = int("-100" + chat_id)
return chat_id, int(match.group(2))
return None, None
@app.get("/stream")
async def stream_telegram(request: Request, url: str, key: str = None):
if key != ACCESS_KEY:
raise HTTPException(status_code=403, detail="Invalid Key")
chat_id, msg_id = parse_tg_link(url)
if not chat_id:
raise HTTPException(status_code=400, detail="Invalid URL")
client = request.app.state.tg
# --- Streaming မလုပ်ခင် Chat ကို အရင် Fetch လုပ်ခြင်း ---
try:
# Chat ID အသစ်ဖြစ်နေပါက Telegram မှ ကြိုတင်အချက်အလက်တောင်းယူခြင်း
await client.get_chat(chat_id)
except Exception as e:
print(f"⚠️ Chat ကို ကြိုတင်ရှာဖွေရာတွင် အခက်အခဲရှိသည် (သို့သော် ဆက်လက်ကြိုးစားမည်): {e}")
try:
msg = await client.get_messages(chat_id, msg_id)
# Media ရှိမရှိ စစ်ဆေးခြင်း
media = msg.video or msg.document or msg.audio or msg.animation
if not media:
print(f"❌ Media Not Found in Message: {msg_id}")
raise Exception("No media found")
except Exception as e:
print(f"❌ Error fetching message {msg_id}: {str(e)}")
raise HTTPException(status_code=404, detail=f"File not found or Access Denied: {str(e)}")
file_size = media.file_size
range_header = request.headers.get("range")
start_byte = 0
if range_header:
match = re.search(r'bytes=(\d+)-', range_header)
if match:
start_byte = int(match.group(1))
async def refined_generator():
# Telegram ရဲ့ offset က MB နဲ့ သွားတာမို့လို့ပါ
offset_in_mb = start_byte // (1024 * 1024)
skip_bytes = start_byte % (1024 * 1024)
try:
generator = client.stream_media(msg, offset=offset_in_mb, limit=30)
first_chunk = True
async for chunk in generator:
if first_chunk:
if len(chunk) > skip_bytes:
yield chunk[skip_bytes:]
first_chunk = False
else:
yield chunk
except Exception as e:
print(f"⚠️ Stream interrupted for {msg_id}: {e}")
return
headers = {
"Content-Type": getattr(media, "mime_type", "video/mp4"),
"Accept-Ranges": "bytes",
"Access-Control-Allow-Origin": "*",
"Cache-Control": "public, max-age=3600",
}
if range_header:
headers["Content-Range"] = f"bytes {start_byte}-{file_size-1}/{file_size}"
status_code = 206
else:
status_code = 200
return StreamingResponse(
refined_generator(),
status_code=status_code,
headers=headers
)
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860) |