mirror of
https://github.com/SrIzan10/vdo.ninja.git
synced 2026-05-01 11:05:24 +00:00
542 lines
15 KiB
HTML
542 lines
15 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>VDO.Ninja Examples Catalog</title>
|
|
<link rel="stylesheet" href="https://vdo.ninja/main.css" />
|
|
<style>
|
|
:root {
|
|
--bg: #0f131d;
|
|
--card-bg: #1c2333;
|
|
--card-border: rgba(255, 255, 255, 0.08);
|
|
--text-muted: #c2cad8;
|
|
--accent: #8ecae6;
|
|
}
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
min-height: 100vh;
|
|
background: var(--bg);
|
|
color: #f5f6f8;
|
|
font-family: Inter, "Segoe UI", system-ui, -apple-system, sans-serif;
|
|
position: relative !important;
|
|
}
|
|
|
|
a {
|
|
color: #edf6ff;
|
|
text-decoration: none;
|
|
}
|
|
|
|
a:hover,
|
|
a:focus-visible {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
#header {
|
|
padding: 16px 24px;
|
|
background: rgba(0, 0, 0, 0.25);
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
|
}
|
|
|
|
#header a {
|
|
color: #f5f6f8;
|
|
font-size: 1.6rem;
|
|
font-weight: 600;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.container {
|
|
max-width: 1120px;
|
|
margin: 0 auto;
|
|
padding: 40px 24px 64px;
|
|
}
|
|
|
|
.page-header {
|
|
margin-bottom: 32px;
|
|
}
|
|
|
|
.page-header h1 {
|
|
margin: 0 0 0.6em;
|
|
font-size: clamp(2rem, 2.8vw, 2.6rem);
|
|
letter-spacing: -0.01em;
|
|
}
|
|
|
|
.page-header p {
|
|
margin: 0 0 0.8em;
|
|
color: var(--text-muted);
|
|
max-width: 70ch;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
#example-groups {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 48px;
|
|
}
|
|
|
|
.group h2 {
|
|
margin: 0;
|
|
font-size: clamp(1.4rem, 2.2vw, 1.8rem);
|
|
}
|
|
|
|
.group-description {
|
|
margin: 8px 0 24px;
|
|
color: var(--text-muted);
|
|
max-width: 70ch;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.card-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
|
|
gap: 18px;
|
|
}
|
|
|
|
.example-card {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
min-height: 190px;
|
|
padding: 18px;
|
|
background: var(--card-bg);
|
|
border: 1px solid var(--card-border);
|
|
border-radius: 14px;
|
|
box-shadow: 0 18px 40px -32px rgba(9, 11, 19, 0.9);
|
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
}
|
|
|
|
.example-card:hover {
|
|
transform: translateY(-4px);
|
|
box-shadow: 0 22px 42px -28px rgba(11, 15, 25, 0.85);
|
|
}
|
|
|
|
.example-card h3 {
|
|
margin: 0;
|
|
font-size: 1.15rem;
|
|
letter-spacing: -0.01em;
|
|
}
|
|
|
|
.example-card p {
|
|
margin: 0;
|
|
color: var(--text-muted);
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.tag-list {
|
|
margin: auto 0 0;
|
|
padding: 0;
|
|
list-style: none;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 6px;
|
|
}
|
|
|
|
.tag-list li {
|
|
padding: 4px 10px;
|
|
font-size: 0.72rem;
|
|
font-weight: 600;
|
|
letter-spacing: 0.05em;
|
|
text-transform: uppercase;
|
|
border-radius: 999px;
|
|
background: rgba(142, 202, 230, 0.14);
|
|
color: var(--accent);
|
|
}
|
|
|
|
@media (max-width: 720px) {
|
|
.container {
|
|
padding: 28px 18px 48px;
|
|
}
|
|
|
|
.card-grid {
|
|
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="header">
|
|
<a id="logoname" href="../">
|
|
<span data-translate="logo-header">
|
|
<font id="qos">V</font>DO.Ninja
|
|
</span>
|
|
</a>
|
|
</div>
|
|
<main class="container">
|
|
<section class="page-header">
|
|
<h1>Examples & Experiments</h1>
|
|
<p>These demos explore different ways to embed, automate, and customize VDO.Ninja. Every page is optional,
|
|
URL-driven, and kept separate from the core experience, so feel free to remix them for your own
|
|
workflows.</p>
|
|
<p>Most pages expect you to launch them with live push/view links or room IDs. Look at the comments or
|
|
top-of-page instructions for required parameters, or tweak the URL to try different behaviours.</p>
|
|
</section>
|
|
<div id="example-groups"></div>
|
|
</main>
|
|
<script>
|
|
const exampleGroups = [
|
|
{
|
|
name: "Remote Control & Automation",
|
|
description: "Control rooms, scenes, or devices remotely using the IFRAME API, data channels, and postMessage hooks.",
|
|
items: [
|
|
{
|
|
href: "addtoscene.html",
|
|
title: "Add to Scene Controller",
|
|
summary: "Use the IFRAME API to add or remove pre-defined stream IDs from a scene and manage their mic state."
|
|
},
|
|
{
|
|
href: "bigmutebutton.html",
|
|
title: "Big Mute Button Remote",
|
|
summary: "Mobile-friendly remote that lets talent toggle their microphone with oversized controls."
|
|
},
|
|
{
|
|
href: "control.html",
|
|
title: "Legacy Layout Console",
|
|
summary: "Send quick layout macros to the director scene to demo the classic control surface."
|
|
},
|
|
{
|
|
href: "custom_video_switcher.html",
|
|
title: "Custom Video Switcher",
|
|
summary: "Swap between preset stream IDs in a manual scene using targeted postMessage commands."
|
|
},
|
|
{
|
|
href: "esports.html",
|
|
title: "Esports POV Toggler",
|
|
summary: "Showcase multiple POV feeds with buttons to reveal each player or clear the scene."
|
|
},
|
|
{
|
|
href: "muteguestiframe.html",
|
|
title: "Mute Guest via IFRAME",
|
|
summary: "Remotely toggle speaker and mic states for a specific stream ID inside an embedded scene."
|
|
},
|
|
{
|
|
href: "obsremote.html",
|
|
title: "OBS Remote Mini",
|
|
summary: "Lightweight interface that tunnels OBS websocket control through VDO.Ninja."
|
|
},
|
|
{
|
|
href: "obs_remote/index.html",
|
|
title: "OBS Remote Dashboard",
|
|
summary: "Full-featured OBS controller with previews and macros, proxied through VDO.Ninja."
|
|
},
|
|
{
|
|
href: "powerpoint.html",
|
|
title: "PowerPoint Remote",
|
|
summary: "Flip through slides remotely while embedding a live view of the deck."
|
|
},
|
|
{
|
|
href: "ptz.html",
|
|
title: "PTZ Remote",
|
|
summary: "Pan, tilt, and zoom a remote camera by sending PTZ commands over the data channel."
|
|
},
|
|
{
|
|
href: "remoteapi.html",
|
|
title: "Remote API Playground",
|
|
summary: "Retro-themed sandbox for experimenting with remote control actions and macros."
|
|
},
|
|
{
|
|
href: "slidingzoom.html",
|
|
title: "Sliding Zoom Controller",
|
|
summary: "Touch-friendly slider that adjusts zoom levels via VDO.Ninja PTZ hooks."
|
|
},
|
|
{
|
|
href: "switchmics.html",
|
|
title: "Switch Mics",
|
|
summary: "Toggle mute on two remote guests with single-click controls for quick audio checks."
|
|
},
|
|
{
|
|
href: "teleprompt.html",
|
|
title: "Teleprompt Controller",
|
|
summary: "Producer-facing interface to push script text and settings to the teleprompter view."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
name: "Production Overlays & Layouts",
|
|
description: "Browser sources and layouts you can drop into OBS, a switcher, or a director tab.",
|
|
items: [
|
|
{
|
|
href: "chat.html",
|
|
title: "Chat Shout Overlay",
|
|
summary: "Monospaced stacked chat overlay tuned for big on-screen shoutouts."
|
|
},
|
|
{
|
|
href: "chatoverlay.html",
|
|
title: "Clean Chat Overlay",
|
|
summary: "Modern chat overlay for OBS with avatars, styling toggles, and sanitised content."
|
|
},
|
|
{
|
|
href: "custom_labels.html",
|
|
title: "Custom Labels Overlay",
|
|
summary: "Display lower-third labels that update automatically as guests join with custom names."
|
|
},
|
|
{
|
|
href: "custom_overlay.html",
|
|
title: "Dynamic Overlay Frame",
|
|
summary: "Trigger branded overlays and nameplates from connection metadata."
|
|
},
|
|
{
|
|
href: "draggable.html",
|
|
title: "Draggable Multi-View",
|
|
summary: "Arrange several viewer windows manually by dragging and resizing thumbnails."
|
|
},
|
|
{
|
|
href: "dual.html",
|
|
title: "Dual View Layout",
|
|
summary: "Display two guests side-by-side using the dual director layout logic."
|
|
},
|
|
{
|
|
href: "gamecontroller.html",
|
|
title: "Controller Visualizer",
|
|
summary: "Render HID and gamepad events as an overlay-friendly controller graphic."
|
|
},
|
|
{
|
|
href: "grid.html",
|
|
title: "Grid Builder",
|
|
summary: "Drop arbitrary URLs into a responsive iframe grid for multi-angle monitoring."
|
|
},
|
|
{
|
|
href: "labelonly.html",
|
|
title: "Label Only Overlay",
|
|
summary: "Show only the connected guest's label as a minimal lower-third element."
|
|
},
|
|
{
|
|
href: "mixer.html",
|
|
title: "Mixer Sandbox",
|
|
summary: "Try the manual scene mixer by dragging streams into layout slots."
|
|
},
|
|
{
|
|
href: "multi.html",
|
|
title: "Multi-Room Monitor",
|
|
summary: "Open multiple director rooms in one tab using the ?rooms= list parameter."
|
|
},
|
|
{
|
|
href: "overlay.html",
|
|
title: "Overlay Helper",
|
|
summary: "Combine a VDO.Ninja feed with an external overlay page inside one source."
|
|
},
|
|
{
|
|
href: "rotated.html",
|
|
title: "Rotated Scene Output",
|
|
summary: "Rotate the scene output for portrait monitors or tall confidence displays."
|
|
},
|
|
{
|
|
href: "sensoroverlay.html",
|
|
title: "Sensor Data Overlay",
|
|
summary: "Render live speed and telemetry data over an incoming video feed."
|
|
},
|
|
{
|
|
href: "status.html",
|
|
title: "Status Ticker",
|
|
summary: "Ticker-style overlay for status updates pulled from chat events."
|
|
},
|
|
{
|
|
href: "teleprompter.html",
|
|
title: "Teleprompter Display",
|
|
summary: "Talent-facing teleprompter view that mirrors incoming script text."
|
|
},
|
|
{
|
|
href: "waitingroom.html",
|
|
title: "Waiting Room Overlay",
|
|
summary: "Show a standby message until the remote feed connects and starts playing."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
name: "Social & Platform Integrations",
|
|
description: "Pair VDO.Ninja streams with third-party chat or engagement widgets.",
|
|
items: [
|
|
{
|
|
href: "kick.html",
|
|
title: "Kick + Video",
|
|
summary: "Combine a Kick chat embed with a VDO.Ninja source in one window."
|
|
},
|
|
{
|
|
href: "socal.html",
|
|
title: "SocialStream Hub",
|
|
summary: "Switch between multiple social chat integrations alongside a VDO.Ninja feed."
|
|
},
|
|
{
|
|
href: "twitch.html",
|
|
title: "Twitch + Video",
|
|
summary: "Embed Twitch chat next to a VDO.Ninja feed for streamers."
|
|
},
|
|
{
|
|
href: "youtube.html",
|
|
title: "YouTube Chat + Video",
|
|
summary: "Co-host YouTube live chat with a VDO.Ninja guest feed."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
name: "Data, Sensors & Messaging",
|
|
description: "Examples that push telemetry, sensor readings, or custom data through VDO.Ninja.",
|
|
items: [
|
|
{
|
|
href: "datachannel-pubsub.html",
|
|
title: "DataChannel Pub/Sub",
|
|
summary: "Publish structured messages and subscribe to updates over VDO.Ninja data channels."
|
|
},
|
|
{
|
|
href: "p2p.html",
|
|
title: "P2P Data Tunnel",
|
|
summary: "Use paired iframes to pass arbitrary data peer-to-peer via VDO.Ninja."
|
|
},
|
|
{
|
|
href: "sensors.html",
|
|
title: "Sensors Dashboard",
|
|
summary: "Capture mobile sensor readings and video, rendering telemetry on canvas."
|
|
},
|
|
{
|
|
href: "rip.html",
|
|
title: "RIP Canvas Relay",
|
|
summary: "Capture a remote view to a hidden canvas for further processing or mixing."
|
|
},
|
|
{
|
|
href: "wireless.html",
|
|
title: "Wireless Relay Lab",
|
|
summary: "Manual message relay between two peers with testing and compression controls."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
name: "Developer & SDK Samples",
|
|
description: "Deeper dives into the SDK, automation helpers, and hardware integrations.",
|
|
items: [
|
|
{
|
|
href: "dynamic-viewer.html",
|
|
title: "Dynamic Viewer SDK",
|
|
summary: "UI-driven sample that adds and removes views dynamically with the SDK helpers."
|
|
},
|
|
{
|
|
href: "googleai.html",
|
|
title: "Gemini Vision Chat",
|
|
summary: "Integrate Google Gemini live video analysis with a VDO.Ninja feed."
|
|
},
|
|
{
|
|
href: "iframe.inbound-stats.html",
|
|
title: "IFRAME Inbound Stats",
|
|
summary: "Request inbound stats over the IFRAME API and log them for inspection."
|
|
},
|
|
{
|
|
href: "iframe.outbound-stats.html",
|
|
title: "IFRAME Outbound Stats",
|
|
summary: "Collect outbound stats from an embedded iframe for monitoring."
|
|
},
|
|
{
|
|
href: "midi.html",
|
|
title: "MIDI Controller",
|
|
summary: "Map MIDI inputs to VDO.Ninja events and test hotkey commands."
|
|
},
|
|
{
|
|
href: "sandbox.html",
|
|
title: "Developer API Sandbox",
|
|
summary: "All-in-one playground for experimenting with the VDO.Ninja developer API."
|
|
},
|
|
{
|
|
href: "simple-iframe-replacement.html",
|
|
title: "DataChannel Replacement",
|
|
summary: "Shows how to replace hidden iframes with the DataChannel SDK."
|
|
},
|
|
{
|
|
href: "turn-only-example.html",
|
|
title: "TURN Only Example",
|
|
summary: "Demonstrates forcing TURN-only routing and inspecting connection details."
|
|
},
|
|
{
|
|
href: "webhid.html",
|
|
title: "WebHID Demo",
|
|
summary: "Connect WebHID devices such as a StreamDeck and forward events through VDO.Ninja."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
name: "Utilities & Helpers",
|
|
description: "Small helpers for link generation, diagnostics, or local capture workflows.",
|
|
items: [
|
|
{
|
|
href: "changepass.html",
|
|
title: "Password Hasher",
|
|
summary: "Prompt-driven tool that creates salted room hashes for invite links."
|
|
},
|
|
{
|
|
href: "noisegate.html",
|
|
title: "Noise Gate Converter",
|
|
summary: "Convert classic OBS noise gate settings into the modern \"My Gate\" format."
|
|
},
|
|
{
|
|
href: "simplelink.html",
|
|
title: "Simple Link Generator",
|
|
summary: "Generate publish, view, and scene links with common parameters."
|
|
},
|
|
{
|
|
href: "zoom.html",
|
|
title: "Zoom Capture Helper",
|
|
summary: "Local capture preview that goes fullscreen for easy window capture."
|
|
}
|
|
]
|
|
}
|
|
];
|
|
|
|
const groupsRoot = document.getElementById("example-groups");
|
|
|
|
for (const group of exampleGroups) {
|
|
const section = document.createElement("section");
|
|
section.className = "group";
|
|
|
|
const heading = document.createElement("h2");
|
|
heading.textContent = group.name;
|
|
section.appendChild(heading);
|
|
|
|
if (group.description) {
|
|
const desc = document.createElement("p");
|
|
desc.className = "group-description";
|
|
desc.textContent = group.description;
|
|
section.appendChild(desc);
|
|
}
|
|
|
|
const grid = document.createElement("div");
|
|
grid.className = "card-grid";
|
|
|
|
for (const item of group.items) {
|
|
const card = document.createElement("article");
|
|
card.className = "example-card";
|
|
|
|
const title = document.createElement("h3");
|
|
const link = document.createElement("a");
|
|
link.href = item.href;
|
|
link.textContent = item.title;
|
|
title.appendChild(link);
|
|
card.appendChild(title);
|
|
|
|
const summary = document.createElement("p");
|
|
summary.textContent = item.summary;
|
|
card.appendChild(summary);
|
|
|
|
if (Array.isArray(item.tags) && item.tags.length) {
|
|
const tagList = document.createElement("ul");
|
|
tagList.className = "tag-list";
|
|
for (const tag of item.tags) {
|
|
const tagItem = document.createElement("li");
|
|
tagItem.textContent = tag;
|
|
tagList.appendChild(tagItem);
|
|
}
|
|
card.appendChild(tagList);
|
|
}
|
|
|
|
grid.appendChild(card);
|
|
}
|
|
|
|
section.appendChild(grid);
|
|
groupsRoot.appendChild(section);
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|