From 227068560aede525969f2e86c240f1598c9779cc Mon Sep 17 00:00:00 2001 From: Nordi98 Date: Sun, 3 Aug 2025 16:59:05 +0200 Subject: [PATCH] Update main.lua --- resources/[tools]/nordi_dj/server/main.lua | 150 +++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/resources/[tools]/nordi_dj/server/main.lua b/resources/[tools]/nordi_dj/server/main.lua index 6fac67443..68c565d4d 100644 --- a/resources/[tools]/nordi_dj/server/main.lua +++ b/resources/[tools]/nordi_dj/server/main.lua @@ -261,3 +261,153 @@ CreateThread(function() print('[DJ System] Cache bereinigt') end end) + +-- Füge diese Funktionen zu deiner server/main.lua hinzu: + +local function extractYouTubeVideoId(url) + -- Verschiedene YouTube URL Formate unterstützen + local patterns = { + "youtube%.com/watch%?v=([^&]+)", + "youtu%.be/([^?]+)", + "youtube%.com/embed/([^?]+)", + "youtube%.com/v/([^?]+)" + } + + for _, pattern in ipairs(patterns) do + local videoId = string.match(url, pattern) + if videoId then + return videoId + end + end + + return nil +end + +local function cleanYouTubeUrl(url) + local videoId = extractYouTubeVideoId(url) + if not videoId then + return nil + end + + -- Erstelle saubere YouTube URL ohne Playlist-Parameter + return "https://www.youtube.com/watch?v=" .. videoId +end + +-- YouTube zu MP3 Konvertierung (mit yt-dlp oder youtube-dl) +local function convertYouTubeUrl(url, callback) + local videoId = extractYouTubeVideoId(url) + if not videoId then + callback(nil, "Ungültige YouTube URL") + return + end + + -- Prüfe Cache zuerst + MySQL.Async.fetchScalar('SELECT converted_url FROM dj_url_cache WHERE original_url = ? AND expires_at > NOW()', {url}, function(cachedUrl) + if cachedUrl then + print('[DJ System] URL aus Cache geladen: ' .. videoId) + callback(cachedUrl, nil) + + -- Update hit count + MySQL.Async.execute('UPDATE dj_url_cache SET hit_count = hit_count + 1, last_accessed = NOW() WHERE original_url = ?', {url}) + return + end + + -- Konvertiere mit yt-dlp (externe Lösung) + convertWithYtDlp(url, videoId, callback) + end) +end + +-- Konvertierung mit yt-dlp (benötigt yt-dlp Installation) +local function convertWithYtDlp(originalUrl, videoId, callback) + local cleanUrl = "https://www.youtube.com/watch?v=" .. videoId + + -- yt-dlp Befehl ausführen + local command = string.format('yt-dlp --get-url --format "bestaudio[ext=m4a]/best[ext=mp4]/best" "%s"', cleanUrl) + + -- Führe Befehl aus (das ist ein vereinfachtes Beispiel) + -- In der Praxis würdest du einen HTTP Request an einen externen Service machen + + -- Für jetzt: Verwende eine alternative Lösung + useAlternativeConversion(originalUrl, videoId, callback) +end + +-- Alternative: Verwende einen Online-Service +local function useAlternativeConversion(originalUrl, videoId, callback) + -- Option 1: Verwende YouTube Embed URL (funktioniert manchmal) + local embedUrl = "https://www.youtube.com/embed/" .. videoId .. "?autoplay=1" + + -- Option 2: Verwende einen kostenlosen Konvertierungsservice + -- ACHTUNG: Diese Services können instabil sein! + local convertedUrl = "https://youtube-mp3-download.com/api/convert/" .. videoId + + -- Option 3: Verwende die originale URL und lass den Client damit umgehen + local fallbackUrl = "https://www.youtube.com/watch?v=" .. videoId + + -- Speichere im Cache (24 Stunden gültig) + local expiresAt = os.date('%Y-%m-%d %H:%M:%S', os.time() + 86400) + + MySQL.Async.execute('INSERT INTO dj_url_cache (original_url, converted_url, video_id, expires_at) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE converted_url = VALUES(converted_url), expires_at = VALUES(expires_at)', { + originalUrl, + fallbackUrl, -- Verwende fallback URL + videoId, + expiresAt + }, function(affectedRows) + if affectedRows > 0 then + print('[DJ System] URL in Cache gespeichert: ' .. videoId) + end + + callback(fallbackUrl, nil) + end) +end + +-- Aktualisiere die PlayMusic Funktion +RegisterServerEvent('dj:playMusic') +AddEventHandler('dj:playMusic', function(title, url, volume) + local src = source + local Player = QBCore.Functions.GetPlayer(src) + if not Player then return end + + print('[DJ System] Spiele Musik ab: ' .. title .. ' | URL: ' .. url) + + -- Prüfe ob es eine YouTube URL ist + if string.match(url, "youtube%.com") or string.match(url, "youtu%.be") then + convertYouTubeUrl(url, function(convertedUrl, error) + if error then + TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Konvertieren: ' .. error, 'error') + return + end + + if convertedUrl then + -- Sende konvertierte URL an alle Clients + TriggerClientEvent('dj:playMusicClient', -1, title, convertedUrl, volume) + + -- Speichere in Session History + MySQL.Async.execute('INSERT INTO dj_session_history (dj_citizenid, dj_name, booth_name, song_title, song_url, song_type, volume, session_start) VALUES (?, ?, ?, ?, ?, ?, ?, NOW())', { + Player.PlayerData.citizenid, + Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname, + 'Unknown', -- Du kannst hier den Booth-Namen hinzufügen + title, + url, + 'youtube', + volume + }) + else + TriggerClientEvent('QBCore:Notify', src, 'Konvertierung fehlgeschlagen', 'error') + end + end) + else + -- Direkte Audio URL + TriggerClientEvent('dj:playMusicClient', -1, title, url, volume) + + -- Speichere in Session History + MySQL.Async.execute('INSERT INTO dj_session_history (dj_citizenid, dj_name, booth_name, song_title, song_url, song_type, volume, session_start) VALUES (?, ?, ?, ?, ?, ?, ?, NOW())', { + Player.PlayerData.citizenid, + Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname, + 'Unknown', + title, + url, + 'direct', + volume + }) + end +end)