YOUTUBELIVE / main.py
Alide21's picture
Update main.py
4093721 verified
import os
import time
import subprocess
import threading
import requests
from datetime import datetime, timedelta
from flask import Flask, jsonify
# ==========================================
# الإعدادات الأساسية
# ==========================================
STREAM_KEY = os.environ.get("STREAM_KEY")
STREAM_URL = "rtmp://a.rtmp.youtube.com/live2/"
BG_IMAGE = "https://images.unsplash.com/photo-1555400038-63f5ba517a47?q=80&w=1920&auto=format&fit=crop"
TICK_SOUND_FILE = "time.mp3"
app = Flask(__name__)
def get_current_status():
try:
res = requests.get("http://api.aladhan.com/v1/timingsByCity?city=Mecca&country=SA&method=4", timeout=5)
data = res.json()['data']
hijri_date = data['date']['hijri']
date_str = hijri_date['date']
h_day = int(hijri_date['day'])
h_month = int(hijri_date['month']['number'])
h_year = int(hijri_date['year'])
status = ""
target_date_gregorian = None
msg = ""
if h_month == 9:
status = "ramadan_live"
msg = "جاء رمضان.. مبارك عليكم الشهر"
elif h_month == 10 and h_day <= 3:
status = "eid_live"
msg = "عيد مبارك - كل عام وأنتم بخير"
else:
status = "counting"
target_h_year = h_year if h_month < 9 else h_year + 1
conv_res = requests.get(f"http://api.aladhan.com/v1/hToG?date=01-09-{target_h_year}", timeout=5)
g_data = conv_res.json()['data']['gregorian']
target_date_gregorian = datetime.strptime(g_data['date'], "%d-%m-%Y")
return {"status": status, "msg": msg, "hijri_str": date_str, "target_date": target_date_gregorian}
except:
return {"status": "counting", "msg": "", "hijri_str": "1447-09-01", "target_date": datetime(2026, 2, 18, 0, 0, 0)}
@app.route('/time_data')
def time_data():
current_state = get_current_status()
if current_state['status'] in ['ramadan_live', 'eid_live']:
return jsonify({"status": "finished", "msg": current_state['msg'], "hijri": current_state['hijri_str']})
diff = current_state['target_date'] - datetime.now()
if diff.total_seconds() <= 0:
return jsonify({"status": "loading", "hijri": current_state['hijri_str']})
days = diff.days
hours, rem = divmod(diff.seconds, 3600)
minutes, seconds = divmod(rem, 60)
return jsonify({"status": "counting", "days": f"{days:02}", "hours": f"{hours:02}", "minutes": f"{minutes:02}", "seconds": f"{seconds:02}", "hijri": current_state['hijri_str']})
@app.route('/')
def home():
html_content = """
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<title>بث مباشر | رمضان</title>
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@700;900&display=swap" rel="stylesheet">
<style>
body { background-color: #0f0f0f; color: white; font-family: 'Cairo', sans-serif; margin: 0; overflow: hidden; }
.video-player {
position: relative; width: 100vw; height: 100vh;
background: url('""" + BG_IMAGE + """') no-repeat center center;
background-size: cover; display: flex; flex-direction: column; justify-content: center; align-items: center;
}
.overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); }
.content { z-index: 10; text-align: center; width: 100%; }
.hijri-badge { background: #4CAF50; padding: 5px 20px; border-radius: 50px; font-size: 20px; margin-bottom: 20px; display: inline-block; }
.title { font-size: 40px; margin-bottom: 30px; text-shadow: 2px 2px 10px rgba(0,0,0,0.8); }
/* الحاوية الأساسية للعد التنازلي */
.countdown {
display: flex;
gap: 15px;
justify-content: center;
direction: ltr;
align-items: flex-start; /* محاذاة العناصر من الأعلى لضمان تناسق الوحدات */
}
.card {
background: linear-gradient(180deg, #4CAF50, #2E7D32);
width: 110px; height: 140px; border-radius: 15px;
font-size: 70px; font-weight: 900; display: flex;
justify-content: center; align-items: center;
box-shadow: 0 8px 15px rgba(0,0,0,0.5);
line-height: 1; /* لضمان توسط الرقم داخل المربع */
}
.unit { display: flex; flex-direction: column; align-items: center; }
.label { margin-top: 10px; font-size: 18px; color: #4CAF50; font-weight: bold; }
/* التعديل المطلوب: وضع النقاط في نصف ارتفاع المربع بالضبط */
.colon {
font-size: 60px;
color: #4CAF50;
font-weight: 900;
height: 140px; /* نفس ارتفاع الـ card */
display: flex;
align-items: center; /* يتوسط عمودياً بالنسبة للـ 140px */
justify-content: center;
line-height: 1;
margin-top: 0;
}
#celebration { display: none; font-size: 60px; color: #FFD700; animation: pulse 2s infinite; }
@keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } }
</style>
</head>
<body>
<div class="video-player">
<div class="overlay"></div>
<div class="content">
<div class="hijri-badge" id="hijri-top">--/--/----</div>
<div id="main-ui">
<div class="title">الوقت المتبقي على شهر رمضان</div>
<div class="countdown">
<div class="unit"><div class="card" id="days">00</div><div class="label">أيام</div></div>
<div class="colon">:</div>
<div class="unit"><div class="card" id="hours">00</div><div class="label">ساعة</div></div>
<div class="colon">:</div>
<div class="unit"><div class="card" id="minutes">00</div><div class="label">دقيقة</div></div>
<div class="colon">:</div>
<div class="unit"><div class="card" id="seconds">00</div><div class="label">ثانية</div></div>
</div>
</div>
<div id="celebration">...</div>
</div>
</div>
<script>
function update() {
fetch('/time_data').then(res => res.json()).then(data => {
document.getElementById('hijri-top').innerText = data.hijri;
if(data.status === 'finished') {
document.getElementById('main-ui').style.display = 'none';
document.getElementById('celebration').innerText = data.msg;
document.getElementById('celebration').style.display = 'block';
} else {
document.getElementById('main-ui').style.display = 'block';
document.getElementById('celebration').style.display = 'none';
document.getElementById('days').innerText = data.days || "00";
document.getElementById('hours').innerText = data.hours || "00";
document.getElementById('minutes').innerText = data.minutes || "00";
document.getElementById('seconds').innerText = data.seconds || "00";
}
});
}
setInterval(update, 1000);
update();
</script>
</body>
</html>
"""
return html_content
def start_stream():
if not STREAM_KEY: return
while True:
current_state = get_current_status()
if current_state['status'] == 'ramadan_live':
display_text, box_color, title_text, font_size = "Ramadan Mubarak", "0xD4AF37", "RAMADAN KAREEM", "65"
elif current_state['status'] == 'eid_live':
display_text, box_color, title_text, font_size = "Eid Mubarak", "0x9C27B0", "EID AL-FITR", "90"
else:
target_ts = int(current_state['target_date'].timestamp()) if current_state['target_date'] else int(time.time())
display_text = f" %{{pts\\:localtime\\:{target_ts}\\:%d}} : %{{pts\\:localtime\\:{target_ts}\\:%H}} : %{{pts\\:localtime\\:{target_ts}\\:%M}} : %{{pts\\:localtime\\:{target_ts}\\:%S}} "
box_color, title_text, font_size = "0x4CAF50", "RAMADAN COUNTDOWN", "90"
ffmpeg_cmd = [
'ffmpeg', '-re', '-stream_loop', '-1', '-i', TICK_SOUND_FILE,
'-loop', '1', '-i', BG_IMAGE, '-map', '1:v', '-map', '0:a',
'-vf', (
"scale=1280:720,setsar=1,"
"drawbox=y=ih/2-80:color=black@0.6:width=iw:height=200:t=fill,"
"drawtext=text='17-08-1447':x=50:y=50:fontsize=30:fontcolor=white:box=1:boxcolor=0x4CAF50@0.8,"
"drawtext=text='RAMADAN COUNTDOWN':x=(w-text_w)/2:y=230:fontsize=40:fontcolor=white,"
"drawtext=text=' %{pts\\:localtime\\:1771372800\\:%d} \\: %{pts\\:localtime\\:1771372800\\:%H} \\: %{pts\\:localtime\\:1771372800\\:%M} \\: %{pts\\:localtime\\:1771372800\\:%S} ':x=(w-text_w)/2:y=(h-text_h)/2+50:fontsize=90:fontcolor=white:box=1:boxcolor=0x4CAF50@1:boxborderw=25"
),
'-vcodec', 'libx264', '-preset', 'veryfast', '-b:v', '3000k', '-maxrate', '3000k', '-bufsize', '6000k',
'-pix_fmt', 'yuv420p', '-g', '60', '-c:a', 'aac', '-b:a', '128k', '-f', 'flv', f"{STREAM_URL}{STREAM_KEY}"
]
try:
subprocess.run(ffmpeg_cmd, check=True)
except:
time.sleep(5)
if __name__ == "__main__":
threading.Thread(target=lambda: app.run(host='0.0.0.0', port=7860, debug=False, use_reloader=False), daemon=True).start()
start_stream()