EDI Machine - Build Your Video Interactive Experiences With IA

EDI Self-Hosted Machine. It’s a template for a small website with a video player integrated with EDI and a few features like subtitle area over the video, a log panel and some floating status boxes. All EDI, VideoPlayer and Machine Features are exposed through a simple API that’s designed specifically for the IA to use.

You can build interactive video experiences integrated with FunScripts just by describing in natural language what you want, and IA will do the programming for you. I built a first experience almost without touching the code myself, even though I’m an experienced programmer — the goal was to see if, by giving instructions and asking for refinements, I could get ChatGPT to assemble the whole thing.

When running The Machine is controlled entirely with the mouse. There are a few inputs available:

  • main click,
  • secondary click,
  • mouse wheel up,
  • mouse wheel down,
  • middle-wheel click,
  • and double-click on either button.

To have IA build an experience for you, This JavaScript helper block into your prompt. Then ask it, using this framework/SDK, to create the experience you want on top of your video: pass the video filenames, the timestamps, what behavior you want in each section, what it should say, what it shouldn’t do with the devices, and how you want it to react.

Finally


DOWNLOAD Edi Machine (Mega)

Example Experience - Loked in Loop heaven - EDI Machine


Code Block for Prompt

// Mini EDI Host Machine (for AI usage)
// No implementation, only what exists and what it does.

// -----------------------------------------------------------------------------
// Core
// -----------------------------------------------------------------------------
// - <video> = master timeline (currentTime in seconds).
// - EDI plays "definitions" by name: type "gallery" | "reaction" | "filler".
// - Devices are assigned to logical channels ("stroker", "anal", "vibe"...).
// - Each channel has its own queue (gallery/filler/reaction).
// - An "experience" = module with createExperience(api) that returns handlers
//   for mouse/wheel to control video + EDI.

// -----------------------------------------------------------------------------
// Types (conceptual)
// -----------------------------------------------------------------------------
// DeviceDto: {
//   name, variants?, isReady?, selectedVariant?,
//   channel?, min?, max?        // intensity 0–100
// }
//
// DefinitionResponseDto: {
//   name, type,                  // used in play(name)
//   fileName?, startTime?, endTime?, duration?, loop?, description?
// }

// -----------------------------------------------------------------------------
// EdiRestClient (server side)
// -----------------------------------------------------------------------------
// new EdiRestClient({ baseUrl, defaultHeaders?, fetchImpl? })

// Devices:
//   getDevices()
//     // List devices with channel, variants and min/max intensity.
//   setDeviceVariant(name, variant)
//     // Change the active Script Variant of the device.
//   setDeviceRange(name, { min, max })
//     // Limit how much that device can go (0–100).
//   setDeviceChannel(name, channel)
//     // Connect device to a logical channel (stroker, anal, etc.).

// Playback (patterns):
//   play(defName, { seek?, channels? }?)
//     // Launch a pattern by name.
//     // seek: starting point (seconds). channels: one or multiple channels.
//   playSynced(defName, { channels? }?)
//     // Same as play(), but uses current video time as seek.
//     // Makes pattern align with video timeline.
//   stop({ channels? }?)
//     // Stop whatever is running (global or only on certain channels).
//   setIntensity(max, { channels? }?)
//     // "Master fader" 0–100 global or per channel, without changing base script.

// -----------------------------------------------------------------------------
// Host → Experience API (createExperience(api))
// -----------------------------------------------------------------------------
// Video helpers:
//   api.getVideoTime()          // current video time (seconds).
//   api.getDuration()           // total duration or NaN.
//   api.getVideoElement()       // direct access to <video>.
//   api.onVideoTime(h)          // subscribe to timeupdate ({ videoTime, ... }).
//
//   api.playVideo(src?, seek?)  // optionally change src, seek and play.
//   api.pauseVideo()            // pause.
//   api.toggleVideo()           // toggle play/pause.
//   api.seekVideo(delta)        // relative seek, clamp >= 0.
//   api.setMuted(muted)         // mute on/off.
//   api.toggleMuted()           // toggle mute state.
//   api.setVideoSource(src)     // change <video> src.
//   api.getVideoElement()       // direct access to <video> element.

// EDI passthrough (same as above):
//   api.getDevices()
//   api.setDeviceVariant(name, variant)
//   api.setDeviceRange(name, { min, max })
//   api.setDeviceChannel(name, channel)
//
//   api.play(defName, { channels?, seek? }?)
//     // Direct version: you choose explicit seek (not necessarily videoTime).
//   api.playSynced(defName, { channels? }?)
//     // Shortcut: seek = api.getVideoTime(). Ideal for video-tied events.
//   api.stop({ channels? }?)
//   api.setIntensity(max, { channels? }?)

// UI / debug:
//   api.say(text, seconds?)
//     // Show subtitle-like overlay (0/omit => until next say).
//   api.log(message)
//     // Write message to HUD with current time (useful for debug).
//   api.setInfo(html)
//     // Render HTML in info panel (controls-info).
//   api.hideInfo()
//     // Hide info panel.

