A Pen by BI__KO BBM on CodePen.
Created
March 7, 2026 04:27
-
-
Save hsnsbhshsh/387b6ddb598e32c984f566bc54e7a442 to your computer and use it in GitHub Desktop.
Untitled
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="ar" dir="rtl"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Sora Downloader Pro - فحص الخادم</title> | |
| <style> | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| } | |
| body { | |
| background: linear-gradient(135deg, #0f172a, #1e293b); | |
| min-height: 100vh; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| padding: 20px; | |
| } | |
| .container { | |
| background: white; | |
| border-radius: 30px; | |
| padding: 35px; | |
| width: 100%; | |
| max-width: 550px; | |
| box-shadow: 0 30px 60px rgba(0,0,0,0.5); | |
| } | |
| h1 { | |
| text-align: center; | |
| color: #0f172a; | |
| margin-bottom: 5px; | |
| font-size: 28px; | |
| } | |
| .subtitle { | |
| text-align: center; | |
| color: #64748b; | |
| margin-bottom: 25px; | |
| font-size: 14px; | |
| } | |
| /* مؤشر حالة الخادم */ | |
| .server-status { | |
| background: #f8fafc; | |
| border-radius: 50px; | |
| padding: 15px 20px; | |
| margin-bottom: 25px; | |
| display: flex; | |
| align-items: center; | |
| gap: 15px; | |
| border: 1px solid #e2e8f0; | |
| } | |
| .status-indicator { | |
| width: 14px; | |
| height: 14px; | |
| border-radius: 50%; | |
| background: #94a3b8; | |
| transition: all 0.3s; | |
| position: relative; | |
| } | |
| .status-indicator.working { | |
| background: #22c55e; | |
| box-shadow: 0 0 15px #22c55e; | |
| animation: pulse 2s infinite; | |
| } | |
| .status-indicator.checking { | |
| background: #f59e0b; | |
| animation: blink 1s infinite; | |
| } | |
| .status-indicator.error { | |
| background: #ef4444; | |
| } | |
| @keyframes pulse { | |
| 0% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.7); } | |
| 70% { box-shadow: 0 0 0 10px rgba(34, 197, 94, 0); } | |
| 100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); } | |
| } | |
| @keyframes blink { | |
| 0% { opacity: 1; } | |
| 50% { opacity: 0.3; } | |
| 100% { opacity: 1; } | |
| } | |
| .status-text { | |
| flex: 1; | |
| font-weight: 600; | |
| color: #334155; | |
| } | |
| .status-details { | |
| font-size: 12px; | |
| color: #64748b; | |
| font-family: monospace; | |
| background: #e2e8f0; | |
| padding: 5px 10px; | |
| border-radius: 20px; | |
| } | |
| .input-group { | |
| margin-bottom: 20px; | |
| } | |
| label { | |
| display: block; | |
| margin-bottom: 8px; | |
| color: #475569; | |
| font-weight: 500; | |
| font-size: 14px; | |
| } | |
| #video-url { | |
| width: 100%; | |
| padding: 15px; | |
| border: 2px solid #e2e8f0; | |
| border-radius: 15px; | |
| font-size: 15px; | |
| transition: all 0.3s; | |
| direction: ltr; | |
| } | |
| #video-url:focus { | |
| outline: none; | |
| border-color: #3b82f6; | |
| box-shadow: 0 0 0 4px rgba(59,130,246,0.1); | |
| } | |
| #video-url:disabled { | |
| background: #f1f5f9; | |
| cursor: not-allowed; | |
| } | |
| .download-btn { | |
| width: 100%; | |
| padding: 15px; | |
| background: linear-gradient(135deg, #3b82f6, #8b5cf6); | |
| color: white; | |
| border: none; | |
| border-radius: 15px; | |
| font-size: 16px; | |
| font-weight: 600; | |
| cursor: pointer; | |
| transition: all 0.3s; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 10px; | |
| margin-bottom: 15px; | |
| } | |
| .download-btn:hover:not(:disabled) { | |
| transform: translateY(-2px); | |
| box-shadow: 0 10px 25px rgba(59,130,246,0.3); | |
| } | |
| .download-btn:disabled { | |
| opacity: 0.5; | |
| cursor: not-allowed; | |
| background: linear-gradient(135deg, #94a3b8, #64748b); | |
| } | |
| .status-box { | |
| padding: 15px; | |
| border-radius: 12px; | |
| margin: 15px 0; | |
| display: none; | |
| font-size: 14px; | |
| } | |
| .status-box.success { | |
| background: #d1fae5; | |
| border: 1px solid #a7f3d0; | |
| color: #065f46; | |
| display: block; | |
| } | |
| .status-box.error { | |
| background: #fee2e2; | |
| border: 1px solid #fecaca; | |
| color: #991b1b; | |
| display: block; | |
| } | |
| .status-box.info { | |
| background: #dbeafe; | |
| border: 1px solid #bfdbfe; | |
| color: #1e40af; | |
| display: block; | |
| } | |
| .result-box { | |
| background: #f8fafc; | |
| border-radius: 15px; | |
| padding: 20px; | |
| border: 1px solid #e2e8f0; | |
| margin-top: 15px; | |
| } | |
| .download-link { | |
| display: block; | |
| padding: 15px; | |
| background: #22c55e; | |
| color: white; | |
| text-decoration: none; | |
| border-radius: 12px; | |
| text-align: center; | |
| font-weight: 600; | |
| margin-bottom: 10px; | |
| transition: 0.3s; | |
| } | |
| .download-link:hover { | |
| background: #16a34a; | |
| } | |
| .copy-btn { | |
| width: 100%; | |
| padding: 12px; | |
| background: #64748b; | |
| color: white; | |
| border: none; | |
| border-radius: 10px; | |
| cursor: pointer; | |
| font-size: 14px; | |
| transition: 0.3s; | |
| } | |
| .copy-btn:hover { | |
| background: #475569; | |
| } | |
| .examples { | |
| margin-top: 20px; | |
| } | |
| .example-buttons { | |
| display: flex; | |
| gap: 10px; | |
| flex-wrap: wrap; | |
| } | |
| .example-btn { | |
| flex: 1; | |
| padding: 10px; | |
| background: #f1f5f9; | |
| border: 1px solid #e2e8f0; | |
| border-radius: 8px; | |
| cursor: pointer; | |
| font-size: 12px; | |
| color: #334155; | |
| transition: 0.3s; | |
| min-width: 100px; | |
| } | |
| .example-btn:hover:not(:disabled) { | |
| background: #e2e8f0; | |
| } | |
| .example-btn:disabled { | |
| opacity: 0.5; | |
| cursor: not-allowed; | |
| } | |
| .loading-spinner { | |
| display: inline-block; | |
| width: 18px; | |
| height: 18px; | |
| border: 3px solid rgba(255,255,255,0.3); | |
| border-radius: 50%; | |
| border-top-color: white; | |
| animation: spin 0.8s linear infinite; | |
| } | |
| @keyframes spin { | |
| to { transform: rotate(360deg); } | |
| } | |
| .server-url { | |
| text-align: center; | |
| margin-top: 20px; | |
| font-size: 11px; | |
| color: #94a3b8; | |
| font-family: monospace; | |
| background: #f1f5f9; | |
| padding: 8px; | |
| border-radius: 20px; | |
| } | |
| .last-check { | |
| font-size: 11px; | |
| color: #94a3b8; | |
| margin-top: 5px; | |
| text-align: center; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>🎬 Sora Video Downloader</h1> | |
| <div class="subtitle">مع فحص الخادم التلقائي</div> | |
| <!-- حالة الخادم --> | |
| <div class="server-status" id="serverStatus"> | |
| <div class="status-indicator" id="statusIndicator"></div> | |
| <div class="status-text" id="statusText">جاري فحص الخادم...</div> | |
| <div class="status-details" id="statusDetails">brahim-1ofn.onrender.com</div> | |
| </div> | |
| <div class="input-group"> | |
| <label for="video-url">🔗 رابط فيديو Sora</label> | |
| <input type="text" id="video-url" placeholder="https://sora.chatgpt.com/p/..." | |
| value="https://sora.chatgpt.com/p/s_6902318491e88191893d935b08d8c428"> | |
| </div> | |
| <button class="download-btn" onclick="downloadVideo()" id="downloadBtn"> | |
| <span>⬇️</span> تحميل الفيديو | |
| </button> | |
| <div class="status-box" id="status"></div> | |
| <div id="result"></div> | |
| <div class="examples"> | |
| <div class="example-buttons"> | |
| <button class="example-btn" onclick="fillExample('https://sora.chatgpt.com/p/s_6902318491e88191893d935b08d8c428')"> | |
| 📋 رابط 1 | |
| </button> | |
| <button class="example-btn" onclick="fillExample('https://sora.chatgpt.com/p/s_6902318491e88191893d935b08d8c429')"> | |
| 📋 رابط 2 | |
| </button> | |
| <button class="example-btn" onclick="checkServerAgain()"> | |
| 🔄 فحص الخادم | |
| </button> | |
| </div> | |
| </div> | |
| <div class="server-url"> | |
| الخادم: https://brahim-1ofn.onrender.com | |
| </div> | |
| <div class="last-check" id="lastCheck"></div> | |
| </div> | |
| <script> | |
| const SERVER_URL = 'https://brahim-1ofn.onrender.com'; | |
| const DOWNLOAD_URL = `${SERVER_URL}/download`; | |
| // فحص الخادم عند تحميل الصفحة | |
| async function checkServer() { | |
| const indicator = document.getElementById('statusIndicator'); | |
| const statusText = document.getElementById('statusText'); | |
| const downloadBtn = document.getElementById('downloadBtn'); | |
| const videoInput = document.getElementById('video-url'); | |
| const exampleBtns = document.querySelectorAll('.example-btn'); | |
| // تغيير الحالة إلى "جاري الفحص" | |
| indicator.className = 'status-indicator checking'; | |
| statusText.innerHTML = 'جاري فحص الخادم...'; | |
| downloadBtn.disabled = true; | |
| videoInput.disabled = true; | |
| exampleBtns.forEach(btn => btn.disabled = true); | |
| try { | |
| // محاولة الاتصال بالخادم | |
| const controller = new AbortController(); | |
| const timeoutId = setTimeout(() => controller.abort(), 5000); | |
| const response = await fetch(SERVER_URL, { | |
| method: 'GET', | |
| signal: controller.signal | |
| }); | |
| clearTimeout(timeoutId); | |
| if (response.ok) { | |
| const text = await response.text(); | |
| if (text.includes('الخادم يعمل') || text.includes('working') || text.includes('بنجاح')) { | |
| // خادم شغال | |
| indicator.className = 'status-indicator working'; | |
| statusText.innerHTML = '✅ الخادم شغال وجاهز'; | |
| downloadBtn.disabled = false; | |
| videoInput.disabled = false; | |
| exampleBtns.forEach(btn => btn.disabled = false); | |
| document.getElementById('lastCheck').innerHTML = `آخر فحص: ${new Date().toLocaleTimeString('ar-EG')}`; | |
| } else { | |
| throw new Error('الخادم لا يستجيب بشكل صحيح'); | |
| } | |
| } else { | |
| throw new Error('الخادم لا يستجيب'); | |
| } | |
| } catch (error) { | |
| // خادم معطل | |
| indicator.className = 'status-indicator error'; | |
| statusText.innerHTML = '❌ الخادم معطل أو لا يستجيب'; | |
| downloadBtn.disabled = true; | |
| videoInput.disabled = true; | |
| exampleBtns.forEach(btn => btn.disabled = true); | |
| document.getElementById('lastCheck').innerHTML = `آخر محاولة: ${new Date().toLocaleTimeString('ar-EG')} - فشل`; | |
| // عرض رسالة للمستخدم | |
| showStatus('⚠️ الخادم غير متصل حالياً. حاول مرة أخرى لاحقاً.', 'error'); | |
| } | |
| } | |
| async function downloadVideo() { | |
| const videoUrl = document.getElementById('video-url').value.trim(); | |
| const downloadBtn = document.getElementById('downloadBtn'); | |
| const statusEl = document.getElementById('status'); | |
| const resultEl = document.getElementById('result'); | |
| if (!videoUrl) { | |
| showStatus('❌ الرجاء إدخال رابط الفيديو', 'error'); | |
| return; | |
| } | |
| // تغيير حالة الزر | |
| downloadBtn.disabled = true; | |
| downloadBtn.innerHTML = '<span class="loading-spinner"></span> جاري التحميل...'; | |
| showStatus('🔄 جاري معالجة الرابط...', 'info'); | |
| resultEl.innerHTML = ''; | |
| try { | |
| const response = await fetch(DOWNLOAD_URL, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| body: JSON.stringify({ | |
| video_url: videoUrl | |
| }) | |
| }); | |
| const data = await response.json(); | |
| if (!response.ok) { | |
| throw new Error(data.error || 'خطأ في الخادم'); | |
| } | |
| const downloadUrl = data.download_url || data.url; | |
| if (downloadUrl) { | |
| showStatus('✅ تم العثور على الفيديو!', 'success'); | |
| resultEl.innerHTML = ` | |
| <div class="result-box"> | |
| <a href="${downloadUrl}" class="download-link" target="_blank"> | |
| ⬇️ تحميل الفيديو الآن | |
| </a> | |
| <button class="copy-btn" onclick="copyToClipboard('${downloadUrl}')"> | |
| 📋 نسخ رابط التحميل | |
| </button> | |
| </div> | |
| `; | |
| // تحميل تلقائي | |
| setTimeout(() => window.open(downloadUrl, '_blank'), 1000); | |
| } else { | |
| throw new Error('لم يتم العثور على رابط التحميل'); | |
| } | |
| } catch (error) { | |
| showStatus(`❌ ${error.message}`, 'error'); | |
| console.error(error); | |
| // فحص الخادم مرة أخرى | |
| checkServer(); | |
| } finally { | |
| // إعادة الزر لحالته | |
| downloadBtn.disabled = false; | |
| downloadBtn.innerHTML = '<span>⬇️</span> تحميل الفيديو'; | |
| } | |
| } | |
| function showStatus(message, type) { | |
| const statusEl = document.getElementById('status'); | |
| statusEl.textContent = message; | |
| statusEl.className = `status-box ${type}`; | |
| } | |
| function fillExample(url) { | |
| document.getElementById('video-url').value = url; | |
| } | |
| function checkServerAgain() { | |
| checkServer(); | |
| } | |
| function copyToClipboard(text) { | |
| navigator.clipboard.writeText(text).then(() => { | |
| alert('✅ تم نسخ الرابط'); | |
| }).catch(() => { | |
| alert('❌ الرجاء نسخ الرابط يدوياً'); | |
| }); | |
| } | |
| // فحص الخادم عند تحميل الصفحة | |
| window.onload = function() { | |
| checkServer(); | |
| }; | |
| // تحميل بالضغط على Enter | |
| document.getElementById('video-url').addEventListener('keypress', (e) => { | |
| if (e.key === 'Enter') downloadVideo(); | |
| }); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment