Update streamlit_app.py
Browse files- streamlit_app.py +32 -12
streamlit_app.py
CHANGED
|
@@ -14,13 +14,12 @@ from TikTokLive import TikTokLiveClient
|
|
| 14 |
TIKTOK_USERNAME = "@ah_md107"
|
| 15 |
STATUS = "/tmp/status.json"
|
| 16 |
LOCK_FILE = "/tmp/app_monitor_core.lock"
|
| 17 |
-
POLL_INTERVAL =
|
| 18 |
GRACE_PERIOD_SECONDS = 120
|
| 19 |
-
# البث سيعتمد حصراً على هذا المفتاح الثابت دون تعديل عناوين
|
| 20 |
CUSTOM_STREAM_KEY = os.getenv("CUSTOM_STREAM_KEY", "skqf-rd92-dfa7-74cx-bxr2")
|
| 21 |
|
| 22 |
# ══════════════════════════════════════════════════════════════════════════════ #
|
| 23 |
-
# محرك المراقبة
|
| 24 |
# ══════════════════════════════════════════════════════════════════════════════ #
|
| 25 |
def run_monitor():
|
| 26 |
lock_file = open(LOCK_FILE, 'w')
|
|
@@ -33,13 +32,20 @@ def run_monitor():
|
|
| 33 |
|
| 34 |
while True:
|
| 35 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
client = TikTokLiveClient(unique_id=TIKTOK_USERNAME)
|
| 37 |
is_live = asyncio.run(client.is_live())
|
| 38 |
|
| 39 |
if is_live:
|
| 40 |
offline_start_time = None
|
| 41 |
if not is_streaming:
|
| 42 |
-
#
|
| 43 |
cmd = (
|
| 44 |
f"streamlink https://www.tiktok.com/{TIKTOK_USERNAME}/live best --hls-live-edge 3 --stdout | "
|
| 45 |
f"ffmpeg -thread_queue_size 8192 -i pipe:0 -c:v copy -c:a aac -ar 48000 -b:a 192k -ac 2 "
|
|
@@ -53,7 +59,7 @@ def run_monitor():
|
|
| 53 |
if is_streaming:
|
| 54 |
if offline_start_time is None: offline_start_time = time.time()
|
| 55 |
|
| 56 |
-
# إ
|
| 57 |
if time.time() - offline_start_time >= GRACE_PERIOD_SECONDS:
|
| 58 |
if process: process.terminate()
|
| 59 |
is_streaming = False
|
|
@@ -64,16 +70,30 @@ def run_monitor():
|
|
| 64 |
except Exception:
|
| 65 |
time.sleep(POLL_INTERVAL)
|
| 66 |
|
| 67 |
-
# تشغيل الخي
|
| 68 |
if "core_monitor_initialized" not in st.session_state:
|
| 69 |
threading.Thread(target=run_monitor, name="CoreTikTokMonitor", daemon=True).start()
|
| 70 |
st.session_state.core_monitor_initialized = True
|
| 71 |
|
| 72 |
# ══════════════════════════════════════════════════════════════════════════════ #
|
| 73 |
-
# الواجهة (
|
| 74 |
# ══════════════════════════════════════════════════════════════════════════════ #
|
| 75 |
-
st.
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
TIKTOK_USERNAME = "@ah_md107"
|
| 15 |
STATUS = "/tmp/status.json"
|
| 16 |
LOCK_FILE = "/tmp/app_monitor_core.lock"
|
| 17 |
+
POLL_INTERVAL = 60 # زيادة الفاصل الزمني لتجنب حظر الـ IP
|
| 18 |
GRACE_PERIOD_SECONDS = 120
|
|
|
|
| 19 |
CUSTOM_STREAM_KEY = os.getenv("CUSTOM_STREAM_KEY", "skqf-rd92-dfa7-74cx-bxr2")
|
| 20 |
|
| 21 |
# ══════════════════════════════════════════════════════════════════════════════ #
|
| 22 |
+
# محرك المراقبة الذكي
|
| 23 |
# ══════════════════════════════════════════════════════════════════════════════ #
|
| 24 |
def run_monitor():
|
| 25 |
lock_file = open(LOCK_FILE, 'w')
|
|
|
|
| 32 |
|
| 33 |
while True:
|
| 34 |
try:
|
| 35 |
+
# 1. التحقق من سلامة عملية البث الفعلية (System Health Check)
|
| 36 |
+
if is_streaming and (process is None or process.poll() is not None):
|
| 37 |
+
is_streaming = False
|
| 38 |
+
process = None
|
| 39 |
+
with open(STATUS, "w") as f: json.dump({"live": False, "msg": "انقطع الاتصال، بانتظار المذيع..."}, f)
|
| 40 |
+
|
| 41 |
+
# 2. فحص حالة اللايف في تيك توك
|
| 42 |
client = TikTokLiveClient(unique_id=TIKTOK_USERNAME)
|
| 43 |
is_live = asyncio.run(client.is_live())
|
| 44 |
|
| 45 |
if is_live:
|
| 46 |
offline_start_time = None
|
| 47 |
if not is_streaming:
|
| 48 |
+
# بدء البث على المفتاح الثابت
|
| 49 |
cmd = (
|
| 50 |
f"streamlink https://www.tiktok.com/{TIKTOK_USERNAME}/live best --hls-live-edge 3 --stdout | "
|
| 51 |
f"ffmpeg -thread_queue_size 8192 -i pipe:0 -c:v copy -c:a aac -ar 48000 -b:a 192k -ac 2 "
|
|
|
|
| 59 |
if is_streaming:
|
| 60 |
if offline_start_time is None: offline_start_time = time.time()
|
| 61 |
|
| 62 |
+
# إغلاق آمن بعد مهلة الأمان
|
| 63 |
if time.time() - offline_start_time >= GRACE_PERIOD_SECONDS:
|
| 64 |
if process: process.terminate()
|
| 65 |
is_streaming = False
|
|
|
|
| 70 |
except Exception:
|
| 71 |
time.sleep(POLL_INTERVAL)
|
| 72 |
|
| 73 |
+
# تشغيل المحرك في الخلفية
|
| 74 |
if "core_monitor_initialized" not in st.session_state:
|
| 75 |
threading.Thread(target=run_monitor, name="CoreTikTokMonitor", daemon=True).start()
|
| 76 |
st.session_state.core_monitor_initialized = True
|
| 77 |
|
| 78 |
# ══════════════════════════════════════════════════════════════════════════════ #
|
| 79 |
+
# الواجهة (Streamlit)
|
| 80 |
# ══════════════════════════════════════════════════════════════════════════════ #
|
| 81 |
+
st.set_page_config(page_title="AutoStreamer Pro", page_icon="📡")
|
| 82 |
+
st.title("📡 رادار بث أحمد عبدالله - النسخة المستقرة")
|
| 83 |
+
|
| 84 |
+
def get_status():
|
| 85 |
+
if not os.path.exists(STATUS) or os.path.getsize(STATUS) == 0:
|
| 86 |
+
return {"live": False, "msg": "جاري فحص حالة البث..."}
|
| 87 |
+
try:
|
| 88 |
+
with open(STATUS, "r") as f: return json.load(f)
|
| 89 |
+
except: return {"live": False, "msg": "بانتظار المذيع..."}
|
| 90 |
+
|
| 91 |
+
s = get_status()
|
| 92 |
+
if s.get("live"):
|
| 93 |
+
st.success("🔴 أحمد عبدالله مباشر الآن!")
|
| 94 |
+
st.info(f"يتم البث عبر المفتاح الثابت: {CUSTOM_STREAM_KEY[:5]}****")
|
| 95 |
+
else:
|
| 96 |
+
st.info(s.get("msg", "بانتظار المذيع..."))
|
| 97 |
+
|
| 98 |
+
if st.button("🔄 تحديث حالة الرادار"):
|
| 99 |
+
st.rerun()
|