Spaces:
Sleeping
Sleeping
File size: 10,283 Bytes
ea45396 7952180 8d380e3 c3109de ea45396 f3d400d 3ef04bd f3d400d 5ccc9df 3ef04bd 35b6f0b f3d400d ea45396 8d380e3 3ef04bd 8d380e3 766d011 8d380e3 766d011 8d380e3 766d011 8d380e3 766d011 8d380e3 766d011 7952180 766d011 8d380e3 766d011 8d380e3 3ef04bd 766d011 c3109de 3ef04bd 4cd7492 8d380e3 81bd079 4cd7492 3ef04bd 8d380e3 766d011 8d380e3 3ef04bd 766d011 3ef04bd 8d380e3 766d011 8d380e3 766d011 8d380e3 766d011 8d380e3 766d011 3ef04bd 8d380e3 3ef04bd 4cd7492 3ef04bd 8d380e3 3ef04bd 8d380e3 3ef04bd 8d380e3 3ef04bd 8d380e3 3ef04bd 8d380e3 3ef04bd 8d380e3 d15b9ea 4cd7492 c3109de 81bd079 3ef04bd 8d380e3 3ef04bd 7952180 8d380e3 766d011 7952180 81bd079 c3109de 81bd079 c3109de 4cd7492 3ef04bd ea45396 766d011 ea45396 8d380e3 766d011 8d380e3 766d011 3ef04bd 766d011 8d380e3 766d011 ba11121 766d011 3ef04bd 4093721 3ef04bd 766d011 7952180 766d011 7952180 | 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 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | 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() |