Ninja Docs
Updates - VDO.Ninja
A general notice to users, on beta and alpha, the echo cancellation isn't working at the moment. It is working on the main production version however. If using or, switch to just if having echo problems or wear headphones at low volume. I'm working on a fix, but I don't have an ETA. Will update when fixed.
** UPDATE: I hot-patched beta and alpha with a fix. This fix disables the option to select custom audio output destinations, but resolves the echo issue. If using a self-deployed instance, you can instead add &noap to the URLs to fix it as well; you can also enable chrome://flags/#chrome-wide-echo-cancellation, patch the code, or just use headphones.

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

  • Added support for &buffer and &sync to the viewer when using &chunked mode on the sender. If on an unstable connection, setting the buffer to a few seconds can help avoid pauses in the video playback, as there will be some buffer to use. (a bit experimental still -- so it might be more a WIP still ).
  • Added a new url param called &include, which is like &view, except it's for including streams that do not exist in the room you are in, assuming those streams are not in another room and have matching passwords. So, useful for adding basic push-streams that you might want to be in multiple rooms at the same time, but not actually be locked to any room. (&view, conversely, is pretty exclusive; that or nothing.)
  • Been playing around a new flag called &flagship, which will optimize the mobile experience for more capable smartphones; essentially, streaming higher quality video to other guests versus the normal mobile-performance mode.
  • I've also modified the non-flagship mode, for low-end mobile devices, to use the &limittotalbitrate flag by default (500-kbps). &limittotalbitrate hasn't been that heavily tested yet, but it's part of v22 and might be better than &totalroombitrate; currently I'll increasingly use them together I think though. They are both the same concept, except one is viewer-side controlled, and the other is sender-side controlled; both limit the bitrate that guests in the room see based on the number of guests in the room. ** changes to alpha, at

June 25

  • The remote control API is expanded to send push event notifications to web-socket listeners when the local mic/speaker/camera is muted. This was added on request for making the bitfocus companion app smarter about keeping track of mute states. (on alpha)

June 16

  • Option to randomly generate a room name has been added to the room-creation page - minor fixes to the mixer have been applied; (lots more to do)
  • &aspectratio + &crop (sender side options) has been updated to work with more camera/sources. If you do for example, you'll get portrait mode. Not compatible with Safari though.
  • Video/audio stats for Firefox have been improved; resolution, framerate, codec, bitrate.
  • &meshcastcodec=h264 won't fail when using Firefox and Meshcast
  • &chunked recording in the director's room works correctly ** These changes are on beta @

June 9

June 8

  • When screen sharing, if the resolution that's requested by the viewer is roughly 100% full scale, (a value based on their window viewing size), the system will now snap the resolution up to 100% (like &scale=100). This should help with video sharpness (text, etc), when the added burden of slightly more CPU load is worth it. Won't snap if the different is great though.
    For example, if a viewer is on a 720p display, watching 1080p content from a director, that's not close enough to make it worthwhile for the director to send 1080p. But if the viewer's window was 1050p, then sending the full 1080p video is worthwhile. This is mainly because scaling seems look nicer when done on the viewer's end, instead of the sender's side.
    Only applies to screen shares, as text-scaling is kind of ugly, and it seems to be commonly desired to make fonts less ugly when screen-sharing. Scaling will still occur, but it won't be as ugly when done by the viewer. Sending 100% all the time works too, via &scale=100, but is pretty inefficient and needlessly heavy on the CPU in most cases.
  • Fixed on issue where is screen sharing as a director, before turning on your camera, didn't show the screen for guests always.
  • If the director isn't a performer, I've added the option to still add a director to/from groups. The group buttons show up in the control bar; where you can add them either via &groups=1,2 or via the / companion service. --- Toggling the director in/out of a group via the API is new. (NULL targets director). --- If &showdirector is used, it will not use the control-bar for group buttons 1 to 8 --- It technically is possible to use groups via the API or URL other than 1 to 8, but I only offer buttons to add guests to groups 1 to 8.
  • Using the &api remote API option, you now can get STATE values as the reply to a GET/POST/WSS request. So if you do, with &api=c6sWHN9zzX added to the director's URL, you will toggle the director in and out of GROUP 1. The response of the HTTP GET request though will be true or false or timeout, based on whether the director was added to the group, removed from the group, or whether it failed. This new feature can be used with a Streamdeck (or other controller) to have the button's color of the Streamdeck match the state of the action.
    *** This is only supported on currently

June 7

  • When holding CTRL and selecting multiple videos to record as a director (in control room), it won't ask for the video bitrates multiple times now; just once for all the selected videos. (this hot fix has been applied to production and beta). This feature is useful for recording multiple videos in sync.

June 6

  • Fixed an issue where if you did right-click -> record of a inbound-video, and then hung up without stopping the recording, the recording wouldn't stop and finalize. (on alpha)

