Ninja Docs

Updates - VDO.Ninja

January 25

  • Updated the http API getDetails request to include info about video visibility; makes it a bit more usable if querying a scene link

January 23

  • Updated GitHub with the current alpha-version of VDO.Ninja (v23-alpha I guess). Also updated GitHub with a formal 'stable' release of the existing v22.9, which is what's been running on production for the last couple months.
  • There's new logic added to support secret-auth-tokens for private turn server deployments; this was mainly a contribution by Jumper on GitHub.

January 21

  • Added a little "pin" icon to the end of the copy/view link when sharing your camera. Pressing it is the same as using &sticky on your URL, as next time you visit VDO.Ninja it will ask you if you wish to reload your &push link. ** on alpha

January 20

  • Streamlabs mobile support improved, but there are still some users who are not able to see video. I can confirm though, it's working with my Google Pixel 4a now at least.
  • If you adjust the resolution on mobile, the frame rate shouldn't change now. I also have the aspect ratio tweaked a bit on android, so if in portrait mode, the aspect ratio is correctly adapted. (I can't say the same for the resolution though, which has a mind of its own still)
  • You can change the Buffer of a video on alpha via right-clicking the menu; this has been further improved to its own window with a numerical-input option as well as a slider.
  • I've added a new IRL-related command called &cutscene (aka, &lowbitratescene), which you can use to specify an OBS cut scene to switch to when the bitrate drops below a threshold and return to the original scene when the bitrate recovers. (assuming the cut scene is active; it won't switch back from a scene that isn't the cut away scene) The default bitrate threshold is 300-kbps, but you can use the existing &bitratecutoff=N option to specify a custom one. Using &cutscene with &bitratecutoff will override the behaviour of &bitratecutoff's other features. It won't start triggering until the bitrate has hit at least the threshold once. to use:
    You can of course use this with &controlobs&remote, to have the publisher change the scenes dynamically, and see what the current OBS scene is (if still connected). ** Note that the OBS Browser source needs the permissions to be set to high, to give VDO.Ninja permissions to change scenes. (on alpha for testing)
  • Added a new experimental parameter called &maindirectorpassword, which lets you set a pseudo 'master room password' as a director. It helps avoid getting locked out as the director, if someone else tries to claim the director-role first. ie: This will add a &token value to the invite/scene links. This token is used by the guests to check a remote database server to see who currently 'owns' the token; it persists though, even if the director is not connected. When using &maindirectorpassword as a director, it tells this database that you are the owner, and it will persist even if you aren't connected to VDO.Ninja. The &token tells the guest to ignore other logic about who the director is, instead using the info provided by the token-lookup to determine whose the director. I may change or revoke this feature, depending on how testing goes this week, as it's rather experimental. ** on alpha for feedback

January 19

  • &autorecord can now accept a bitrate as a value, as it wasn't doing so before (on alpha)

January 16

  • New turn server added to Washington DC area.
  • &website as a director now works again (auto shares a website to all guests)
  • If multiple mic inputs are selected, they will be auto-selected on page load (rather than just one mic only). ** changes on alpha

