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)