Ninja Docs
  • What is VDO.Ninja?
    • How does it work
    • Use cases
    • Why use VDO.Ninja over other solutions?
    • Sponsor ❤
  • Getting started
    • VDO.Ninja basics
    • What are stream IDs?
    • The power of the URL parameter
    • Multi-Person Chat
    • Rooms
    • Even higher quality video
    • Mobile phone camera into webcam
    • Cheat sheet of basic parameters
  • Steve's helper apps & tools
    • Electron Capture
      • Documentation
    • Social Stream Ninja
      • Documentation reference
    • Meshcast.io
    • Caption.Ninja
    • Raspberry.Ninja
      • Documentation
    • Mixer App
    • WHIP and WHEP tooling
    • Versus.cam
    • Speed and Quality Tests
    • Comms
    • Teleprompter Tool
    • LUT maker for color grading
    • Native mobile app versions
    • VDO Applications
    • Tech Demonstrations
    • Invite Link Generators
    • Community contributed tools
    • Mic test
    • Whiteboard
  • Guides
    • Cheat Sheets
    • Common questions re: Rooms
    • Video bitrate for push/view links
    • Video bitrate in rooms
    • How to get permanent links
    • Basic hotkeys
    • MIDI, API and WebHID support
    • Hardware-accelerated video encoding
    • Audio Filters & Bitrate
    • Options to record streams
    • External guides and how-tos
    • How to lock the resolution
    • How to use VDO.Ninja as a webcam for Google Hangouts, Zoom, and more
    • How to capture without browser sources
    • How to control bitrate/quality
    • How to selectively allow access
    • Stream Scheduling and Promotion
    • How to send the audio/video output of one OBS to another OBS using VDO.Ninja
    • How to mirror a video while Full-Screen - For iPads and Teleprompters
    • How to capture an application's audio
    • How to control VDO.Ninja with Touch Portal
    • How to publish from OBS into VDO.Ninja
    • How to screen share your iPhone/iPad
    • How to get iPhones to output 1080p Videos
    • How to stream into Zoom without OBS
    • How to connect a smartphone to computer via USB
    • How to edit an invite after sending it
    • How to get highest video quality (for an interview)
    • How to stream 4K video using VDO.Ninja
    • How to get lowest audio latency possible
    • How to share webcam from inside OBS
    • How to publish to Facebook Live
    • How to embed VDO.Ninja into a site with iFrames
      • Detecting User Joins / Disconnects
      • Create custom drawing app
      • Generic P2P Data Transmission Guide
      • IFRAME API for Directors
      • IFRAME API Basics
    • How to use the green screen just locally
    • How to connect a GoPro to VDO.Ninja
    • How to install RaspNinja on Jetson
    • How to transfer guests to other rooms
    • How to set up a simple chat room
    • How to screen share in 1080p
    • How to control PowerPoint remotely with VDO.Ninja
    • How to improve quality of the native app
    • How to stream transparent video
    • Recommended OBS WHIP settings
    • How to use VDO.Ninja on a website
    • Keep Mic Active in Background on Android Browser
    • PlayStation or Xbox to VDO.Ninja
    • Enabling WebRTC Sources in OBS
    • Picking the right microphone
    • Set Up Proper Lighting
    • System requirements for streaming
    • From OBS to VDO.Ninja using WHIP
    • Deploy your own Meshcast-like service
    • Windows TTS Audio Capture Methods for OBS
    • Syncing USB audio with VDO.Ninja -> OBS Virtual Camera
  • Advanced Options (URL Parameters)
    • Most common Parameters
      • &push
      • &quality
      • &videodevice
      • &audiodevice
      • &effects
      • &label
      • &meshcast
      • &view
      • &videobitrate
      • &audiobitrate
      • &codec
      • &novideo
      • &noaudio
      • &showlabels
      • &room
      • &director
      • &proaudio
      • &scene
      • &roombitrate
      • &password
      • &broadcast
    • Setup Parameters
      • &push
      • &room
      • &password
      • &hash
      • &e2ee
      • &label
      • &labelsuggestion
      • &permaid
      • &group
      • &groupview
      • &groupaudio
      • &datamode
      • &audiooutput
      • &sink
      • &audiodevice
      • &videodevice
      • &vdo
      • &device
      • &miconly
      • &miconlyoption
      • &safemode
      • &autostart
      • &easyexit
      • &webcam
      • &webcam2
      • &screenshare
      • &screenshare2
      • &website
      • &fileshare
      • &intro
      • &host
      • &tips
      • &welcome
      • &welcomeb64
      • &welcomeimage
      • &hangupmessage
      • &humb64
      • &groupmode
      • &audience
    • Camera Parameters
      • &whitebalance
      • &exposure
      • &saturation
      • &sharpness
      • &contrast
      • &brightness
    • Video Parameters
      • &blind
      • &quality
      • &width
      • &height
      • &aspectratio
      • &contenthint
      • &mediasettings
      • &noscale
      • &fps
      • &maxframerate
      • &effects
      • &effectvalue
      • &imagelist
      • &avatar
      • &fullscreen
      • &showpreview
      • &minipreview
      • &minipreviewoffset
      • &largepreview
      • &nopreview
      • &hideguest
      • &videomute
      • &ptz
      • &webp
      • &webpquality
      • &scale
      • &viewwidth
      • &viewheight
      • &dpi
      • &sharper
      • &codec
      • &h264profile
      • &buffer
      • &buffer2
      • &fadein
      • &broadcast
      • &directoronly
      • &showonly
      • &novideo
      • &nodirectorvideo
      • &slideshow
      • &zoom
    • Video Bitrate Parameters
      • &outboundvideobitrate
      • &maxvideobitrate
      • &limittotalbitrate
      • &controlroombitrate
      • &roombitrate
      • &maxbandwidth
      • &videobitrate
      • &totalscenebitrate
      • &totalroombitrate
      • &totalbitrate
      • &zoomedbitrate
      • &optimize
    • Audio Parameters
      • &proaudio
      • &stereo
      • &mutespeaker
      • &deafen
      • &noaudioprocessing
      • &audiodevice
      • &echocancellation
      • &audiogain
      • &autogain
      • &compressor
      • &denoise
      • &distort
      • &equalizer
      • &limiter
      • &lowcut
      • &noisegate
      • &noisegatesettings
      • &audiocontenthint
      • &audiolatency
      • &micdelay
      • &mute
      • &automute
      • &outboundaudiobitrate
      • &inputchannels
      • &monomic
      • &audiooutput
      • &sink
      • &volume
      • &volumecontrol
      • &audiobitrate
      • &vbr
      • &mono
      • &noaudio
      • &nodirectoraudio
      • &panning
      • &sync
      • &samplerate
      • &channels
      • &channeloffset
      • &playchannel
      • &ptime
      • &maxptime
      • &minptime
      • &audiocodec
      • &dtx
      • &nofec
    • Mixer/Scene Parameters
      • &solo
      • &view
      • &include
      • &exclude
      • &layout
      • &activespeaker
      • &activespeakerdelay
      • &order
      • &slots
      • &fakeguests
      • &randomize
      • &cover
      • &43
      • &portrait
      • &square
      • &forceviewerlandscape
      • &animated
      • &manual
      • &locked
      • &poster
      • &hideplaybutton
      • &motiondetection
      • &scene
      • &scenetype
      • &autoadd
      • &hiddenscenebitrate
      • &preloadbitrate
      • &waitimage
      • &waitmessage
      • &waittimeout
      • &viewslot
    • Settings Parameters
      • &language
      • &remote
      • &controlobs
      • &allowedscenes
      • &stats
      • &sticky
      • &clearstorage
      • &disablehotkeys
      • &showlist
      • &nopush
      • &hidehome
      • &hidetranslate
      • &clock
      • &clock24
      • &timer
      • &powerpoint
      • &widget
      • &token
      • &transcribe
      • &signalmeter
      • &batterymeter
      • &consent
      • &prompt
      • &hands
      • &notify
      • &r2d2
      • &directorchat
      • &maxconnections
      • &maxviewers
      • &chunked
      • &retransmit
      • &rampuptime
      • &sensor
      • &sensorfilter
      • &postimage
      • &postinterval
      • &slot
      • &closedcaptions
      • &nocaptionlabels
      • &enhance
      • &bitratecutoff
      • &cutscene
      • &statsinterval
      • &keyframerate
      • &maxpublishers
      • &showconnections
      • &obsfix
      • &streamlabs
      • &getfaces
      • &nochunked
    • Buttons and Control Bar Parameters
      • &autohide
      • &controlbarspace
      • &nosettings
      • &nomicbutton
      • &nospeakerbutton
      • &novideobutton
      • &nofileshare
      • &screensharebutton
      • &nohangupbutton
      • &chatbutton
      • &bigbutton
      • &fullscreenbutton
      • &nowebsite
      • &hands
      • &videocontrols
      • &nocontrols
      • &forcecontrols
    • Design Parameters
      • &label
      • &showlabels
      • &fontsize
      • &style
      • &bgimage
      • &showall
      • &meterstyle
      • &cleanoutput
      • &cleanish
      • &css
      • &base64css
      • &js
      • &base64js
      • &mirror
      • &nomirror
      • &flip
      • &rotatewindow
      • &structure
      • &color
      • &blur
      • &border
      • &bordercolor
      • &rounded
      • &margin
      • &darkmode
      • &lightmode
      • &background
      • &chroma
      • &transparent
      • &nocursor
      • &favicon
      • &headertitle
      • &rotate
      • &grid
      • &hideheader
      • &hidemenu
      • &tally
      • &tallyoff
      • &cleanviewer
      • &obsoff
      • &pip
      • &pipall
      • &pipme
      • &rows
    • Director Parameters
      • &director
      • &codirector
      • &blindall
      • &cleandirector
      • &hidesolo
      • &hidecodirectors
      • &minidirector
      • &orderby
      • &queue
      • &rooms
      • &broadcasttransfer
      • &showdirector
      • &slotmode
      • &previewmode
      • &novice
      • &layouts
      • &maindirectorpassword
      • &totalroombitrate
      • &limittotalbitrate
      • &notify
      • &mutespeaker=0
      • &showconnections
      • &widget
      • &pausepreview
    • Screen-share Parameters
      • &screensharestereo
      • &screenshare
      • &screenshare2
      • &screenshareaec
      • &screenshareautogain
      • &screensharecursor
      • &screensharedenoise
      • &screensharefps
      • &screensharehide
      • &screenshareid
      • &screensharelabel
      • &screensharequality
      • &screensharecontenthint
      • &screenshareaspectratio
      • &screensharetype
      • &smallshare
      • &screensharevideoonly
      • &suppresslocalaudio
      • &prefercurrenttab
      • &selfbrowsersurface
      • &systemaudio
      • &displaysurface
      • &screensharebutton
      • &screensharebitrate
      • &sharperscreen
      • &sspaused
    • Recording Parameters
      • &record
      • &autorecord
      • &autorecordlocal
      • &autorecordremote
      • &recordcodec
      • &pcm
      • &recordmotion
      • &chunked
    • Guest queuing Parameters
      • &queue
      • &screen
      • &hold
      • &holdwithvideo
      • &queuetransfer
    • Meshcast Parameters
      • &meshcast
      • &meshcastaudiobitrate
      • &meshcastbitrate
      • &meshcastcodec
      • &mcscreensharebitrate
      • &mcscreensharecodec
      • &meshcastscale
      • &meshcastcode
      • &nomeshcast
    • WHIP Parameters
      • &whipout
      • &whipview
      • &whipoutcodec
      • &whipoutaudiobitrate
      • &whipoutvideobitrate
      • &whipoutscale
      • &whipoutscreensharecodec
      • &whipoutscreensharebitrate
      • &cftoken
      • &svc
    • Mobile Parameters
      • &facing
      • &forcelandscape
      • &forceportrait
      • &forceios
      • &notios
      • &flagship
      • &mobile
      • &notmobile
      • &app
    • API & MIDI Parameters
      • &api
        • API reference
        • API reference - AI Generated
        • Client (node) event example
      • &pie
      • &midi
      • &midiin
      • &midiout
      • &midiremote
      • &midichannel
      • &mididevice
      • &midioffset
      • &mididelay
      • &datamode
      • &postapi
    • TURN & STUN Parameters
      • &turn
      • &stun
      • &addstun
      • &icefilter
      • &proxy
      • &relay
      • &secure
      • &tcp
      • &tz
    • Parameters added in Version 24
    • Complete List of Parameters in v26
    • Upcoming Parameters
    • Other Parameters
  • Releases
    • v24
    • v23 🌱
    • v22 👑
    • v21 ❤️
    • v20 🎁
    • v19 🚀🤯
      • v19.1 - 19.4
    • v18
      • v18.3
    • v17
    • v16
      • v16.3
      • v16.4
    • v15
    • v14
    • v13
      • v13.4
    • v12
    • v10
    • v8
  • Updates
    • Updates - VDO.Ninja
    • Updates - Social Stream & Chat Overlay
      • Updates - Social Stream Standalone App
    • Updates - Electron Capture App
    • Updates - Raspberry.Ninja
    • Updates - Versus.cam
    • Updates - Mixer App
    • Updates - WHIP/WHEP
    • Updates - Native mobile apps
    • Updates - Caption.Ninja
    • Updates - Meshcast.io
    • Updates - Speed Test
    • Updates - Comms
    • Updates - Miscellaneous
  • Development Progress
  • Help!
    • Fail safes and Backups
    • Privacy and security details
      • VDO.Ninja Terms of Service
      • VDO.Ninja Privacy Policy
    • Project Contact Info
    • Where can I report a bug?
    • Where can I get support?
    • Feature Requests
    • Logos and media assets
    • What does VDO stand for?
  • Common errors and known issues
    • Can't screen capture certain games
    • ATEM not working with Firestick
    • Very old iPhone support
    • Can't select audio output on iOS
    • Screen-share is just a black video
    • Mic audio dropping out
    • Loss of audio when OBS minimized
    • Known issues
    • Echo or feedback issues
    • Works on WiFi but not on 4G
    • Can't capture an application's audio when screen-sharing
    • Can't load camera both in OBS and VDON
    • Can't select a camera lens on mobile
    • No video in OBS, just an "Add camera" button
    • Audio over VDO.Ninja isn't working
    • Loading circle shows in OBS or browser
    • Appearing then disappearing guest
    • Can't auto-start screen sharing
    • Audio Clicking / Popping / Distortion
    • Can't share my screen
    • Nothing shows up in OBS
    • Already in use or claimed errors
    • Blue spinning window
    • Cursor shows trailing or artifacting
    • Packet Loss
    • Overheating
    • Audio is delayed in OBS
    • vMix High CPU
    • OBS Virtual Camera has low FPS
    • Virtual camera not working on Mac
    • Mic stops on MacOS when OBS opens
    • Video stream looks corrupted
    • Video freezes mid-stream
    • Webcam freezes after a time
    • Is the VDO.Ninja server down?
    • Hosted your own TURN server?
    • Can't screen-share from certain devices
    • Cursor shows when screen-sharing
    • Getting “Overconstrained" Camera Error
    • Autoplay doesn't work in Chrome or vMix v77
    • Low frame rates
    • Black borders around the video in OBS
    • Mic's volume keeps changing
    • Enable Camera / Microphone permissions
    • FPS drop if app not in focus
    • Surround sound error when screen sharing with USB headset
    • Relay candidate being selected
    • Camera works in Safari; not Chrome
    • Robotic Audio Distortion
    • Can't load camera from non-SSL host
    • Camera on macOS doesn't show?
    • Can't screen share Adobe Lightroom
    • Decklink support?
    • iOS audio stops during phone calls
    • Can't turn off echo-cancellation on macOS
    • Video lag grows over time
    • Can't connect unless via VPN
    • Improving vMix performance
    • Use a Virtual Camera more than Once
  • Platform specific issues
    • Android
    • macOS
    • iOS (iPhone/iPad)
    • Firefox
    • Opera GX
  • Useful Links
  • FAQ
  • Sponsor ❤
  • Edit this documentation