// -----------------------------------------------------------------------------
// Experience module shape
// -----------------------------------------------------------------------------
// ctx = { videoTime, duration, rawEvent }
//
// export function createExperience(api) {
//   // optional setup (subscribe to onVideoTime, configure devices, etc.)
//   return {
//     onMousePrimaryDown(ctx),
//     onMouseSecondaryDown(ctx),
//     onMousePrimaryDouble(ctx),
//     onMouseSecondaryDouble(ctx),
//     onMouseWheel(ctx, delta),  // generic (delta = deltaY)
//     onMouseWheelClick(ctx),    // middle button
//     onMouseWheelDown(ctx),     // wheel down (deltaY > 0)
//     onMouseWheelUp(ctx)        // wheel up (deltaY < 0)
//   };
// }
//
// URL Parameters:
//   ?edi=<baseUrl>    // EDI server base URL (default: 'http://localhost:5000')
//   ?exp=<moduleUrl>  // experience module URL (default: './default-experience.js')
//
// Global reference:
//   window.ediVideoHost  // EdiVideoHost instance available globally

Examples:

Simple Edge Pause with auto Resume

Prompt:
Using this SDK, create an experience that, on start, loads the video ./Cock Hero 1.mp4 (the definition named is Cock Hero 1) and begins playing it. Each time I press the primary click, all device activity should stop for 30 seconds, then resume using playSynced at 50% intensity for another 30 seconds, and finally return to 100% intensity. Throughout this cycle, the video continues playing

Result :

// Cock Hero Control Experience
// ---------------------------------------------------------------
// Behavior:
// - On start: loads and plays "Cock Hero 1.mp4".
// - On primary click:
//     1) Stop all device activity for 30 seconds.
//     2) Resume using playSynced("Cock Hero 1") at 50% intensity for 30 seconds.
//     3) Return to 100% intensity and keep playing synced.
// - Video never pauses.

export function createExperience(api) {
  let running = true;  // click lock to prevent re-triggering

  // Simple async delay helper
  const delay = ms => new Promise(res => setTimeout(res, ms));

  // Start: load video and play from the beginning
  api.playVideo("./Cock Hero 1.mp4", 0);
  api.say("Loading Cock Hero 1…");  
  api.log("Experience initialized.");

  // Main handler for primary click
  async function handlePrimary() {
    // Prevent multiple concurrent executions
    if (!running) return;
    running = false;

    api.log("PRIMARY CLICK → Stop devices for 30s");
    api.stop();          // stop all channels
    api.setIntensity(0); // fully mute intensity

    await delay(30000);  // wait 30 seconds

    api.log("PRIMARY CLICK → Resume at 50% for 30s");
    api.setIntensity(50); 
    api.playSynced("Cock Hero 1"); // sync pattern with current video time

    await delay(30000);

    api.log("PRIMARY CLICK → Back to 100% intensity");
    api.setIntensity(100);
    api.playSynced("Cock Hero 1"); // keep aligned with video

    running = true; // unlock handler
  }

  // Experience event map
  return {
    onMousePrimaryDown: ctx => handlePrimary(ctx),
    onMouseSecondaryDown() {},
    onMousePrimaryDouble() {},
    onMouseSecondaryDouble() {},
    onMouseWheel() {},
    onMouseWheelClick() {},
    onMouseWheelDown() {},
    onMouseWheelUp() {}
  };
}

Cock Hero With 3 Lifes, Ruin and Post Orgasm Alternative Endings

Prompt:
Using this SDK, create a Cock Hero experience with 3 lives and 2 alternate endings.
Load the video ./CockHero.mp4 (definition name: cockHero), which lasts 60 minutes.
When the user presses the primary click, pause all device activity for 30 seconds, then resume synced to the video and subtract 1 life.
If the player loses all lives before the 30-minute mark, jump to 60:00 where the ruined orgasm sequence starts.
If the player loses all lives after the 30-minute mark, jump to 65:00 where the full orgasm + punishment post orgasm sequence starts.
When the video reaches minute 60 during normal gameplay, stop the video so the later scenes remain hidden.

// cock-hero-lives-experience.js