June 4

  • Added the ability to have multiple unique audio output destinations per VDO.Ninja instance.
    To use at the moment, right-click a VDO.Ninja video in chrome/edge/electroncapture, (on the alpha-version of VDO.Ninja), and you'll see a menu option to change the audio output destination. This selected output destination overrides the default audio output destination set in the VDO settings menu, and it's specific to just the video that you right-clicked.
    This option allows you to have one audio stream output to a virtual cable, and another output to your headset, for example.
    Over the next few days I will probably change up how the menu works, as its pretty crude right now,. This feature also doesn't work in Safari/Mobile or if audio processing is disabled, so that UX aspect needs work. Hoping it's a good start for now though; testing welcomed.
    ** on

June 2

  • &sensor now also includes speed and altitude data (on production)
  • Added a demo/sample on how to overlay speed + acceleration on top of video playback (compatible with a mobile phone sender)
  • Added a new option to explicitly list what sensor data you want to capture and transmit, when using &sensor &sensorfilter=gyro,lin,acc,mag,pos,ori For the above demo, you can use &sensorfilter=pos,lin to just send the data you need, reducing the load on the phone/network. (on alpha)
  • Right-clicking a link in VDO.Ninja will now offer the option to show the link as a QR Code. This makes it easy to copy any link over to a your mobile phone or to create a shareable QR code with guests. (on alpha)
  • Implemented a workaround for a novel Chrome bug where specifying a custom audio channel in the director's room (C1, C2, etc) would break the custom audio output device support. * Fix pushed to alpha.

June 1

  • Added the &meshcastscale (&mcscale) parameter; this will scale down the Meshcast video output via the URL, post camera capture setup. Because of how Meshcast works, this is a sender-side parameter. You may wish to use this to lower the resolution if your camera has a fixed capture resolution. (Alternatively, if you need to dynamically adjust the resolution, that option already exists via camera settings via width/height slider adjustments)
  • Fixed a conflict when using &director parameter + &webcam/&website/&screenshare parameters at the same time (the later parameters get disabled now, avoiding conflicts)
  • If using a view-push link combo, just to be safe, I have the viewer re-request unloaded streams automatically at a interval now. For unattended viewing sessions.
  • Pausing a video while it is in 'full window' mode, will actually pause it now.
  • Added a "channelCount" option to the audio controls, which will let the director/sender toggle between Stereo and Mono audio channels, IF &stereo/&proaudio is added to the sender's URL and the sender supports +2-channels. So, if you're using &stereo on your guests, and you can only hear one of your guests on the left or right channel, you can use this to down-mix their microphone to a mono channel only. Due to some tricky technical challenges, this feature involves down mixing with web-audio nodes, and stereo can't be enabled if &stereo isn't in the URL. It might also make all audio from that guest mono at the moment. (adding &mono to the view URL also works, but that will make all sources in the view link mono)
    ** all updates on alpha at

May 27

  • Improved logic for determining best turn server to use, if needed. (on alpha)

May 23

  • Deployed a new turn server in Poland; it's only yet available on alpha.
  • Two large broadcast servers enabled on production, in France and Canada.

May 21

  • Added new viewer-side parameters that can be used in place of &scale; &viewheight=180&viewwidth=320, (aka &vw/&vh) which effectively does the same thing as &scale, but instead you pass a resolution. -- It's important to note, that due to flexibility to request width/heights that are not aspect-ratio compatible, and due to bitrate/quality resolution limitations, these values are just 'max' target resolution values; the actual resolution you get could be still less. They also do not impact the actual capture resolution of the remote sender's camera, so its purely for requesting a specific downscaled resolution. This command applies to all video elements in a view port, and it disables the auto-scaler functionality. -- Similarly, also added the option to the IFRAME API to request different down-scaled resolutions dynamically, per connection, if you want greater programmatic control vs static URL options. This is on alpha at

May 20

  • Added options to host your own default background images for the virtual background effect; -- &imagelist=xxxx can be used to pass a list of images via the URL. Code to generate the list properly can be found here: (images must be cross origin enabled) -- At the base of index.html, if self-hosting VDO.Ninja, you can hard-code the list of images as well. -- Related: when selecting a background image, you'll get a gentle glow around the selected image now. There's also a horizontal scroll bar, if the number of images listed are too much to fit. ** changes on alpha at

May 19

  • Made a new bitrate option called &maxbandwidth, which differs from other commands as it leverages a chromium (chrome/edge/brave/electron) feature to judge the available bandwidth of a sender's connection. Passing a value to it as the sender (a percentage; 1 to 100 ideally), you can try to ensure the connection never uses more than that amount of the available reported bandwidth. (on alpha) So the notion is, if you want to set the invite link bitrate to 50-mbps, but one guest only has only a 20-mbps connection, &maxbandwidth=80 will try to limit the bitrate to around 16-mbps. I sometimes will tell people to set the bit rate to about 80% of what their connection can allow, as higher than that can result in some frame stutter when there is packet loss, since the connection lacks headroom to recover. This command will try to do it automatically, for all the viewers of a stream. My goal here is to use it with the mixer or stats app, so eSports users can crank out high bitrates with less tinkering per guest. I have no idea how well it will work in practice so far.
  • Fixed an issue where the director's mic audio could cut out after stopping the screen share, depending on how the screen-share was cancelled. - added &showall (or &style=7), which will include non-media-based push connections as video elements in a group room. This can include guests that joined without audio/video, directors, or a data-only connection, like maybe MIDI-output source. - to help avoid some types of connections showing up when using &showall, I've also added a &nopush mode, which blocks outbound publishing connections. This acts a bit like a &scene=1 link, so unless &showall is added, you'll need to use the IFRAME API to show/hide videos in it. (also just on alpha atm)

