import streamlit as st import asyncio import subprocess import threading import time from datetime import datetime from TikTokLive import TikTokLiveClient # ═══════════════════════════════════════════════════════════════════ # ⚙️ الإعدادات # ═══════════════════════════════════════════════════════════════════ BROADCASTERS = [ { "tiktok": "@dharialshammarii0", "stream_key": "p0ep-37wz-q3yg-7twf-3acb", }, # أضف المزيد بنفس التنسيق ] YT_RTMP_BASE = "rtmp://a.rtmp.youtube.com/live2/" POLL_INTERVAL = 60 # ثانية بين كل فحص # ═══════════════════════════════════════════════════════════════════ # 🚀 دوال البث الجديدة (بدون streamlink) # ═══════════════════════════════════════════════════════════════════ def stream_broadcaster(tiktok_username, stream_key): """ تستخدم yt-dlp لاستخراج البث، وتمريره إلى ffmpeg للنسخ المباشر إلى يوتيوب. """ # رابط قناة TikTok url = f"https://www.tiktok.com/{tiktok_username}/live" # أمر yt-dlp: استخراج أفضل جودة وإخراجها إلى stdout yt_dlp_cmd = f'yt-dlp -f best -o - "{url}"' # أمر ffmpeg: استقبال الدفق من stdin ونسخه مباشرة لـ RTMP ffmpeg_cmd = ( f"ffmpeg -hide_banner -loglevel error " f"-re -i pipe:0 " f"-c:v copy -c:a copy " f"-f flv {YT_RTMP_BASE}{stream_key}" ) # دمج الأمرين في سطر واحد full_cmd = f"{yt_dlp_cmd} | {ffmpeg_cmd}" print(f"🔴 بدء بث {tiktok_username} عبر yt-dlp...") try: proc = subprocess.Popen(full_cmd, shell=True) proc.wait() print(f"⏹️ انتهى بث {tiktok_username}") except Exception as e: print(f"❌ خطأ أثناء بث {tiktok_username}: {e}") def monitor_and_stream(): """المراقبة المستمرة وتشغيل البث عند الحاجة""" active_threads = {} while True: for broadcaster in BROADCASTERS: tiktok = broadcaster["tiktok"] key = broadcaster["stream_key"] try: client = TikTokLiveClient(unique_id=tiktok) is_live = asyncio.run(client.is_live()) except Exception as e: print(f"⚠️ تعذر فحص {tiktok}: {e}") continue if is_live and tiktok not in active_threads: t = threading.Thread( target=stream_broadcaster, args=(tiktok, key), daemon=True, ) t.start() active_threads[tiktok] = t elif not is_live and tiktok in active_threads: del active_threads[tiktok] time.sleep(POLL_INTERVAL) # ═══════════════════════════════════════════════════════════════════ # 🎬 بدء المراقبة في الخلفية # ═══════════════════════════════════════════════════════════════════ if "monitor_started" not in st.session_state: monitor_thread = threading.Thread( target=monitor_and_stream, name="TikTokMonitor", daemon=True, ) monitor_thread.start() st.session_state.monitor_started = True # ═══════════════════════════════════════════════════════════════════ # 🎨 واجهة المستخدم # ═══════════════════════════════════════════════════════════════════ st.set_page_config(page_title="TikTok 2 YouTube", page_icon="🔴") st.title("🔴 نظام البث التلقائي (الحل النهائي)") st.markdown("### الحسابات المراقبة:") for b in BROADCASTERS: st.write(f"- {b['tiktok']}") st.success("النظام يعمل في الخلفية. يمكنك إغلاق الصفحة.") st.caption(f"آخر تحديث: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")