Powered by GitBook
On this page
  • Simple VDO.Ninja API WebSocket Client Example
  • How to Use This Example
  • Key Features
  • Usage on links

Was this helpful?

  1. Advanced Options (URL Parameters)
  2. API & MIDI Parameters
  3. &api

Client (node) event example

Simple VDO.Ninja API WebSocket Client Example

While I'm a fan of just connecting and seeing what the API outputs, based on different events/actions, here's some code to get you started with basic incoming connection detection.

Simple VDO.Ninja API WebSocket Client Example

Here's a NodeJS example that demonstrates how to:

  1. Connect to the VDO.Ninja API via WebSocket

  2. Detect when streams connect or disconnect

  3. Periodically poll for stream details

const WebSocket = require('ws');

class VDONinjaMonitor {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.apiServer = 'wss://api.vdo.ninja:443';
    this.ws = null;
    this.connected = false;
    this.streams = {};
    this.reconnectTimeout = null;
    this.pollInterval = null;
  }

  // Connect to the WebSocket server
  connect() {
    console.log(`Connecting to ${this.apiServer}...`);
    
    this.ws = new WebSocket(this.apiServer);
    
    this.ws.on('open', () => {
      console.log('WebSocket connection established');
      // Join with the API key
      this.ws.send(JSON.stringify({ join: this.apiKey }));
      this.connected = true;
      
      // Start polling for details periodically
      this.startPolling();
    });
    
    this.ws.on('message', (data) => {
      try {
        const message = JSON.parse(data);
        this.handleMessage(message);
      } catch (error) {
        console.error('Error parsing message:', error);
      }
    });
    
    this.ws.on('close', () => {
      console.log('WebSocket connection closed');
      this.connected = false;
      this.stopPolling();
      this.scheduleReconnect();
    });
    
    this.ws.on('error', (error) => {
      console.error('WebSocket error:', error);
      this.stopPolling();
      this.scheduleReconnect();
    });
  }
  
  // Handle messages from the WebSocket
  handleMessage(message) {
    // Log all messages for debugging
    console.log('Received message:', JSON.stringify(message, null, 2));
    
    // Handle connection events
    if (message.action === 'guest-connected') {
      const streamID = message.streamID;
      console.log(`Stream connected: ${streamID}`);
      
      // Store stream info
      this.streams[streamID] = {
        connected: true,
        label: message.value?.label || 'Unknown',
        connectTime: new Date()
      };
      
      // You could trigger additional actions here
    }
    // Handle alternative connection event
    else if (message.action === 'push-connection' && (message.value === true || message.value === "true")) {
      const streamID = message.streamID;
      console.log(`Stream connected (via push-connection): ${streamID}`);
      
      // Store stream info or update existing
      if (!this.streams[streamID]) {
        this.streams[streamID] = {
          connected: true,
          connectTime: new Date()
        };
      } else {
        this.streams[streamID].connected = true;
        this.streams[streamID].reconnectTime = new Date();
      }
    }
    // Handle disconnection events
    else if (message.action === 'push-connection' && (message.value === false || message.value === "false")) {
      const streamID = message.streamID;
      console.log(`Stream disconnected: ${streamID}`);
      
      if (this.streams[streamID]) {
        this.streams[streamID].connected = false;
        this.streams[streamID].disconnectTime = new Date();
        
        // Optional: Remove from active streams after a period
        setTimeout(() => {
          if (this.streams[streamID] && !this.streams[streamID].connected) {
            delete this.streams[streamID];
          }
        }, 60000);
      }
    }
    
    // Handle responses to our getDetails requests
    else if (message.callback && message.callback.action === 'getDetails') {
      console.log('Received stream details:');
      
      // The result contains detailed information about all connected streams
      const details = message.callback.result;
      
      if (details && details.guests) {
        // Update our local cache with the latest details
        Object.keys(details.guests).forEach(streamID => {
          if (!this.streams[streamID]) {
            this.streams[streamID] = {
              connected: true,
              connectTime: new Date()
            };
            console.log(`Discovered stream in poll: ${streamID}`);
          }
          
          // Update stream details
          this.streams[streamID] = {
            ...this.streams[streamID],
            ...details.guests[streamID],
            lastSeen: new Date()
          };
        });
        
        // Check for streams that are in our cache but not in the response
        Object.keys(this.streams).forEach(streamID => {
          if (this.streams[streamID].connected && !details.guests[streamID]) {
            console.log(`Stream not found in poll, marking as disconnected: ${streamID}`);
            this.streams[streamID].connected = false;
            this.streams[streamID].disconnectTime = new Date();
          }
        });
      }
    }
    
    // Handle action-specific events
    else if (message.action) {
      switch (message.action) {
        case 'remote-mute-state':
          // Handle remote mute state changes
          if (message.streamID && this.streams[message.streamID]) {
            this.streams[message.streamID].remoteMuted = message.value;
            console.log(`Stream ${message.streamID} remote mute state: ${message.value}`);
          }
          break;
          
        case 'remote-video-mute-state':
          // Handle remote video mute state changes
          if (message.streamID && this.streams[message.streamID]) {
            this.streams[message.streamID].videoMuted = message.value;
            console.log(`Stream ${message.streamID} video mute state: ${message.value}`);
          }
          break;
        
        case 'director':
        case 'codirector':
          // Handle director status changes
          if (message.streamID && this.streams[message.streamID]) {
            this.streams[message.streamID].isDirector = message.value;
            console.log(`Stream ${message.streamID} director state: ${message.value}`);
          }
          break;
      }
    }
  }
  
  // Send a command to the WebSocket
  sendCommand(action, value = null, target = null) {
    if (!this.connected) {
      console.warn('Cannot send command: WebSocket not connected');
      return false;
    }
    
    const command = { action };
    if (value !== null) command.value = value;
    if (target !== null) command.target = target;
    
    try {
      this.ws.send(JSON.stringify(command));
      return true;
    } catch (error) {
      console.error('Error sending command:', error);
      return false;
    }
  }
  
  // Request updated details about all streams
  requestDetails() {
    return this.sendCommand('getDetails');
  }
  
  // Start polling for stream details
  startPolling(intervalMs = 10000) {
    this.stopPolling();
    this.pollInterval = setInterval(() => {
      this.requestDetails();
    }, intervalMs);
    
    // Initial request
    this.requestDetails();
  }
  
  // Stop polling
  stopPolling() {
    if (this.pollInterval) {
      clearInterval(this.pollInterval);
      this.pollInterval = null;
    }
  }
  
  // Schedule reconnection attempt
  scheduleReconnect(delayMs = 5000) {
    if (this.reconnectTimeout) {
      clearTimeout(this.reconnectTimeout);
    }
    
    this.reconnectTimeout = setTimeout(() => {
      console.log('Attempting to reconnect...');
      this.connect();
    }, delayMs);
  }
  
  // Get a summary of connected streams
  getStreamSummary() {
    const connectedStreams = Object.keys(this.streams).filter(id => this.streams[id].connected);
    
    console.log(`\n=== Stream Summary ===`);
    console.log(`Total tracked streams: ${Object.keys(this.streams).length}`);
    console.log(`Currently connected: ${connectedStreams.length}`);
    
    console.log(`\nConnected streams:`);
    connectedStreams.forEach(streamID => {
      const stream = this.streams[streamID];
      console.log(`- ${streamID} (${stream.label || 'Unlabeled'})`);
    });
    
    return {
      total: Object.keys(this.streams).length,
      connected: connectedStreams.length,
      streams: this.streams
    };
  }
  
  // Close the connection
  disconnect() {
    this.stopPolling();
    if (this.reconnectTimeout) {
      clearTimeout(this.reconnectTimeout);
      this.reconnectTimeout = null;
    }
    
    if (this.ws) {
      this.ws.close();
      this.ws = null;
    }
    
    this.connected = false;
  }
}