May 16

  • Stats for Meshcast will now appear in the director's scene stats section and the new stats page; by request
    (unlike normal stats, these Meshcast stats are just for the meshcast ingest, and not for the re-broadcast to the viewers. it also means you will see the meshcast stats even if no viewer/scene is yet connected.)
  • You can now also close the scene-options section, but have the stats stay visible (if active), as a director now also. (freeing up some space)

May 15

  • Beta updated with all recent updates and new mixer updates. Find it at:

May 14

  • I now try to alert the user when they have disabled webRTC; some privacy extensions or nanny-guard software might do it in a way that I can detect.

May 11

  • &remote, if used on a push link without a password added, it will now allow the remote viewer limited control (hangup, focus, zoom, detailed stats), even if they don't have &remote added to their URL also.
  • When using &remote, the option to "reload" the remote browser is now available, so you can potentially reload a remote unattended session that contains &autostart&webcam
    ** all changes on alpha @

May 8

  • Had a request to add mirror + flipping of video itself, rather than just via CSS. (as full-screen support was needed). I already had &effects=2 for mirroring the actual video itself, so I've added two more modes that can flip and flip+mirror. Might be useful for teleprompter work. flips flips + mirrors mirrors
  • I've added experimental support for local Media Recordings to iPhone/iPad devices. (&record may work now, etc)
  • The iPad/IPhone needs to have "MediaRecorder" enabled in its "experimental webkit features" Safari settings section
  • The user will have to click "download" once the recording has finished to actual save the file -- The resulting file is still a webM file, which the iPhone itself won't be able to play, but will play fine elsewhere.
  • I've included numerous pop-up warning messages to ensure the 'experimental' part is communicated
    ** on (all current code is up to date on beta)
  • &bgimage= can be used to set the default image avatar, when using &style=0 or &style=6. This only impacts what the person with the parameter added sees and must be either a URL or a base64 data image/SVG. URL-encoded values. on alpha ie:
  • &controls=0 [off/false] or &nocontrols, will force hide the video control bar. (on local dev atm)
  • Added the option to set a dedicated hold-to-talk key to VDO.Ninja; CTRL+M can work in place of this still by default, but this lets you set a custom combo/key that doesn't act as a mute toggle at all (if just tapped accidentally) ** This is on alpha

May 5

  • When using the &remote control option, the viewer can now remotely hang-up the sender via the right-click menu. The sender needs to remote control enabled for this to work of course. ** on local dev, coming to beta soon.

May 4

  • When you "full screen" a video using the native browser-full screen button, it will now behave the same way as the full-window solo button now. (increases the resolution of the target video, and lowers the bitrate of the others, now hidden, videos.). * on beta/dev branches

May 3

  • Made &totalbitrate (&tb) set both &totalscenebitrate and &totalroombitrate flags. Not quite sure how well it will work, but since a scene and a guest are exclusive possibilities, it's a bit of a flexible way to just learn one flag to do it all, as I realize all the options can get confusing. &trb and &tsb limit the total incoming bitrate, dividing up the bandwidth available to each video being played back. There are nuances in differences, with the main one being &trb is for a guest link and &tsb is for a scene/view link. (on local dev for now, pending more testing)
  • Added another security option, for those concerned about random spying of their streams. Add &prompt to the push link to enable. (or &approve/&validate) What it is: After a new peer viewer connection is established, but before the video/audio streams start getting sent to that new viewer, a prompt will appear asking the publisher if they wish to send their stream to that viewer. If they say no, the remote viewer is disconnected and no video/audio is sent to them. If they have &label=xxx added to their view link, that label will appear as the display name. Otherwise, if no label is available, a random ID representing that connection is shown. There's nothing stopping a disconnected viewer from re-joining and re-asking, causing some grief, and spoofing an identify isn't too hard, but it gives you some control and warning to block unexpected viewers. In the future, I can add this control to the director, rather than just the senders, and add additional ways to check identities. For now though, it's a start.
    ** on for testing

May 2

  • Added graphs to the director room; one graph for each scene a guest is connected to. If video isn't active/visible, the bitrate should be zero, implying VDO.Ninja has it paused/disabled, but on standby. You can see the graphs via the "scene stats" button. Toggling the button will enable and disable the stats.
  • The graph is color coded; red/yellow implies packet loss, but otherwise green. Currently the graph is capped to like 4-mbps; higher than that isn't display atm.
    ** alpha updated. Test it out at
  • Fixed a more recent bug in VDO.Ninja where the special &sstype=3 screen share mode did not work as solo links; stats for it were not always cleaned up either, so that's fixed too. (on dev)
  • Added manual-input fields for the camera/audio setting sliders. Both for director + push links. You can enter by hand values, rather than using the sliders. Also made "aspect ratio" and "frame rate" available options. ** on
Copy link