January 12

  • Improved publishing stats when using &meshcast; server region + external watchURL are available now there.
  • &screensharevideoonly will hide the audio selection menu when screen sharing; it will also hide that warning message about no audio selected when screen sharing.
  • Fixed some issues with &viewwidth and &viewheight (works like &scale, but tries to target certain resolutions instead (also from the viewer's side tho). ** pushed to alpha

January 11

January 9

  • Re-worked the animation logic for VDO.Ninja; should be much smoother and accurate now.
  • When screen-sharing with &screensharetype=3, you'll now see your screen share preview, in the same way the normal screen share mode works. This allows it to work with custom layouts, as before it was hidden there, too.
  • The UI for the director's guest control boxes have been reworked; hoping this makes it easier for external CSS customization.
  • Added some added connection stats; initial capture resolution/frame of the remote publisher, along with aspect ratio iframe api updates. This should make it easier for iframe wrappers of VDO.Ninja to have accurate placeholders for incoming video feeds during loading.
  • The remote http API sample page was updated to include some recent additional button options, specifically relating to joining/leaving groups.
  • Added an option called &widget, which lets you pass a URIComponent-encoded URL value. It will load a side-bar with that page as an IFRAME embed, with support for YouTube/Twitch specifically added. -- The director of a room also has the option to enable/disable the widget function for everyone in the room via the room settings menu.
    -- This was designed for Twitch / YouTube / Social Stream chat, but could in theory work with any CORS-friendly site, such as a third-party web tool. -- If the director uses &widget, it will auto sync that with all guests as they connect. I'll try to find ways to make it easier to resize/minimize in the future.
    **changes on alpha at

January 4

  • Added support for remote PowerPoint slide control. (previous/next slide) -- Documented things quite a bit here: -- I've only tested with Windows + PowerPoint so far, but it can be tweaked to work with more than PPT without much trouble. -- Uses AutoHotKey + VDO.Ninja + MIDI to achieve the result; quite a few different ways implement it, with samples provided -- built-in basic controller added, via &powerpoint (aliases: &slides, &ppt, &pptcontrols) -- IFRAME sample app provided with larger buttons and sample code to add more custom buttons/actions if needed. (start/stop/etc): -- HTTP / WSS remote control also added; and prevSlide -- Local Streamdeck support also working, via MIDI. -- YouTube Tutorial:
    * on alpha at


December 30

  • Added &groupview, which is the same as &group, except it lets you see those groups without actually needing to join them with your mic/camera. (There's no button in the directors/guest view for this, since there isn't a need yet for that.)
  • You can change the view-only groups via the API (HTTP / IFrame) or using the Comms app, which has been updated with buttons for this option. the HTTP documentation:
  • You can now use the HTTP/WSS API to both join and leave a group; not just toggle said state. Both the view-group function and regular group function.

December 27

  • Added &mididelay=1000, which lets you precisely delay the MIDI play-out from VDO.Ninja to your MIDI device when using &midiin, irrespective of network latency. Use case: If you have a remote drum machine, you can have it play out the beat exactly 4-bars ahead, allowing for music jamming types with even high ping delays between locations.
  • Added the option to right click a remote video and add/adjust the &buffer delay for that specific video dynamically.
  • Added &buffer2=500, which is the same as &buffer, but instead also tells the system to include the round-trip-time in the buffer delay calculation. This way 500-ms of buffer on a connection that has a 200ms ping time will result in a smaller 300-ms buffer, leading to an end-to-end playout delay of ~500ms. -- won't work that well with Meshcast. -- not super precise, but on a stable connection maybe within 20-ms of flux? ** changes on alpha at

December 21

December 19

  • &fullscreenbutton is improved, so that even when there is a single video on the page, it will show. It also shows more reliably, without needing to move the mouse around a bit to re-show the button after going full screen. Lastly, when used, it now hides the native full-screen button, so users have to use it. Unlike the native full screen button, this full screen mode alternative keeps the chat and control bar overlays visible (like press F11). Since this is probably the preferred way most users will want to full screen to work, I may make it the default mode at some point, after some more testing/feedback. (not supported on iOS/iPhone tho) Changes on alpha for testing at (join a room as a guest to trigger)

December 18

  • Fixed a stats (relay vs host vs srflx) issue, where sometimes the incorrect stat appeared. fix on alpha at
  • Added a small mouse-over tooltip to the candidate type value in the stats menu, to hint at what it means again if needed.
  • GitHub updated with the newest code (currently in sync with alpha).
  • Made it so mobile won't go to sleep while streaming out audio-only content.

December 11

  • I created a guide + script for offline / local-only deployment of VDO.Ninja, so using it without Internet, connected to a router-only or something. -- I've tested it on a raspberry pi, and have included the resulting RPI image as well, if you want to quick deploy it, but the guide is pretty simple as well. -- please note: there is already code / instructions for self-deploying VDO.Ninja; this new repo is specifically to help non-techies use VDO.Ninja offline.
  • Also fixed a minor issue where specifying a custom handshake server via index.html was adding a needless URL param to all links; pushed that fix to GitHub already.

December 10

  • Pushed a couple hot fixes for recently found bugs introduced in VDO.Ninja v22.
    -- One bug caused mobile phones to push lower than available bandwidth. -- The second bug had &optimize=0 sometimes causing video scenes to not correctly load all guests when toggling scenes in OBS.
    These fixes have been pushed everywhere; production, beta, alpha, and github. Thank you for reporting the issues; please report any others you find.

December 9

  • Add &clearstorage (aka, &clear). This will clear all the saved user preferences for all sessions, including &sticky'd data, director settings, any camera and microphone settings, and probably a couple other small things. This also includes the "default" saved stated of camera settings before adjusted. I also added a button to manually do this via the User menu settings.
    ** on alpha

December 8

  • Added "change URL" permissions to the &consent flag. That is, when using &consent on the guest URL, the director can remotely change the guest's URL without additional permission -- it will just change. (&consent already gave the director controls to remotely change mic / camera) * added to alpha
  • Added &fakeguests=N (or &fakefeeds) as a parameter. It creates simulated guest videos, based on the value passed to the parameter, using real-guests where possible. The default value is 4. -- You can use this feature to help position and visualize what &cover, &portrait, etc. looks like. -- This doesn't yet support labels or layouts really, but I welcome feedback. -- Currently I just threw up a video of me, 16:9, of 500-kbps. -- You don't actually need to create a room / scene to play with it.
    ** on alpha. try it at:
  • Fixed an issue where the director's last-used saved audio output destination wasn't applying, even though the settings menu should it was selected.
  • Made it so the right-click pause video feature works with &meshcast streams. Doesn't actually stop the incoming data stream, but it does pause its playback.
  • Just pushed beta into production (v22.9) after a week of testing; this had a fix for Meshcast screen sharing and some translation mistakes. Alpha currently is running v22.10.
  • &smallshare will work on the scene-side now also, which disables the automixer's larger screen share layout, and instead just uses an equal-sized video layout for all videos. * on alpha
  • Fixed a bug with the 'deafen guest' function in the director's room. * updated on prod, beta, alpha

December 5

  • Added &automute, which will auto mute the microphone of a guest when not loaded in an active OBS scene. -- Useful for perhaps limiting the discussion in a group chat to those on air. -- &automute=2 will mute it everywhere, while the default will still allow the director to speak to the guest, even if not in a scene. -- This is a guest-side URL parameter; you may want to apply it to all guests. -- Required quite a bit of code reworking; error reporting is on in the console, so please report issues. Feedback also welcomed.
  • Fixed the Tally light system. (broke in v22 I guess)
  • The group buttons for the director will appear under their control-box when using active and using &showdirector now, rather than isolating them to the lower control bar.
  • Some minor CSS / code tweaks
  • Cleaned up some HTML code on director's page to make it a bit easier to modify with custom CSS, by a user's request.
  • Improved Firefox support for the director's solo talk and for the new &automute function; will need some further testing though. ** changes on alpha for testing at

December 4

  • Updated the &audiodevice (&ad) parameter so it can accept multiple audio devices. &audiodevice=cam,cable for example, will select the camlink and virtual audio cable devices as an audio source when joining.
  • &audiodevice={device name} will now also now show the selected audio devices before joining, while &audiodevice=1 or &audiodevice=0 will still hide the option to change or see audio devices. ** pushed to alpha and Beta

December 2

  • &noaudioprocessing is even more aggressive in disabling audio processing effects now, useful for debugging, but breaks a lot of functionality.
  • The parameter &codec=hardware is added; it's Android-specific and is the same as doing &codec=h264&h264profile, but perhaps easier to remember. Worth trying if your android phone is struggling to publish video at a high enough quality into OBS. I may expand on this feature to be smarter. ** changes pushed to alpha for user-testing and feedback. Thank you.

December 1

  • Added &fullscreenbutton, aka &fsb, adds a full-screen button to the control bar. It essentially just mimics F11, with added support for detecting the Escape button to exit full screen. -- also while using &fullscreenbutton, the previous little 'full window' button in the top-right of videos (if in a group room) will also auto-F11 and isolate that video, rather than just isolate the video. -- you can still right-click and select "full-window" on any video to isolate it without going full screen, if you need that. -- you can test by opening two such guest links: -- ultimately I'd like to override the native video full screen button with this behaviour, when &fullscreenbutton is used, but I'm still working on that aspect.
  • Fixed a bug where the guest screen share, while in broadcast mode, was misplaced on the screen.
  • Fixed a bug where &language didn't work in translating a couple elements, like "join with camera".
  • Re-enabled &limittotalbitrate for non-guests, as it was causing me some problems before with It might still be causing issues, so more testing is needed.
  • Fixed an issue where changing a system-level audio device duplicated the audio output options during camera/mic setup.
  • Fixed an issue where screen sharing as a guest, while someone is sharing a website with you, causes the website to refresh. (In the case of, this caused a reconnection loop) ** changes on alpha at the moment at, pending more testing.

November 29

  • Patched an issue with VDO.Ninja where the 'page loaded' event didn't always trigger, causing the browser to display an incorrect 'waiting to load' state. This might cause odd behaviors' to the how the page loads now, but should fix issues where OBS custom CSS styles didn't always apply. Please let me know if there are problems, and remember, the previous version of VDO.Ninja at is still available if so.

November 24

  • The recently added &audiocodec=pcm option no longer needs &insertablestreams to be used on the sender's side; works with just a viewer-side flag now and works with video.
  • &audiocodec=pcm now will support 48khz and 44.1khz mono playback (48khz default), and if &stereo is used, it changes to two-channel stereo 32khz.
  • The existing &samplerate=44100 option can lower the sample rate of this pcm mode (down to 8khz even), and hence the resulting audio bitrate. Since pcm is raw, &audiobitrate won't work, so expect 550 to 1200-kbps in just audio bitrates per viewer.
  • Fixed a bug with the video-settings sliders in the director room, where changing a setting didn't visually always update the correct feedback input field - fixed a bug where using &view=xxx&novideo didn't display a press-to-play button in the browser.
  • Fixed a bug where the self-preview video didn't have the right height when using &layouts.
  • Fixed a bug where if a guest muted their video, and unmuted, it didn't always resize correctly afterwards.
  • Fixed a bug where if a guest muted their video, the audio-only spacer box that remained would resize smaller, rather than just staying the same size. ** changes have been pushed to production (and beta/alpha) Please report any other bugs.

November 23

  • Added a couple exact presets for the aspect ratio setting; should make it easier to precisely crop an incoming guest who doesn't have their smartphone oriented right, or just in case you want to reset the aspect ratio to 16:9, etc.
    ** on alpha at

November 22

  • Made the &clock and timer overlay be something you can 'pop out' and overlay as a native picture-in-picture element; just right-click it and select pop-out from the context menu.
  • Fixed an issue where the right-click -> edit URL feature in v22 broke
  • Viewer-side &audiocodec=pcm is now available as an audio codec option; this is 32khz, 16bit, mono, and uncompressed, so ~512-kbps bitrate. You'll need the sender to have &insertablestreams applied to their URL for this to work currently, as it requires the sender to enable a special mode that allows for custom codecs. This is very experimental at the moment, so its still a WIP.
  • &micsamplerate (&msr) added, which lets you specify the capture audio sample rate. Also added purely for experimental reasons; I don't recommend touching. ** All these changes are on alpha at, which I'll push into production pending user testing.

November 19

  • Some advanced audio-related VDO.Ninja updates: -- I show the audio codec now used in the stats, along with whether audio forward error correction (FEC) is on or not (on by default)
    -- &nofec on the viewer side can disable FEC. -- &audiocodec on the viewer side can let you specify the audio codec; opus (default), pcmu, pcma, isac, g722 and red -- &audiocodec=red is pretty much sending two opus streams, with one as a backup in case of packet loss; support in Chromium 97 and up, but the only way I can so far tell that it is working is to check if the audio bitrate has doubled -- &dtx (aka, &usedtx), is also now functional (viewer side). Using this flag will turn off the audio encoder automatically when no little to no sound is detected. The VDO.Ninja default uses a dynamic audio bitrate mode (&vbr), but using &dtx takes things to the next level. It might be useful as a very mild noise-gate I suppose? -- Also fixed a couple minor bugs, such as no play button appearing when using &view=StreamID&novideo ** changes on alpha at

November 18

  • For better or worse, I updated Production (VDO.Ninja) to version v22.6 ... up from v21.4. IF HAVING PROBLEMS suddenly, please do a hard-browser refresh. This includes in your browser and the OBS browser source, if using that. The previous v21 release can still be found at, if you want to go back. Release notes coming soon.
  • I separated &sync and &buffer, so audio-sync isn't auto-enabled when &buffer is specified in the URL. I was finding &sync was causing some audio clicking issues, as adjusting audio playback speed isn't easy; you have a choice now. Use &buffer and &sync together or standalone items.
  • Fixed an issue with iPhones where changing the camera caused your own preview video to go small.
  • &screensharebitrate now works outside of group rooms, even with basic push/view links.

November 16

  • Added the "mic delay" option as a slider to the director's control; it's available by default, with up to 500-ms of delay ready. If you make use of it, it will "enable" the &micdelay web audio node remotely if not yet on, which might cause a clicking sound. Hoping that this though can help with problematic guests who might be out of sync. This is not the same as &buffer or &sync delay, which are a view-side parameters.
  • &micdelay, if used on a basic push link, will show the mic delay as a slider now also. So you can adjust it as needed. I don't show the slider by default unless using the URL parameter, as I don't think its a commonly used feature.
  • I think I fixed an issue with Firefox where not all the audio-output devices were available to choose from, at least on desktop, and so I've added the custom logic Firefox requires to get it working. On Firefox, you'll now need to select "Show more options" in the audio drop down menu, where Firefox will prompt you to select the audio output device with its own prompt.
  • Added an option called &hidehome, which hides the VDO.Ninja homepage and many links that lead to it. You can also enable at a code level with session.hidehome=true;, which is useful if doing a self-deployment, where you don't want anyone to stumble onto the site and start using it. You'll still be able to join push links and create rooms via URL parameters, but that's about it. ** updated alpha ( and GitHub with all changes.

November 15

  • Added the &clock parameter, which shows the current time in the lower right; this can be applied to pretty much all link types.
    -- The director has a button that lets them enable the clock for everyone in the room (via the director's room settings button). -- &clock=false or &cleanoutput will force-disable the clock from being remotely triggerable. -- The director has a button that lets them also enable a global count-down timer. Holding CTRL + click will let the director pause the timer. If someone joins the room or reloads, the timer will also be reloaded, in sync. Button also in the room settings menu.
    -- This count down timer is the same concept as the per-guest timer the director already has, and will actually conflict with it if both are used, since it uses the same state/variable to keep track of time remaining. -- The director will see the global count down timer also; it will just be a bit smaller on screen.
  • For VDO.Ninja, right-clicking a video and selecting "audio output destination" should work again. I had to disable that feature for a bit, as some users were reporting audio issues with it enabled. It might have some compatibilities issues, but it won't activate now unless used.
  • When using the special &screensharetype=3 screen share mode (screen share with better echo cancellation), support for recording that local screen share, at the same time as as the main video, has been added. You'll need to use the &autorecord feature to trigger the recording, and when it does start recording, a button will appear specific to stopping that screen recording if needed.
  • I improve the &buffer and &sync feature a bit -- it will activate and sync up faster now, which might be helpful on unstable connections.
  • I haven't been able to validate it works, but I think I added support for H265 (HEVC) to VDO.Ninja; the catch is it might only work between two iPhones running the experimental H265 WebRTC support currently; maybe Raspberry Ninja in the future. I haven't managed to make it work yet though, so its just hypothetical support. ** This is all on alpha, at I'm definitely feeling its time to push this code into production soon, so if you get a chance to do any tests on alpha (maybe mobile / load testing?), it will help speed up the release. Thank you.
  • Applied a small hotfix to production related to iPhones, specifically in response to iPhone 14 issues. If anyone encounters problems with using iPhones on production, including issues with muting, let me know.

November 11

  • Added a new URL parameter. &directoronly (&do). This is just the same as doing &view=DirectorStreamID, but without having to know the stream ID for the director.
    -- It will actually connect to any director, including co-directors, not just the main one.
    -- &view, &include, &exclude have a lower priority to &directoronly. So if there are two directors, you can do &directoronly&exclude=coDirector123, so that the codirector doesn't connect.
    -- I changed the toggle in the director's room for "Guests hear others" from &view= to &directoronly. The point of this change is that the director can now still talk to those in the room.
    -- Purpose of change: I had a user who wanted &broadcast, but also not have the guests hear each other. It's a bit of a hassle to do &view=DirectorStreamID, and the toggle is labelled to be misleading by saying "guests", not "everyone".
    -- You can use &directoronly to replace &broadcast if you don't want the guests hearing each other.
    ** change is on alpha for testing and feedback.

November 8

  • Added a 'cycle visual styles' button to the "users" settings menu in VDO.Ninja (and Comms app) This lets you toggle the &style=N options, between 1,2,4,5,6 I think? So if you find it distracting, the waveform in the Comms app or such, you can toggle as a guest.
    ** Change is on alpha at

November 7

  • Fixed some issues with the 'last used' audio output device saving feature, as it was not always triggering fully on page reload. The selected output device didn't always match the actual output device, in some cases, after a page reload. -- note: I don't load the last-used 'saved' output device if loading a scene/view link, unless its set in URL param, as I just found it was too confusing as there was no obvious way to check what the default audio output device was in that case.
  • When using &vd=videoDevice, the name matching order now sorts based on NameStartsWith, then ExactDeviceID, and then finally NameIncludes. This should avoid the Streamlabs OBS Virtual Cam being selected when you actually want the OBS Virtual Camera being selected, as the two devices both contain obs virtual camera in their name. It was causing me grief at least.
  • Couple minor bugs, like the right-click "show control bar" option not toggling the menu option in the UI properly when the control bar is visible. *** changes on alpha for testing and feedback. Thank you

November 5

  • Fixed an issue where the transfer-function for co-directors wasn't a bit broken; transfers were only partially completed. The fix for this should be on alpha now at

November 4

  • Pushed a workaround for a nasty iOS bug that is impacting iPhone 14 Pros. Fix is on production and alpha; Please report any issues it might cause.

November 3

  • Fixed a bunch of co-director sync logic, which was a bit buggy before, but I think I got the issues out.
  • Updated the video stats code with the newest spec; Chrome was deprecating the API I was using.
  • Added stats support for Firefox, including support for it in the speed-test, the guest check app, and stats pop-up.
  • CTRL + click support to access the stats pop-up added to Firefox (before you had to right click and select "show stats" from the menu). ** changes applied to alpha at

November 1

  • &controlbarspace forces the bottom control bar to be in its own dedicated space, regardless of screen size.
  • &volumecontrol (alias, &vc) shows a dedicated local audio-volume control bar for canvas or image elements. Video elements already have a control-bar with volume, so I don't show it there currently. I'll likely tweak this more over time.
  • Fixed an issue with &screensharetype=3 crashing the browser when specifying an audio track to share. ** changes are at The Comms app is a good demonstrator of the features

October 30

  • Deployed a turn server to Seoul, SK. on beta & alpha

October 28

  • Added more 'visually impaired' meta data to help with assisted readers ** on

October 26

  • Added &labelsuggestion=defaultnamehere (aka, &ls) This is the same as &label, except it asks the user still for a user name. If they leave it blank or cancel the prompt asking for a name, it will use the default label. Once the user enters their label, &label=username is added to the URL, so if they reload, they won't be asked again for the label. &label takes priority over &labelsuggestion. This is on for testing/feedback
  • Fixed an issue where &activespeaker and &showlist and &style=6 wasn't working together as expected
  • Updated , so it's now in sync with alpha

October 24

  • Added &groupmode to VDO.Ninja, which changes the way groups work when not in a group. With &groupmode added to your URL, when not assigned to a group, you don't hear or see anything. This also goes for remote participants who are not in a group - you will not see or hear them if they are not in a group, even if you also are not in a group. The default normally with VDO.Ninja is that if not in a group, you see and hear everyone. This remains true if not using &groupmode, even if others in the room are. Others may not be able to see or hear you though, if they have &groupmode enabled, and you haven't picked a group. So, &groupmode only impacts the local user, and will not impact remote connections. ** changes are on alpha. Please report bugs.

October 10

  • Added &layouts=[[{xxxxxx}]] as a URL parameter option, where you can pass a set of different layouts (as a URL-encoded ordered array) to VDO.Ninja. (** on alpha) This is akin to using the, to visually set layouts, but instead you are just manually setting all the available layouts directly, bypassing the mixer app. Once you have set the layouts, the "layout" API feature becomes a bit more useful, as you can remotely activate any of those layouts with a simple API command. I documented the 'layout' API option a bit here, but the tl;dr; is that you can either use this API call to set a layout from within the array of layouts that are set, or you can pass a full-fledge layout-object, for on-the-fly custom layouts. ie: {action:'layout',value':5} or {action:'layout',value':[{xxxx.layout-stuff-here.xxxx]]} fyi, the layout and the API in general work with the page, so you can use it to create the layouts, and then manually switch between them via the API. The API is streamdeck-friendly.
  • &meshcastbitrate works again; some recent chrome updates I think broke it a bit, but it's fixed now. This lets you set the Meshcast bitrate higher than 2500-kbps via VDO.Ninja. (Please set sparingly, with targets limited to just what's needed)
  • The director's "request" microphone/output change button has a "refresh" option now, which doesn't require a user's permission to use. It will "refresh" the currently active microphone/speaker output, which might solve issues with unexplained sudden audio loss. (the 'refresh' will reconnect the audio pipeline for that device, so if it crashes, this can potentially fix it -- fyi, this already was an option for the video device. -- if using the &consent, then the buttons will now say "apply", instead of "request", as you don't need to request a change in that case.
  • Fixed some niche audio issues where if loading canvas-only view links (no video, just audio) are loaded in Chrome/Firefox, with &style=2 set, the audio didn't play due to auto-play problems. With this fix it will now play the audio, although you'll still need to click the screen first. Before it got a bit stuck, even if clicking the screen. ** changes on alpha at

October 8

  • Custom groups used by remote guests now show in the director's view, just like custom scenes do. -- If you use &groups=group,test,vdo, new group buttons will appear -- By default, groups 1 to 6 are there -- If you use &groups=1,2,3 , you'll auto-join groups 1, 2 and 3

October 2

  • Fixed a couple minor bugs with VDO.Ninja, such as the &consent message on dark-mode not being easily read.
  • Improved the API for remote controlling mute/add2scene/etc for guests. True/false and 'toggle' work as values now; before just toggle worked for guest-specific calls. (changes on alpha)

September 27

  • Updated the 'create reusable link' page a bit; added the option for "generate host link also", which sets things up for a simple two-way interview format.
  • &welcomeimage added; this lets you specify a welcome image (URL) that appears for a few seconds before fading away once a guest joins. ie: ** on alpha

September 26

  • Updated the screen-share layouts to have a larger screen, relative to the other videos: It now targets an average of around 80% screen real-estate for the main screen share.
  • Up to 20-videos on screen now are supported in the screen-share view; before after around 12-videos they started to be hidden
    **changes on alpha ( and github

September 23

  • Firefox won't playback stereo audio as stereo by default now; it will require the &stereo/&proaudio flag to enable stereo playback. &mono also works with Firefox now, allowing you to use &proaudio&mono with Firefox. (this was just a quirk of Firefox's default settings vs Chrome that I long needed to address)
  • Made the little upload arrow in the top-right color coded in response to the detected 'average' upload connection quality; won't be supported by all browsers, but most.
    ** updated both alpha and beta.

September 21

  • When using &waitimage, the specified 'waiting to connect' image will appear after all connections end. This is a bit different than the default behaviour of the spinner, which doesn't re-appear, but I assume if you're advanced enough to use the &waitimage option, you're okay with this.
  • Added the option to "draw on the screen", which might be a useful tool for niche use cases where you might need to take notes, etc. It doesn't affix to videos themselves, but rather it's just a full-window transparent canvas overlay, You can start/stop/clear and select a couple style-types with this feature, via the settings -> User menu. You can also do CTRL + ALT + D to toggle this as needed.
    ** on alpha at

September 19

  • With VDO.Ninja, if using &stereo, &s , stereo=5, or &proaudio, I'm now showing a little check-box that the guests themselves can check to set their mic input to MONO mode. While there's a few different ways to set a mic to mono mode, they aren't always obvious to people I'm finding, especially when using &proaudio/&stereo mode. For example, some guests will appear in the left or right-audio channel, due to their mic/interface setup. It's not always obvious on how to fix this when about to go live, so I'm hoping this helps avoids those situations. -- It won't interfere with the screen share modes, so they will be stereo still -- It won't show if using &stereo=1, as that is explicitly stereo since a value is passed. -- The guest can toggle it on and off in the settings, without needing to go into any advanced audio settings -- The remote director can still use the existing "channel count' in the advanced audio settings to override this button, unless the guest toggles it back on -- There's several other ways to set mono mode of course, including &monomic, &inputchannels=1, &stereo=3, channelCount, &mono (playback), &ec&dn&ag, and within OBS/Windows itself.
    ** updated on to alpha at

September 17

  • &waitimage now has its wait image 'fit' to the screen, and &cover will have it 'cover' the screen.
  • &waitimage now works with scene links; not just basic view links. (** on alpha)

September 16

  • Simplified the connection type wording in the stat's menu , plus made the publisher's connection type available to the viewer's side so you can more clearly see now if a guest has ignored your request to use Ethernet.
    *** Changes on alpha at

September 12

  • Added &effects=7 (or &effects=zoom), which will provide a manual zoom option in the effects menu. (you can also select the zoom mode via the effects menu, if available)
  • Added &getfaces on the viewer link (or {getFaces:true} via the IFrame API), which will request a continuous stream of face bounding boxes, for all inbound videos and all faces contained within. The data is transmitted to the parent IFRAME, and this data can be used for moving the IFrame window around, if you wish to make your own custom face-tracker or whatever else.
  • &effects=1 on the sender side (or &effects=facetracking) will auto-center the user's face in the center of their video, zooming in as needed. It takes a moment to initiate, but it offers a gentle PTZ-like effect. -- note: I previously had &effects=1, but it wasn't that good, so this is a more polished attempt. It's also available from the effects drop down menu now as a selectable option, as before I was hiding it.
    -- important note: Both &getfaces and &effects=1 requires the use of the Chromium experimental face detection API, as I'm using the built-in browser face-tracking model for this. You can enable the API flag here: chrome://flags/#enable-experimental-web-platform-features My hope is that this feature will eventually be enabled by default within Chromium, as loading a large ML model to do face detection otherwise is a bit heavy; you may need to enable this within the OBS CLI if wishing to use it there? *** Changes on alpha at

September 9

  • Added mobile touch support to the tap-to-focus (only mouse support previously).
  • Minor issue with drag-to-zoom fixed.
  • Fixed issue with not being able to reset video settings to default after changing them.
  • &autohide works better now; also on mobile, the &autohide makes the control bar transparent on timeout, to avoid conflicts with tap-to-zoom/focus logic.
  • It's easy to adjust video settings on mobile, as there is a large space to scroll without accidentally clicking a setting slider. Also more bottom padding, making it easier to click close in landscape mode.
  • Made the &sticky redirect confirmation prompt less ugly, and I now don't ask if the URL already matches the saved session's URL.
  • Made some changes/fixes to the recently new switchMode (&previewmode) function of the director room (hopefully no bugs?). ** changes on alpha @

September 7

  • Added some notice icons to the PTZ controls, which show a tooltip on hover that explains remote PTZ only works if the remote window is visible.
  • made the audio / video director control settings scrollable (max height ~500px), so you can more easily see the video while making changes to it.
  • Increased the size of Canadian and German turn relay servers (4x larger), and completed other backend maintenance.

September 6

  • &showconnections will display the total number of p2p connections of a remote stream. Works with the director's room and the automixer. Might help give comfort over privacy/security during a stream.
  • Total number of p2p remote connections (viewers) of a stream source will also appear in the stats menu, even without &showconnections. Could be useful for debugging CPU/bandwidth issues.
  • Connections may represent video/audio streams, or just a data-connection. Meshcast-hosted streams might not be accounted for, depending on how the viewer is connecting.
  • Added showChat and showDirectorChat as HTTP/WSS API options for sending messages to guest(s). Useful if you want to hotkey a streamdeck command with some welcome message for guests.
  • Added events notifications relating to the director's guest-mute, guest-video-mute, and guest-position-change actions, along with any remote-video-mute updates to the HTTP/WSS API (by request for the bitfocus companion app)
** on alpha

September 2

  • Noise gate remote control has been tweaked a bit; the correct state is loaded now on a director's page refresh
  • Added an option to control the compressor remotely (3 states for the compressor; Off/On/Limiter)
  • Fixed issues on alpha, including now where the labels for guests were not always positioning correct if audio-only
  • ** changes on alpha @

August 31

  • Added a button in the director's room. It lets you toggle between a Preview layout and the normal Director layout; the Preview layout will mirror what a basic &scene=0 link would look like. Useful if you want to switch to a guest-like mode as a director, and then switch back as needed to the director's room to make adjustments. - to enter this mode by default, &previewmode can be used by the director ** on alpha at
  • &noisegatesettings has been added to, which is used in conjunction with &noisegate. This feature lets you tweak the noise-gate's variables, making it more or less aggressive as needed. example:,25,3000 It takes a comma separated list: -- First value is target gain (0 to 100), although 0 to 40 is probably the recommended range here -- second value is the threshold value where the gate is triggered if below it. ~ 100 is loudly speaking, ~ 20 is light background noise levels, and under 5 is quiet background levels. -- third value is how 'sticky' the gate-open position is, in milliseconds. Having this set to a few seconds should prevent someone from being cut off while speaking or if taking a short pause.

August 25

  • Added new sender-side parameters that can customize how you want VDO.Ninja to balance resolution vs frame rate, specifically when bitrate or CPU is insufficient to offer both at the same time. -- for video, &contenthint=detail -- for screen-shares, &screensharecontenthint=motion, which will override &contenthint for just screen-shares if set also. The two options for video are detail or motion. Screen shares generally tends towards detail by default, and camera sources are tend towards motion by default. detail will try to prioritize resolution over frame rate, so the frame rate may drop a lot used. motion will try to maximize frame rate, but may drop the resolution a lot. There's no way to force both on as there's no magic bullet if your CPU or network cannot keep up. note: If using &codec=vp9 on the viewer side, the frame rate may drop as low as even 5-fps. -- Also for audio, I've added &audiocontenthint=music The two options are speech and music. No idea what it does exactly, but when using music there seems to be a fixed bitrate of 32-kbps sent out by default, where as with speech it is variable, using less bandwidth when not speaking. These parameters have been tested on Chrome, but other browsers may vary in behavior. Safari seems to just ignore things, for example. ** changes on alpha

August 23

  • Updated the translation files on GitHub and on, so recently added UI elements can have alternative translations added
  • Custom scenes will now be sorted based on alphanumerical value. (rather than order of connection). ** on alpha

August 22

  • When you toggle the customize-scene-link function as a director, some of those items will now be applied to the guests' solo link also. (just the ones I think are relevant)
  • &sharper and &sharpen are now aliases of &dpi=2, which should 'up to' double the amount of playback video resolution, if the dynamic resolution optimization is enabled at least, in certain cases. This is a lot like &scale=100, but perhaps slightly more efficient in some cases. This is mainly for when you intend to have a large screen-shares in a scene, where you don't want the tiny guest videos to be a 100% scale, but 50% scale is fine (up from 25% scale). &dpi already exists on production, but by adding these aliases, I hope it's more discoverable.
  • As an alternative to &sharper, I've also added &sharperscreen, which sets &scale=100, but only for screen-shares. (virtual cameras not included). This is probably even more efficient than &scale=100 or &sharper, and it's designed for when screen-sharing a lot of text. Text looks a bit soft when streaming video at 1:1 pixel resolution. It's recommended to only use these parameters within the context of a scene link, and not on guest links, due to the higher CPU / bandwidth it may use.
  • Chunked mode on alpha lets you switch cameras/audio now, without them breaking; muting video still breaks things tho. (chunked mode remains a WIP) ** changes push to alpha
  • Put up a YouTube video (second in a series so far) where I am investigating the performance of a cellular bonding device and its software, specifically as it relates to VDO.Ninja uses. If on a bad connection, doing remote streaming, or just want some added stream reliability, cellular-bonding seems worth considering.

August 17

  • Added the option to customize the &grid (&ruler/&thirds) effect by passing an image link. (can help center guests) -- transparent PNG or an SVG file are the recommended options. -- it will stretch to cover the camera preview-area, so probably best to keep things 16:9 aspect if needed. -- URL can be URL-encoded, for more complex URLs. Simple URLs might work without. -- technically this can be used as an overlay for other things, but it only works with the self-preview. -- leave the passed value empty if you wish to have the white basic rule-of-thirds show as default. example: ** on alpha.
  • Added as an alternative to If's a more user-friendly version of &proxy. ** Just on alpha for now

August 16

  • &activespeaker=3 and 4 added; which are the same as 1 and 2, except it will not switch to show audio-only sources (just video only). As a recap, active speaker mode shows the person(s) who are actively speaking, and hides those who aren't.
  • Fixed a bug/race condition in Chrome where the web-audio audio effects pipeline and having to 'click-to-play' didn't always unmute all the audio. (&activespeaker mode when viewed as a scene, in chrome, for example. Wasn't an issue in OBS)
  • Changed chunked mode a small bit, so the video stream uses the same frame rate and resolution of the original video source, rather than a fixed resolution/frame rate.
  • Chunked mode should work with audio-only or video-only tracks now
  • Solo links are setup to use &solo instead of &scene now; it's the same outcome, except &solo tells the system not to apply custom 'layouts' to them. Links updates in the director's room and the mixer app. ** changes on the alpha version of VDO.Ninja at
  • Added details on how to fix camera permissions denied, improving the messaging with an image and doc link. * on alpha

August 11

  • Right clicking the screen-share icon will give you an option to open the screen share in a new tab, all pre-configuerd. Useful if you want to share multiple windows while in a group room, or don't want to see your own screen share while talking to others.
  • Bugs with &screensharetype=3 have been resolved, I think. (this mode supports desktop-audio capture without echo issues)

August 9

  • &aspectratio now works with screen shares, so you can force crop an incoming screen share to be a certain aspect ratio. If &screenshareaspectratio is used, (&ssar), it will apply to just screen shares. If &ssar does not have a value passed, it's assumed to be set as "default", which overrides &aspectratio option, if used also. ** on alpha, ie:

August 6

  • The API / IFRAME sandbox page for developer using VDO.Ninja got a style update and facelift by @Sam MacKinnon Ty, * it's on alpha at and GitHub.

August 5

  • When the director talks to you in solo-talk mode, the other guests in the room now drop to 25% volume. This way the guest the director is talking to can hear the director more clearly. (by request) * on alpha,

August 3

  • &hidecodirectors will hide the co-directors from appearing in the director's room. You might have a few co-directors join you, but they might be taking up space, so this is a way to prevent that. It simply hides the boxes; they are still there at a code level.
  • Added, which will mirror the updates from this discord 📑│updates channel, which should be helpful for those not using Discord to see development progress. (basic, but will undergo more updates). The Discord in general has been undergoing improvements; the mods here have been working hard to keep the discord and documentation functional, so thank you to them.
  • Added &mobile and &notmobile as a couple options to I already have &flagship, &noscale, and &forceios as a few options to configure mobile devices, but mobile/notmobile are more generic options that will optimize a guest/push link based on whether VDO.Ninja thinks they are a smartphone or not. &mobile might help reduce CPU issues, and &notmobile might be able to improve video quality (in case you want to override the automatic defaults, which already detects if a device is mobile or not).

August 1

  • Chat messages that contain URLs will now have those URLs be clickable (opens into a new window)
  • The pop-out chat feature has had a bug fixed and minor polish applied
  • When using the IFrame API to control bitrates, I have added an optional called "lock" that lets you affix the bitrate you set so the rest of VDO.Ninja doesn't try to constantly override it. {bitrate: 2500, lock:true} for example. I also assume lock=true by default, so no changes are needed really to start benefiting from this. (previously you had to disable the auto-mixer to lock a bitrate).
  • Also added {manualBitrate: xxx} to the IFrame API , which is a bit like bitrate, but keeps track of what the current target bitrate should be. When you set manualBitrate=false, it will apply the expected target value. Also, it won't work when used in conjunction with custom audio bitrates, whereas bitrate will.
  • There's a third new bitrate option, which is targetBitrate, which lets the automixer keep doing its thing, but it sets a new max target bitrate. The target bitrate will still be applied when set, but the automixer may lower it if needed when it decides to, but it's the new target for 'unlocked' max speed. Some browser will ignore it though, if it's set higher than the bitrate that was manually set the via URL, so it's probably something you don't want to use along with &bitrate.

July 27

  • Fixed the new OBS &remote=xx not working correctly when a password was set (on alpha and GitHub)

July 24

  • Fixed a bug where if the director is highlighted, newly loaded scenes would be blank.
  • Added two-way solo talk as an option to the http/wss VDO.Ninja API.
  • Also, - added the ability for VDO.Ninja to Remotely Control OBS Studio while streaming/directing; useful for IRL maybe? -- The menu button to control OBS auto-shows in the director's view or push-mode, if OBS Studio is set to give VDO.Ninja "full" permissions. -- The menu button can also be added manually, for even guests, using &controlobs -- &obsoff can be used to set permissions to fully off (also disables tally light and scene optimizations tho) when added to the OBS browser source link. -- The OBS instance still needs &remote={optional-passcode-here} added to the URL for remote commands to work. If &remote is left blank, it gives anyone permissions to control it. If a value is passed to &remote, the sender needs to have a matching &remote value or manually enter they need to manually enter passcode in the pop up control menu. -- If the OBS browser source has its permissions set to something other than full (lower than level 5), the control menu will still show what info it has -- current scene, recording/streaming state, etc; depending on level. The lower the level, the less info is available to show; can't remotely change anything though. -- It supports multiple OBS instances and will label them according to the &label=xxx value set on the scene/view link, or whatever the unique connection ID is. All this is on alpha, at

July 23

  • The &webp mode has been modified a bit. Main change is that you now enable it by add &webp to the sender's URL, and &codec=webp to the viewer's URL (otherwise, it falls back to normal video mode). No need for &broadcast anymore. (as a reminder, this mode sends the video as a series of low-quality images, rather than a more efficient video stream).
  • I've removed the toggle in the director's room for this &webp feature, as &chunked mode is replacing its purpose there, but you might still want to use this mode when the viewer-side does not support video playback or hardware acceleration. Specifically, this option lets you bring motion images (aka, crude video) into the Streamlabs mobile app, as a browser source, where other forms of video decoding is not supported.
  • I've also created a new viewer-side option called &slideshow . This option decodes incoming video (first video to load), but plays them back as series of full-window images. That is, a single image element, that gets updated 24 times a second, instead of playing the video back within an efficient video element. I have no idea why you might want this option, as it pretty crude up and uses up a lot of CPU, but you can right-click to save a single frame from the video to disk, as a PNG file. This might be useful if you need to take a lot of snap shots of some video and don't want to have to hassle with cropping a window-grab. Quality of the images is pretty high; near lossless. ** on alpha

July 21

  • The &grid overlay option now works in non-room mode
  • Added the toggles for &grid and &avatar to the director's link customization section.
  • Added &smallshare as a new option, which makes the screen share behave like a webcam share. ie: not larger in size vs other windows, for the publisher or the viewers. This is a push-side parameter. This is useful if a VR guests screen sharing an app of themselves, versus using a virtual camera. It can also be useful for gaming, where a larger screen share might bog down the system of the sender more than needed. *** on alpha at

July 20

  • Updated the local audio controls to have a NOISE GATE option. -- This is a new noise gate, that lowers your mic volume to 10% of its current value based on volume-level activity. If you haven't made a significant sound in few seconds, the noise gate kicks in, and will re-enable when a significant noise is detected. It will take about 300-ms for the volume to recover once the noise triggers it back on, which can be a small bit harsh/distracting at times. -- &noisegate or &noisegate=1 (&gating/&ng) will enable it by default (if using it in a room, currently); and &noisegate=0 will hide the option from the menu. -- The older existing &noisegate=1 option I moved to &noisegate=4, as this new version is replacing it. I'm keeping the older version around as an option though.
  • Fixed some of the labels for the local audio labels; camel-case is replaced with words, and true/false replaced with on/off.
  • Fixed an issue where iPhones's video output would freeze when the director would feature-highlight any other participant.
    ** on alpha at

July 19

  • Added the ability to "tap to focus" when a camera supports focusing. You'll want to switch the camera over to manual focus (via settings->video->focusMode) before it will be active, but then you can just touch on the screen to have it auto-focus on that spot. Note: It's a bit slow and not 100% accurate and may conflict with the zoom, if used. on alpha at
  • Improved the advanced video settings; focus, exposure, white-balance. The auto and manual modes are now a checkbox, and I worked out a few of the odd behaviour issues that Chrome + Logitech webcams were having when try to set modes/values. *** on alpha at

July 16

  • Added an option to post a snapshot of your local camera to a HTTPS/POST URL (blob/jpeg)
    so, for example, posts to a sample test server I have up. The URL is URL encoded, but not always necessary. If posting to my test server, the image can be accessed at There's caching enabled mind you, so you'll want to post-fix the current timestamp to the URL to disable that per request. For example, This feature could be useful to checking out a stream before actually connecting to it, as that's my intent with it, but it is also something you can use with Octoprint, where you need an IP camera jpeg source as input. ** on alpha, at

July 14

  • The &website function now lets you start/stop and change website sources; no longer is it just one site and that's it. (only the director previously could change websites constantly). I suppose you could use this to remotely change inputs in an OBS browser source via a remote website, as I think the YouTube implementation supports synced playback/scrubbing.
  • There's toggle in the director's room now to add &scale=100 to the scene links. Might improve sharpness a bit, at the cost of increased CPU/network load.
  • Fixed an issue where if a guest was viewing the director in full-window mode, and the director changed the total room bitrate value, the new &totalroombitrate value would be ignored by that guest until they exited the full-window mode.
  • Also fixed an issue where if setting a custom total room bitrate value higher than 4000 via the URL (&totalroombitrate), the slider to adjust the TRB value will be extended so the max range is that of the URL value if higher than 4000. ** on for testing.

July 10

  • Tweaked the mic meter on (3x more intense) and added a visual meter to the settings menu; should help judging if you're mic is active easier. (by request)
  • In case curious, I've been working on quite a few core-components and larger new features for VDO.Ninja this week. ie: chunked video improvements, IFrame API enhancements, refactoring code for future ui dev efforts, and some invite management features. I'll probably update more on those things once they are further along or complete.

July 3

  • Unless manually specified (&screensharequality or &screenshare), I have the screen share resolution matching the webcam resolution now. This avoids a sudden CPU spike when screen sharing; still room for improvement tho.
  • For the time being, I have &limittotalbitrate only applying to guests, rather than all viewers. I need to revisit this at some point soon. ** changes on alpha

July 1

  • The WSS API (wss:// has been expanded to include hang up events for publishers, along with viewer-side events for incoming connections/streams. These efforts will lead to a richer StreamDeck integration.
  • Add &background, which accepts a URL-encoded image URL to make as the app's default background. For example, . The image will scale in size to cover the VDO.Ninja app's background. &chroma can still be used to set the background color, if using transparencies. There already exists &bgimage, which will set the default background image for videos; this however will set a background image for the entire page.
    ** These changes are on alpha

June 30

  • Fixed a bug with &statsinterval=100 not updating on sender side (only viewer side before). This updates how frequent the stats updates.
  • Added the ability to dynamically change the scale of a video to the IFRAME API. accepts scale, plus optionally uuid or a stream ID as a a target.
  • Added &base64js, which lets a user add raw java script to the URL to run on page load. to test. ** changes on alpha

June 28