KiWA001 commited on
Commit
8a922b7
·
1 Parent(s): 1048740

feat: add audio support for browser portal and audio captchas

Browse files

Audio Support:
- Added browser args for audio autoplay and media stream
- Enabled microphone and camera permissions in browser context
- Added AudioContext wrapper for proper audio initialization
- Audio elements can now autoplay without user gesture
- Support for audio captchas (reCAPTCHA audio challenges)
- Media stream permissions for WebRTC applications

Browser Args Added:
- --autoplay-policy=no-user-gesture-required
- --use-fake-ui-for-media-stream
- --use-fake-device-for-media-stream
- --enable-features=AudioServiceOutOfProcess
- --disable-features=AudioServiceSandbox

Stealth Scripts Added:
- AudioContext constructor wrapper
- HTMLMediaElement.play() override for autoplay
- Proper destination channel count mocking

This enables:
- Audio captcha solving
- Video/audio playback in browser
- WebRTC applications
- Full multimedia browser experience

Files changed (1) hide show
  1. browser_portal.py +35 -3
browser_portal.py CHANGED
@@ -126,7 +126,7 @@ class BrowserPortal:
126
 
127
  self.playwright = await async_playwright().start()
128
 
129
- # Maximum stealth args
130
  args = [
131
  "--disable-blink-features=AutomationControlled",
132
  "--disable-features=IsolateOrigins,site-per-process",
@@ -147,6 +147,12 @@ class BrowserPortal:
147
  "--no-default-browser-check",
148
  "--password-store=basic",
149
  "--use-mock-keychain",
 
 
 
 
 
 
150
  ]
151
 
152
  # Build browser launch options
@@ -161,7 +167,7 @@ class BrowserPortal:
161
 
162
  self.browser = await self.playwright.chromium.launch(**launch_options)
163
 
164
- # Use a real Chrome user agent
165
  self.context = await self.browser.new_context(
166
  viewport=self.config.viewport,
167
  user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
@@ -169,7 +175,7 @@ class BrowserPortal:
169
  timezone_id="America/New_York",
170
  color_scheme="light",
171
  geolocation={"latitude": 40.7128, "longitude": -74.0060},
172
- permissions=["geolocation"],
173
  java_script_enabled=True,
174
  has_touch=False,
175
  is_mobile=False,
@@ -254,6 +260,32 @@ class BrowserPortal:
254
  }
255
  return getParameter.call(this, parameter);
256
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
  """)
258
 
259
  self.page = await self.context.new_page()
 
126
 
127
  self.playwright = await async_playwright().start()
128
 
129
+ # Maximum stealth args with audio support
130
  args = [
131
  "--disable-blink-features=AutomationControlled",
132
  "--disable-features=IsolateOrigins,site-per-process",
 
147
  "--no-default-browser-check",
148
  "--password-store=basic",
149
  "--use-mock-keychain",
150
+ # Audio support
151
+ "--autoplay-policy=no-user-gesture-required",
152
+ "--use-fake-ui-for-media-stream",
153
+ "--use-fake-device-for-media-stream",
154
+ "--enable-features=AudioServiceOutOfProcess",
155
+ "--disable-features=AudioServiceSandbox",
156
  ]
157
 
158
  # Build browser launch options
 
167
 
168
  self.browser = await self.playwright.chromium.launch(**launch_options)
169
 
170
+ # Use a real Chrome user agent with audio permissions
171
  self.context = await self.browser.new_context(
172
  viewport=self.config.viewport,
173
  user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
 
175
  timezone_id="America/New_York",
176
  color_scheme="light",
177
  geolocation={"latitude": 40.7128, "longitude": -74.0060},
178
+ permissions=["geolocation", "microphone", "camera"],
179
  java_script_enabled=True,
180
  has_touch=False,
181
  is_mobile=False,
 
260
  }
261
  return getParameter.call(this, parameter);
262
  };
263
+
264
+ // Audio Context support for audio captchas
265
+ if (window.AudioContext || window.webkitAudioContext) {
266
+ const OriginalAudioContext = window.AudioContext || window.webkitAudioContext;
267
+ window.AudioContext = function() {
268
+ const instance = new OriginalAudioContext();
269
+ // Ensure destination is properly connected
270
+ if (instance.destination) {
271
+ Object.defineProperty(instance.destination, 'maxChannelCount', {
272
+ get: () => 2
273
+ });
274
+ }
275
+ return instance;
276
+ };
277
+ window.AudioContext.prototype = OriginalAudioContext.prototype;
278
+ if (window.webkitAudioContext) {
279
+ window.webkitAudioContext = window.AudioContext;
280
+ }
281
+ }
282
+
283
+ // Allow audio autoplay
284
+ const originalAudioPlay = HTMLMediaElement.prototype.play;
285
+ HTMLMediaElement.prototype.play = function() {
286
+ this.muted = false;
287
+ return originalAudioPlay.apply(this, arguments);
288
+ };
289
  """)
290
 
291
  self.page = await self.context.new_page()