Fake Camera - Ommogle

Remplace ta caméra par une image personnalisée sur OmeTV, Omegle et sites similaires

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Fake Camera - Ommogle
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Remplace ta caméra par une image personnalisée sur OmeTV, Omegle et sites similaires
// @author       Claude
// @match        *://*.ommogle.com/*
// @grant        none
// @run-at       document-start
// ==/UserScript==

(function () {
  'use strict';

  // ─── CONFIG ───────────────────────────────────────────────
  const CONFIG = {
    imageUrl: null,       // URL de ton image (rempli automatiquement via le panneau)
    fps: 30,
    width: 640,
    height: 480,
  };
  // ──────────────────────────────────────────────────────────

  let fakeStream = null;
  let canvas = null;
  let ctx = null;
  let img = null;
  let animFrame = null;

  // Crée le canvas caché qui sert de fausse caméra
  function createFakeStream(imageUrl) {
    if (fakeStream) {
      fakeStream.getTracks().forEach(t => t.stop());
    }
    if (animFrame) cancelAnimationFrame(animFrame);

    canvas = document.createElement('canvas');
    canvas.width = CONFIG.width;
    canvas.height = CONFIG.height;
    ctx = canvas.getContext('2d');

    img = new Image();
    img.crossOrigin = 'anonymous';

    img.onload = () => {
      const draw = () => {
        ctx.drawImage(img, 0, 0, CONFIG.width, CONFIG.height);
        animFrame = setTimeout(() => requestAnimationFrame(draw), 1000 / CONFIG.fps);
      };
      draw();
    };

    img.onerror = () => {
      // Si l'image échoue, dessine un écran noir avec texte
      ctx.fillStyle = '#000';
      ctx.fillRect(0, 0, CONFIG.width, CONFIG.height);
      ctx.fillStyle = '#fff';
      ctx.font = '20px sans-serif';
      ctx.textAlign = 'center';
      ctx.fillText('Image non chargée', CONFIG.width / 2, CONFIG.height / 2);
    };

    img.src = imageUrl;
    fakeStream = canvas.captureStream(CONFIG.fps);
    return fakeStream;
  }

  // Override getUserMedia pour retourner le faux flux
  const originalGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);

  navigator.mediaDevices.getUserMedia = async function (constraints) {
    // Si la caméra n'est pas demandée, on laisse passer normalement
    if (!constraints || !constraints.video) {
      return originalGetUserMedia(constraints);
    }

    // Si aucune image choisie, on laisse passer la vraie caméra
    if (!CONFIG.imageUrl) {
      console.warn('[FakeCam] Aucune image choisie, utilisation de la vraie caméra.');
      return originalGetUserMedia(constraints);
    }

    console.log('[FakeCam] Flux caméra remplacé par image personnalisée.');
    return createFakeStream(CONFIG.imageUrl);
  };

  // ─── UI PANNEAU ───────────────────────────────────────────
  function createPanel() {
    const panel = document.createElement('div');
    panel.id = 'fakecam-panel';
    panel.innerHTML = `
      <div id="fakecam-header">📷 Fake Camera</div>
      <div id="fakecam-body">
        <label>Colle une URL d'image :</label>
        <input type="text" id="fakecam-url" placeholder="https://..." />
        <label>Ou upload une image :</label>
        <input type="file" id="fakecam-file" accept="image/*" />
        <div id="fakecam-preview-wrap">
          <img id="fakecam-preview" />
        </div>
        <button id="fakecam-apply">✅ Appliquer</button>
        <button id="fakecam-reset">🔄 Désactiver (vraie caméra)</button>
        <div id="fakecam-status">En attente d'une image...</div>
      </div>
    `;

    const style = document.createElement('style');
    style.textContent = `
      #fakecam-panel {
        position: fixed;
        top: 16px;
        right: 16px;
        z-index: 999999;
        background: #1a1a2e;
        color: #eee;
        font-family: monospace;
        font-size: 13px;
        border: 1px solid #444;
        border-radius: 12px;
        width: 260px;
        box-shadow: 0 8px 32px rgba(0,0,0,0.6);
        overflow: hidden;
        transition: all 0.3s ease;
      }
      #fakecam-header {
        background: #16213e;
        padding: 10px 14px;
        font-weight: bold;
        font-size: 14px;
        cursor: pointer;
        user-select: none;
        border-bottom: 1px solid #333;
        letter-spacing: 1px;
      }
      #fakecam-body {
        padding: 12px;
        display: flex;
        flex-direction: column;
        gap: 8px;
      }
      #fakecam-body label {
        font-size: 11px;
        color: #aaa;
        margin-bottom: 2px;
      }
      #fakecam-url {
        background: #0f3460;
        border: 1px solid #555;
        color: #fff;
        border-radius: 6px;
        padding: 6px 8px;
        font-size: 12px;
        width: 100%;
        box-sizing: border-box;
      }
      #fakecam-file {
        font-size: 11px;
        color: #ccc;
      }
      #fakecam-preview-wrap {
        display: flex;
        justify-content: center;
      }
      #fakecam-preview {
        max-width: 100%;
        max-height: 100px;
        border-radius: 6px;
        border: 1px solid #555;
        display: none;
        object-fit: cover;
      }
      #fakecam-apply, #fakecam-reset {
        border: none;
        border-radius: 6px;
        padding: 8px;
        cursor: pointer;
        font-size: 12px;
        font-family: monospace;
        width: 100%;
      }
      #fakecam-apply {
        background: #0f9b58;
        color: #fff;
      }
      #fakecam-apply:hover { background: #0d7a46; }
      #fakecam-reset {
        background: #444;
        color: #ccc;
      }
      #fakecam-reset:hover { background: #333; }
      #fakecam-status {
        font-size: 11px;
        color: #f0a500;
        text-align: center;
        padding: 4px;
      }
    `;

    document.head.appendChild(style);
    document.body.appendChild(panel);

    // Toggle panel
    document.getElementById('fakecam-header').onclick = () => {
      const body = document.getElementById('fakecam-body');
      body.style.display = body.style.display === 'none' ? 'flex' : 'none';
    };

    // Upload fichier → convertir en base64
    document.getElementById('fakecam-file').onchange = function () {
      const file = this.files[0];
      if (!file) return;
      const reader = new FileReader();
      reader.onload = (e) => {
        document.getElementById('fakecam-url').value = e.target.result;
        showPreview(e.target.result);
      };
      reader.readAsDataURL(file);
    };

    // Aperçu depuis URL
    document.getElementById('fakecam-url').oninput = function () {
      if (this.value) showPreview(this.value);
    };

    function showPreview(src) {
      const preview = document.getElementById('fakecam-preview');
      preview.src = src;
      preview.style.display = 'block';
    }

    // Appliquer
    document.getElementById('fakecam-apply').onclick = () => {
      const url = document.getElementById('fakecam-url').value.trim();
      if (!url) {
        setStatus('❌ Aucune image fournie !', '#e74c3c');
        return;
      }
      CONFIG.imageUrl = url;
      createFakeStream(url);
      setStatus('✅ Image activée ! Relance la caméra sur le site.', '#0f9b58');
    };

    // Reset
    document.getElementById('fakecam-reset').onclick = () => {
      CONFIG.imageUrl = null;
      if (fakeStream) fakeStream.getTracks().forEach(t => t.stop());
      fakeStream = null;
      if (animFrame) cancelAnimationFrame(animFrame);
      setStatus('🔄 Vraie caméra réactivée.', '#aaa');
    };

    function setStatus(msg, color) {
      const s = document.getElementById('fakecam-status');
      s.textContent = msg;
      s.style.color = color || '#f0a500';
    }
  }

  // Attendre que le DOM soit prêt
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', createPanel);
  } else {
    createPanel();
  }

})();