Spaces:
Paused
Paused
| const TelegramBot = require('node-telegram-bot-api'); | |
| const ffmpegInstaller = require('@ffmpeg-installer/ffmpeg'); | |
| const ffmpeg = require('fluent-ffmpeg'); | |
| const si = require('systeminformation'); | |
| const TOKEN = '7899900752:AAE6xg24cB29m2O7_-Ox8P9e0Fhmyw6Y8bo'; | |
| const ADMIN_ID = 7708913693; | |
| ffmpeg.setFfmpegPath(ffmpegInstaller.path); | |
| const bot = new TelegramBot(TOKEN, { polling: true }); | |
| const userStreams = {}; // { chatId: { streamId: { proc, timeout } } } | |
| const streamCounter = {}; // { chatId: number } | |
| function getSystemSettings() { | |
| return si.cpu() | |
| .then(cpu => si.mem() | |
| .then(mem => { | |
| const cores = cpu.cores || 1; | |
| const ramGB = mem.total / 1024 / 1024 / 1024; | |
| let preset = 'ultrafast'; | |
| if (cores >= 8) preset = 'faster'; | |
| else if (cores >= 4) preset = 'veryfast'; | |
| let bitrate = '800k'; | |
| let resolution = '640x360'; | |
| if (ramGB >= 8) { | |
| bitrate = '3000k'; | |
| resolution = '1280x720'; | |
| } else if (ramGB >= 4) { | |
| bitrate = '1500k'; | |
| resolution = '854x480'; | |
| } | |
| return { preset, bitrate, resolution }; | |
| }) | |
| ); | |
| } | |
| function usageExample(chatId) { | |
| return bot.sendMessage(chatId, | |
| `❌ الأمر غير صحيح أو غير مكتمل.\n\n` + | |
| `استخدم أحد الأوامر التالية:\n\n` + | |
| `/stream streamkey m3u8_url [cc_text]\n` + | |
| `مثال:\n` + | |
| `/stream FB-123456789 https://example.com/stream.m3u8 مرحباً بالعالم\n\n` + | |
| `/stop stream_id\n` + | |
| `مثال:\n` + | |
| `/stop 1\n\n` + | |
| `/check\n` + | |
| `لعرض معلومات النظام` | |
| ); | |
| } | |
| // /stream | |
| bot.onText(/^\/stream(?:\s+(.+))?$/, async (msg, match) => { | |
| const chatId = msg.chat.id; | |
| const argsText = match[1]; | |
| if (!argsText) return usageExample(chatId); | |
| const args = argsText.trim().split(/\s+/); | |
| if (args.length < 2) return usageExample(chatId); | |
| const key = args[0]; | |
| const m3u8 = args[1]; | |
| const ccText = args.slice(2).join(' '); | |
| if (!streamCounter[chatId]) streamCounter[chatId] = 0; | |
| streamCounter[chatId]++; | |
| const streamId = streamCounter[chatId]; | |
| try { | |
| const { preset, bitrate, resolution } = await getSystemSettings(); | |
| let command = ffmpeg(m3u8) | |
| .videoCodec('libx264') | |
| .audioCodec('aac') | |
| .outputOptions([ | |
| `-preset ${preset}`, | |
| `-b:v ${bitrate}`, | |
| '-f', 'flv' | |
| ]) | |
| .size(resolution); | |
| if (ccText && ccText.trim() !== '') { | |
| const filter = `drawbox=x=(w-text_w)/2-10:y=h-text_h-40:w=text_w+20:h=text_h+30:[email protected]:t=max,` + | |
| `drawtext=text='${ccText}':fontcolor=white:fontsize=24:x=(w-text_w)/2:y=h-text_h-30`; | |
| command = command.videoFilters(filter); | |
| } | |
| const rtmpUrl = `rtmps://live-api-s.facebook.com:443/rtmp/${key}`; | |
| command = command.output(rtmpUrl); | |
| const proc = command.spawn(); | |
| if (!userStreams[chatId]) userStreams[chatId] = {}; | |
| userStreams[chatId][streamId] = { proc }; | |
| const timeout = setTimeout(() => { | |
| if (proc && !proc.killed) { | |
| proc.kill('SIGTERM'); | |
| bot.sendMessage(chatId, `⏹️ تم إيقاف البث معرف ${streamId} تلقائياً بعد 4 ساعات.`); | |
| delete userStreams[chatId][streamId]; | |
| } | |
| }, 4 * 60 * 60 * 1000); | |
| userStreams[chatId][streamId].timeout = timeout; | |
| bot.sendMessage(chatId, | |
| `✅ تم بدء البث بنجاح!\n\n` + | |
| `▶️ معرف البث: ${streamId}\n` + | |
| `الدقة: ${resolution}\n` + | |
| `معدل البت: ${bitrate}\n` + | |
| `الإعدادات: ${preset}\n` + | |
| `⏳ سيتم إيقاف البث تلقائياً بعد 4 ساعات` | |
| ); | |
| proc.on('error', err => { | |
| bot.sendMessage(chatId, `❌ حدث خطأ في البث معرف ${streamId}:\n${err.message}`); | |
| clearTimeout(timeout); | |
| delete userStreams[chatId][streamId]; | |
| }); | |
| proc.on('exit', (code, signal) => { | |
| if (signal === 'SIGTERM') { | |
| bot.sendMessage(chatId, `⏹️ تم إيقاف البث معرف ${streamId}.`); | |
| } else if (code !== 0) { | |
| bot.sendMessage(chatId, `⚠️ البث معرف ${streamId} انتهى برمز خروج ${code}.`); | |
| } | |
| clearTimeout(timeout); | |
| delete userStreams[chatId][streamId]; | |
| }); | |
| } catch (e) { | |
| return bot.sendMessage(chatId, `❌ فشل بدء البث:\n${e.message}`); | |
| } | |
| }); | |
| // /stop | |
| bot.onText(/^\/stop(?:\s+(\d+))?$/, (msg, match) => { | |
| const chatId = msg.chat.id; | |
| const streamId = match[1] ? Number(match[1]) : null; | |
| if (!streamId) return usageExample(chatId); | |
| if (!userStreams[chatId] || !userStreams[chatId][streamId]) { | |
| return bot.sendMessage(chatId, `⚠️ لا يوجد بث نشط بالمعرف ${streamId}.`); | |
| } | |
| const { proc, timeout } = userStreams[chatId][streamId]; | |
| if (proc && !proc.killed) { | |
| proc.kill('SIGTERM'); | |
| clearTimeout(timeout); | |
| bot.sendMessage(chatId, `⏹️ تم إيقاف البث معرف ${streamId} من قبلك.`); | |
| delete userStreams[chatId][streamId]; | |
| } else { | |
| bot.sendMessage(chatId, `⚠️ البث معرف ${streamId} متوقف بالفعل.`); | |
| } | |
| }); | |
| // /check | |
| bot.onText(/\/check/, async (msg) => { | |
| const chatId = msg.chat.id; | |
| try { | |
| const cpu = await si.cpu(); | |
| const mem = await si.mem(); | |
| const osInfo = await si.osInfo(); | |
| const message = ` | |
| <b>معلومات النظام:</b> | |
| نظام التشغيل: ${osInfo.distro} ${osInfo.release} | |
| المعالج: ${cpu.manufacturer} ${cpu.brand} (${cpu.cores} أنوية) | |
| الذاكرة: ${(mem.total / 1024 / 1024 / 1024).toFixed(2)} GB | |
| `; | |
| bot.sendMessage(chatId, message, { parse_mode: 'HTML' }); | |
| } catch (err) { | |
| bot.sendMessage(chatId, `❌ خطأ في جلب معلومات النظام: ${err.message}`); | |
| } | |
| }); | |
| // رد افتراضي | |
| bot.on('message', (msg) => { | |
| const chatId = msg.chat.id; | |
| const text = msg.text || ""; | |
| if ( | |
| text.startsWith('/stream') || | |
| text.startsWith('/stop') || | |
| text.startsWith('/check') | |
| ) return; | |
| usageExample(chatId); | |
| }); | |
| console.log('🤖 البوت يعمل الآن...'); |