Erleben Sie die Zukunft des Online-Video-Chats mit unserem Chatroulette Multi-Paar Klon – alles in einer einzigen, leistungsstarken PHP-Datei. Professionell gestaltet wie von einer Marketing-Agentur, bietet dieses Script eine vollständige Chatroulette-Erfahrung mit modernem Design und allen wichtigen Features.
Highlights:
- Multi-Paar-Unterstützung: Verbinde mehrere Nutzer gleichzeitig, automatische Partnerzuweisung und Warteschlange
- Echtzeit-Video & Audio: High-Quality-WebRTC-Streaming für reibungslosen Videochat
- Integrierter Chat: Nachrichten in Echtzeit, Speicherung der letzten 100 Nachrichten
- Automatisches Reconnect: Partnerverlust? Kein Problem, das Script weist sofort einen neuen Partner zu
- Mobile-optimiert: Perfekte Darstellung auf Smartphones und Tablets
- Professionelles Agentur-Design: Modernes Layout, glatte Animationen, stilvolle Buttons
- Einfache Installation: Alles in einer Datei, JSON-Speicherung, sofort einsatzbereit
- Inaktive Nutzer werden automatisch entfernt
Technische Details:
- Vollständig in PHP, AJAX & JavaScript umgesetzt
- Keine zusätzliche Datenbank erforderlich, JSON-Dateien speichern alle Daten
<?php
session_start();
// JSON-Dateien für Multi-Paar, Chat, WebRTC Signalisierung
$pairFile = 'pairs.json';
$webrtcFile = 'webrtc.json';
$chatFile = 'chat.json';
$inactiveTimeout = 60; // Sekunden für Inaktivität
if(!isset($_SESSION['uid'])) $_SESSION['uid'] = 'U'.rand(1000,9999);
function cleanPairs(){
global $pairFile, $inactiveTimeout;
if(!file_exists($pairFile)) return;
$pairs = json_decode(file_get_contents($pairFile),true);
$now = time();
foreach($pairs as $k=>$p){
if(isset($p['time']) && ($now-$p['time'])>$inactiveTimeout) unset($pairs[$k]);
}
file_put_contents($pairFile,json_encode(array_values($pairs)));
}
if(isset($_GET['action'])){
header('Content-Type: application/json');
$action = $_GET['action'];
$uid = $_SESSION['uid'];
// Neue Partner suchen
if($action==='get_pair'){
cleanPairs();
$pairs = file_exists($pairFile)?json_decode(file_get_contents($pairFile),true):[];
$partner = null;
foreach($pairs as &$p){
if(count($p['users'])===1 && $p['users'][0]!==$uid){
$p['users'][]=$uid;
$p['time']=time();
$partner = $p['users'][0];
break;
}
}
if(!$partner) $pairs[]=['users'=>[$uid],'time'=>time()];
file_put_contents($pairFile,json_encode($pairs));
echo json_encode(['partner'=>$partner]);
exit;
}
if($action==='offer' && isset($_POST['data'])){
$webrtc = file_exists($webrtcFile)?json_decode(file_get_contents($webrtcFile),true):[];
$webrtc[$uid]=['offer'=>$_POST['data'],'answer'=>null,'time'=>time()];
file_put_contents($webrtcFile,json_encode($webrtc));
echo json_encode(['status'=>'ok']);
exit;
}
if($action==='answer' && isset($_POST['target']) && isset($_POST['data'])){
$webrtc = file_exists($webrtcFile)?json_decode(file_get_contents($webrtcFile),true):[];
if(isset($webrtc[$_POST['target']])) $webrtc[$_POST['target']]['answer']=$_POST['data'];
file_put_contents($webrtcFile,json_encode($webrtc));
echo json_encode(['status'=>'ok']);
exit;
}
if($action==='check_answer'){
$webrtc = file_exists($webrtcFile)?json_decode(file_get_contents($webrtcFile),true):[];
$ans = isset($webrtc[$uid])?$webrtc[$uid]['answer']:null;
echo json_encode(['answer'=>$ans]);
exit;
}
// Chat
if($action==='get_messages'){
if(!file_exists($chatFile)) file_put_contents($chatFile,json_encode([]));
echo file_get_contents($chatFile);
exit;
}
if($action==='send_message' && isset($_POST['message'])){
$messages = file_exists($chatFile)?json_decode(file_get_contents($chatFile),true):[];
$messages[]=['user'=>$uid,'message'=>htmlspecialchars($_POST['message']),'time'=>date('H:i:s')];
if(count($messages)>100) $messages = array_slice($messages,-100);
file_put_contents($chatFile,json_encode($messages));
echo json_encode(['status'=>'ok']);
exit;
}
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chatroulette Multi-Paar Klon</title>
<style>
body{font-family:'Helvetica Neue',sans-serif;margin:0;padding:0;background:#f0f2f5;color:#333;display:flex;flex-direction:column;min-height:100vh;}
header{background:linear-gradient(90deg,#4A90E2,#50E3C2);color:#fff;padding:1.5rem;text-align:center;box-shadow:0 4px 6px rgba(0,0,0,0.1);}
header h1{margin:0;font-size:2rem;letter-spacing:1px;}
#videoContainer{display:flex;flex-wrap:wrap;justify-content:center;gap:1rem;padding:1rem;transition:0.3s;}
video{width:45%;max-width:480px;border-radius:12px;border:2px solid #4A90E2;box-shadow:0 4px 10px rgba(0,0,0,0.2);transition:0.3s;}
#chat{max-width:700px;margin:auto;background:#fff;border-radius:12px;padding:1rem;box-shadow:0 6px 15px rgba(0,0,0,0.1);flex:1;display:flex;flex-direction:column;}
#messages{height:250px;overflow-y:auto;border:1px solid #ddd;padding:0.5rem;margin-bottom:0.5rem;border-radius:8px;background:#fafafa;}
input[type=text]{width:75%;padding:0.5rem;border-radius:8px;border:1px solid #ccc;font-size:1rem;margin-bottom:0.5rem;}
button{padding:0.5rem 1rem;border:none;border-radius:8px;background:#4A90E2;color:#fff;cursor:pointer;font-size:1rem;transition:0.3s;}
button:hover{background:#357ABD;}
footer{text-align:center;padding:1rem;color:#888;margin-top:auto;background:#f0f2f5;}
a{color:#4A90E2;text-decoration:none;}
a:hover{text-decoration:underline;}
@media(max-width:768px){video{width:100%;}}
</style>
</head>
<body>
<header><h1>Chatroulette Multi-Paar Klon</h1></header>
<div id="videoContainer">
<video id="localVideo" autoplay muted></video>
<video id="remoteVideo" autoplay></video>
</div>
<div id="chat">
<div id="messages"></div>
<input type="text" id="messageInput" placeholder="Nachricht eingeben...">
<button onclick="sendMessage()">Senden</button>
</div>
<footer>© <?=date('Y')?> <a href="http://www.dreamcodes.net" target="_blank">Dreamcodes</a></footer>
<script>
let localStream, pc, partnerUid, reconnectInterval;
function fetchMessages(){
fetch('?action=get_messages').then(r=>r.json()).then(data=>{
const messagesDiv = document.getElementById('messages');
messagesDiv.innerHTML = data.map(m=>`<b>${m.user}</b> [${m.time}]: ${m.message}`).join('<br>');
messagesDiv.scrollTop = messagesDiv.scrollHeight;
});
}
function sendMessage(){
const msg=document.getElementById('messageInput').value;
if(!msg) return;
fetch('?action=send_message',{method:'POST',body:new URLSearchParams({message:msg})})
.then(()=>{document.getElementById('messageInput').value=''; fetchMessages();});
}
setInterval(fetchMessages,2000);
fetchMessages();
async function startWebRTC(){
localStream = await navigator.mediaDevices.getUserMedia({video:true,audio:true});
document.getElementById('localVideo').srcObject = localStream;
while(!partnerUid){
const resp = await fetch('?action=get_pair').then(r=>r.json());
partnerUid = resp.partner;
await new Promise(r=>setTimeout(r,1000));
}
await connectPeer();
}
async function connectPeer(){
pc = new RTCPeerConnection({iceServers:[{urls:'stun:stun.l.google.com:19302'}]});
localStream.getTracks().forEach(track=>pc.addTrack(track,localStream));
pc.ontrack = e=>{document.getElementById('remoteVideo').srcObject=e.streams[0]};
pc.onconnectionstatechange = ()=>{if(pc.connectionState==='disconnected'){partnerUid=null; startWebRTC();}};
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
await fetch('?action=offer',{method:'POST',body:new URLSearchParams({data:JSON.stringify(offer)})});
let answer = null;
while(!answer){
answer = await fetch('?action=check_answer').then(r=>r.json()).then(d=>d.answer);
await new Promise(r=>setTimeout(r,1000));
}
await pc.setRemoteDescription(JSON.parse(answer));
}
startWebRTC().catch(console.error);
</script>
</body>
</html>