WebRTC Spoofer

WebRTC Spoofer (Logitech Brio 4K & Blue Yeti Mic as Virtual Matrix 4) with Video & Audio Requested Good For Ome.tv an Uhmegle

  1. // ==UserScript==
  2. // @name WebRTC Spoofer
  3. // @namespace http://tampermonkey.net/
  4. // @version 8.0
  5. // @description WebRTC Spoofer (Logitech Brio 4K & Blue Yeti Mic as Virtual Matrix 4) with Video & Audio Requested Good For Ome.tv an Uhmegle
  6. // @author Cxsmo
  7. // @match *://*/*
  8. // @grant none
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (function () {
  13. 'use strict';
  14.  
  15. // Forcefully overwrite original methods
  16. const originalEnumerateDevices = navigator.mediaDevices.enumerateDevices.bind(navigator.mediaDevices);
  17. const originalGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);
  18.  
  19. // Webcam Emulation (Logitech Brio 4K)
  20. const brioProperties = {
  21. deviceId: "logitech-brio-4k-webcam-id", // Fake device ID
  22. groupId: "logitech-brio-group-id", // Fake group ID
  23. label: "Logitech BRIO 4K Stream Edition", // Fake webcam label
  24. kind: "videoinput",
  25. capabilities: {
  26. width: 3840, // 4K resolution
  27. height: 2160,
  28. frameRate: 60, // 60 FPS
  29. aspectRatio: 16 / 9,
  30. colorDepth: 10, // 10-bit color depth for higher-quality video
  31. },
  32. };
  33.  
  34. // Microphone Emulation (Blue Yeti as Virtual Matrix 4)
  35. const blueYetiProperties = {
  36. deviceId: "blue-yeti-mic-id", // Fake device ID (for the Virtual Matrix 4 mic)
  37. groupId: "blue-yeti-group-id", // Fake group ID
  38. label: "Blue Yeti USB Microphone", // Fake mic label
  39. kind: "audioinput",
  40. capabilities: {
  41. sampleRate: 48000, // 48kHz sample rate
  42. channelCount: 2, // Stereo sound
  43. volume: 100, // Maximum volume
  44. },
  45. };
  46.  
  47. // Override enumerateDevices to ensure fake device data
  48. navigator.mediaDevices.enumerateDevices = async function () {
  49. const devices = await originalEnumerateDevices();
  50.  
  51. // Force overriding the device label and IDs for video and audio devices
  52. return devices.map((device) => {
  53. if (device.kind === "videoinput") {
  54. // Force webcam properties (Logitech Brio 4K)
  55. return {
  56. ...device,
  57. deviceId: brioProperties.deviceId,
  58. groupId: brioProperties.groupId,
  59. label: brioProperties.label,
  60. };
  61. } else if (device.kind === "audioinput") {
  62. // Force microphone properties to only show the Blue Yeti mic (Virtual Matrix 4)
  63. return {
  64. ...device,
  65. deviceId: blueYetiProperties.deviceId,
  66. groupId: blueYetiProperties.groupId,
  67. label: blueYetiProperties.label,
  68. };
  69. }
  70. return device;
  71. });
  72. };
  73.  
  74. // Override getUserMedia to ensure requested constraints match fake properties
  75. navigator.mediaDevices.getUserMedia = function (constraints) {
  76. // Handle video constraints (Logitech Brio 4K)
  77. if (!constraints.video && !constraints.audio) {
  78. // If neither audio nor video is requested, default to requesting both
  79. constraints.video = {
  80. width: { ideal: brioProperties.capabilities.width },
  81. height: { ideal: brioProperties.capabilities.height },
  82. frameRate: { ideal: brioProperties.capabilities.frameRate },
  83. facingMode: "user", // Optional: set to front-facing camera
  84. };
  85. } else if (constraints.video) {
  86. // If video is requested, apply the Logitech Brio-like settings
  87. constraints.video = {
  88. width: { ideal: brioProperties.capabilities.width },
  89. height: { ideal: brioProperties.capabilities.height },
  90. frameRate: { ideal: brioProperties.capabilities.frameRate },
  91. facingMode: "user", // Optional: set to front-facing camera
  92. ...constraints.video,
  93. };
  94. }
  95.  
  96. // Handle audio constraints (Blue Yeti Mic as Virtual Matrix 4)
  97. if (!constraints.audio) {
  98. // If audio is not requested, apply default Blue Yeti settings
  99. constraints.audio = {
  100. deviceId: { ideal: blueYetiProperties.deviceId },
  101. channelCount: { ideal: blueYetiProperties.capabilities.channelCount },
  102. sampleRate: { ideal: blueYetiProperties.capabilities.sampleRate },
  103. volume: blueYetiProperties.capabilities.volume,
  104. };
  105. } else if (constraints.audio) {
  106. // If audio is requested, apply Blue Yeti microphone settings
  107. constraints.audio = {
  108. deviceId: { ideal: blueYetiProperties.deviceId },
  109. channelCount: { ideal: blueYetiProperties.capabilities.channelCount },
  110. sampleRate: { ideal: blueYetiProperties.capabilities.sampleRate },
  111. volume: blueYetiProperties.capabilities.volume,
  112. ...constraints.audio,
  113. };
  114. }
  115.  
  116. return originalGetUserMedia(constraints);
  117. };
  118.  
  119. // Override getSettings for MediaStreamTrack to provide fake settings for streams
  120. const originalGetSettings = MediaStreamTrack.prototype.getSettings;
  121. MediaStreamTrack.prototype.getSettings = function () {
  122. const settings = originalGetSettings.call(this);
  123. return {
  124. ...settings,
  125. width: brioProperties.capabilities.width,
  126. height: brioProperties.capabilities.height,
  127. frameRate: brioProperties.capabilities.frameRate,
  128. aspectRatio: brioProperties.capabilities.aspectRatio,
  129. colorDepth: brioProperties.capabilities.colorDepth,
  130. sampleRate: blueYetiProperties.capabilities.sampleRate,
  131. channelCount: blueYetiProperties.capabilities.channelCount,
  132. volume: blueYetiProperties.capabilities.volume,
  133. };
  134. };
  135.  
  136. // Add a check for the WebRTC environment and log the details
  137. function checkWebRTC() {
  138. if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
  139. console.log("WebRTC is supported on this page.");
  140. } else {
  141. console.warn("WebRTC is not supported. Some features may not work.");
  142. }
  143. }
  144.  
  145. // Check WebRTC support on page load
  146. checkWebRTC();
  147.  
  148. // Add validation to block resolution 640x360 and only allow 1080p (1920x1080) or 4K (3840x2160)
  149. const originalMediaTrackConstraints = MediaStreamTrack.prototype.getSettings;
  150. MediaStreamTrack.prototype.getSettings = function () {
  151. const settings = originalMediaTrackConstraints.call(this);
  152. // Block 640x360 resolution by not allowing it in constraints
  153. if (settings.width === 640 && settings.height === 360) {
  154. console.warn("Blocked 640x360 resolution.");
  155. return {
  156. ...settings,
  157. width: 1920, // Force to 1080p resolution
  158. height: 1080,
  159. };
  160. }
  161. // If the resolution is not 640x360, we allow 1080p (1920x1080) or 4K (3840x2160)
  162. if (settings.width <= 1920 && settings.height <= 1080) {
  163. console.log("Resolution allowed:", settings.width, settings.height);
  164. return settings;
  165. } else {
  166. // If the resolution is higher than 1080p, force to 4K resolution
  167. return {
  168. ...settings,
  169. width: 3840, // Force to Brio 4K resolution
  170. height: 2160,
  171. };
  172. }
  173. };
  174.  
  175. // Log the result to make sure the spoofing works
  176. console.log("WebRTC Spoofer: Logitech Brio 4K webcam and Blue Yeti USB microphone (Virtual Matrix 4) emulation active.");
  177. })();