// Cock Hero with 3 lives and 2 alternate endings
export function createExperience(api) {

  // --- Config (seconds) ------------------------------------------------------
  const VIDEO_SRC = './CockHero.mp4';
  const DEF_NAME = 'cockHero';

  const GAME_DURATION = 60 * 60;   // 60 minutes of gameplay
  const HALF_MARK    = 30 * 60;    // 30 minutes threshold
  const RUINED_TIME  = 60 * 60;    // Ruined orgasm sequence
  const FULL_TIME    = 65 * 60;    // Full orgasm + punishment sequence

  const PENALTY_SECONDS = 30;

  // --- State -----------------------------------------------------------------
  let lives = 3;
  let isGameOver = false;
  let inPenalty = false;
  let penaltyTimeoutId = null;

  // --- Helpers ---------------------------------------------------------------
  const formatLives = () => `Lives: ${'❤'.repeat(lives)}${lives === 0 ? ' (GAME OVER)' : ''}`;

  function updateHud(message) {
    const status = `${message}<br>${formatLives()}`;
    api.say(status);
    api.setInfo(status);
    api.log(`[HUD] ${message} | ${formatLives()}`);
  }

  function clearPenaltyTimer() {
    if (!penaltyTimeoutId) return;
    clearTimeout(penaltyTimeoutId);
    penaltyTimeoutId = null;
  }

  function startBasePlayback() {
    api.playVideo(VIDEO_SRC, 0);
    api.playSynced(DEF_NAME);
    api.setIntensity(100);
    updateHud('Cock Hero challenge begins (3 lives)');
  }

  function stopEverything(reason) {
    if (isGameOver) return;
    isGameOver = true;
    clearPenaltyTimer();
    api.stop();
    api.pauseVideo();
    api.log(`[END] ${reason}`);
  }

  function jumpToEnding(lastLossTime) {
    const beforeHalf = lastLossTime < HALF_MARK;
    const target = beforeHalf ? RUINED_TIME : FULL_TIME;
    const label  = beforeHalf ? 'Ruined orgasm 💀' : 'Full orgasm + punishment 😈';

    isGameOver = true;
    clearPenaltyTimer();
    inPenalty = false;

    api.playVideo(VIDEO_SRC, target);
    api.playSynced(DEF_NAME);
    api.setIntensity(100);

    api.say(label, 15);
    api.log(`[ENDING] Jump to ${label} at ${Math.round(target / 60)} min`);
    api.setInfo(`${label}<br>You lost all your lives.`);
  }

  function applyPenalty(ctx) {
    if (isGameOver) return;
    if (inPenalty) return;
    if (lives <= 0) return;

    const lossTime = api.getVideoTime();
    lives -= 1;
    inPenalty = true;

    api.stop();
    updateHud(`You lost a life. ${PENALTY_SECONDS}s penalty…`);

    if (lives === 0) {
      penaltyTimeoutId = setTimeout(() => {
        jumpToEnding(lossTime);
      }, PENALTY_SECONDS * 1000);
      return;
    }

    penaltyTimeoutId = setTimeout(() => {
      inPenalty = false;
      api.playSynced(DEF_NAME);
      api.setIntensity(100);
      updateHud('Back in action. Stay in rhythm…');
    }, PENALTY_SECONDS * 1000);
  }

  // --- Video time listener ---------------------------------------------------
  api.onVideoTime(({ videoTime }) => {
    if (isGameOver) return;
    if (inPenalty) return;

    // If the player survives to minute 60 with lives left, stop the video.
    if (videoTime >= GAME_DURATION && lives > 0) {
      stopEverything('Reached minute 60 with lives remaining.');
      api.say('Challenge complete. You reached 60 minutes, but no ending for you 😏', 15);
      api.setInfo('Challenge complete.<br>You survived the full game but earned no ending.');
    }
  });

  // --- Init ------------------------------------------------------------------
  startBasePlayback();

  // --- Event handlers --------------------------------------------------------
  return {
    onMousePrimaryDown(ctx) {
      applyPenalty(ctx);
    },
    onMouseSecondaryDown(ctx) {
      api.toggleVideo();
      api.log('[Input] Secondary click: toggle video');
    },
    onMousePrimaryDouble(ctx) {
      api.say(`Status — ${formatLives()}`, 3);
      api.log('[Input] Primary double-click: show status');
    },
    onMouseSecondaryDouble(ctx) {
      // Not used
    },
    onMouseWheelClick(ctx) {
      // Not used
    }
  };
}
8 Likes

Thanks for the examples you’ve shared.

I’m looking for some appropriate multiple orgasm JOI/JOE videos to build a simple experience around.

The idea is that the user will be able to keep the video in sync with whether or not they’re about to cum. Moving the video on to the right place if they’ve completed faster than the instructions, etc.

1 Like

I can’t wait to try this. Are the games and videos fixed? Or can the user choose their own experience personalized to them.

I’m not familiar with AI coding, so I’m curious, where do I find this “IA” program? Google finds no relevant results with just this 2 letter name and searching for “IA code” or similar, it shows generic AI pages.

When Im trying to test it, primary click just pauses the video. Ive tried changing it to scroll wheel but that doesnt do anything. Any ideas?

If you can show me a code repo or give me a high-level overview of what you want to do, I can give you better advice. As for the click thing, I had to ask ChatGPT to hide the video controls

Hi ZSG,

In some countries such as France and Spain, the abbreviation for Artificial Intelligence is IA.

So when the author is referring to IA, they’re really just referring to a generic AI language model, not a specific package or product.

Most language models like ChatGPT should be capable of generating working code for the framework that the author shared.

Ah, that makes sense. Thanks for clarifying.
Hopefully ChatGPT will cooperate with me, as sexual topics are usually avoided by the AI by what I read about it.

how do i gain the EDI capabilities? it seems straight forward but im unsure which files to download, where to put them, and if this is even safe for my computer. Do you have any advice for a newcomer