Pro4 / streamlit_app.py
Reoo88's picture
Update streamlit_app.py
5595d22 verified
Raw History Blame Contribute Delete
4.99 kB
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')}")