// Usage example
const API_KEY = 'YOUR_API_KEY_HERE'; // Replace with your actual API key
const monitor = new VDONinjaMonitor(API_KEY);

// Connect to the API
monitor.connect();

// Periodically print a summary of streams (every 30 seconds)
setInterval(() => {
  monitor.getStreamSummary();
}, 30000);

// Handle application shutdown
process.on('SIGINT', () => {
  console.log('Shutting down...');
  monitor.disconnect();
  process.exit(0);
});

How to Use This Example

  1. Save this code as vdo-ninja-monitor.js

  2. Install the WebSocket dependency:

    npm install ws
  3. Replace 'YOUR_API_KEY_HERE' with your actual VDO.Ninja API key

  4. Run the script:

    node vdo-ninja-monitor.js

Key Features

This script demonstrates:

  1. WebSocket Connection: Establishes and maintains a connection to the VDO.Ninja API

  2. Event Handling: Detects when streams connect and disconnect

  3. Auto-Reconnection: Reconnects if the connection drops

  4. Periodic Polling: Requests updated details every 10 seconds

  5. Stream Tracking: Maintains a record of all seen streams with their status

You can extend this example to:

  • Send notifications when streams connect/disconnect

  • Log connection events to a database

  • Trigger actions based on specific stream events

  • Control streams or layouts based on connection patterns

Usage on links

Any link type that connects to a stream can use the API parameter to detect the incoming media connection status:

  1. View link: https://vdo.ninja/?view=streamID&api=myapikey - Detects when the broadcaster you're viewing connects/disconnects

  2. Scene link: https://vdo.ninja/?scene&view=streamID&api=myapikey - Shows the video while monitoring connection status

  3. Director link: https://vdo.ninja/?director=roomname&api=myapikey - Monitors all connections in a specific room

Each option enables the WebSocket API that sends events when streams connect or disconnect. The monitoring code works with any of these link types, though director links provide the most comprehensive monitoring if you're using rooms. The key difference is which connection events you'll receive - view links only report on the specific stream being viewed, while director links report on all room participants. You can also detect events from publishers, or those pushing media streams, however each publisher may need the &api added to detect when they go live. When they disconnect, you may or may not get a notification from them that they are hanging up — it depends on if they do a proper hang-up or a hard-close.

PreviousAPI reference - AI GeneratedNext&pie

Last updated 23 days ago

Was this helpful?