Initial commit
Dieser Commit ist enthalten in:
318
browser/video_stealth_enhancement.py
Normale Datei
318
browser/video_stealth_enhancement.py
Normale Datei
@ -0,0 +1,318 @@
|
||||
# Video Stealth Enhancement Module
|
||||
"""
|
||||
Erweiterte Video-spezifische Stealth-Maßnahmen für Instagram DRM-Schutz
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
logger = logging.getLogger("video_stealth_enhancement")
|
||||
|
||||
class VideoStealthEnhancement:
|
||||
"""Video-spezifische Anti-Detection und DRM-Schutz"""
|
||||
|
||||
def __init__(self, context: Any):
|
||||
self.context = context
|
||||
|
||||
def apply_video_stealth(self) -> None:
|
||||
"""Wendet erweiterte Video-Stealth-Maßnahmen an"""
|
||||
|
||||
# 1. DRM und Widevine Capability Spoofing
|
||||
drm_script = """
|
||||
() => {
|
||||
// Enhanced Widevine DRM Support
|
||||
if (!navigator.requestMediaKeySystemAccess) {
|
||||
navigator.requestMediaKeySystemAccess = function(keySystem, supportedConfigurations) {
|
||||
if (keySystem === 'com.widevine.alpha') {
|
||||
return Promise.resolve({
|
||||
keySystem: 'com.widevine.alpha',
|
||||
getConfiguration: () => ({
|
||||
initDataTypes: ['cenc'],
|
||||
audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}],
|
||||
videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}],
|
||||
distinctiveIdentifier: 'optional',
|
||||
persistentState: 'optional'
|
||||
}),
|
||||
createMediaKeys: () => Promise.resolve({
|
||||
createSession: () => ({
|
||||
addEventListener: () => {},
|
||||
generateRequest: () => Promise.resolve(),
|
||||
update: () => Promise.resolve(),
|
||||
close: () => Promise.resolve()
|
||||
})
|
||||
})
|
||||
});
|
||||
}
|
||||
return Promise.reject(new Error('KeySystem not supported'));
|
||||
};
|
||||
}
|
||||
|
||||
// EME (Encrypted Media Extensions) Support
|
||||
Object.defineProperty(HTMLMediaElement.prototype, 'canPlayType', {
|
||||
value: function(type) {
|
||||
const supportedTypes = {
|
||||
'video/mp4; codecs="avc1.42E01E"': 'probably',
|
||||
'video/mp4; codecs="avc1.4D4015"': 'probably',
|
||||
'video/webm; codecs="vp8"': 'probably',
|
||||
'video/webm; codecs="vp9"': 'probably',
|
||||
'audio/mp4; codecs="mp4a.40.2"': 'probably',
|
||||
'audio/webm; codecs="opus"': 'probably'
|
||||
};
|
||||
return supportedTypes[type] || 'maybe';
|
||||
}
|
||||
});
|
||||
|
||||
// Enhanced Media Capabilities
|
||||
if (!navigator.mediaCapabilities) {
|
||||
navigator.mediaCapabilities = {
|
||||
decodingInfo: function(config) {
|
||||
return Promise.resolve({
|
||||
supported: true,
|
||||
smooth: true,
|
||||
powerEfficient: true
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
# 2. Video Element Enhancement
|
||||
video_element_script = """
|
||||
() => {
|
||||
// Enhanced Video Element Support
|
||||
const originalCreateElement = document.createElement;
|
||||
document.createElement = function(tagName) {
|
||||
const element = originalCreateElement.call(this, tagName);
|
||||
|
||||
if (tagName.toLowerCase() === 'video') {
|
||||
// Override video properties for better compatibility
|
||||
Object.defineProperty(element, 'webkitDisplayingFullscreen', {
|
||||
get: () => false,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
Object.defineProperty(element, 'webkitSupportsFullscreen', {
|
||||
get: () => true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
Object.defineProperty(element, 'webkitDecodedFrameCount', {
|
||||
get: () => Math.floor(Math.random() * 1000) + 100,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
Object.defineProperty(element, 'webkitDroppedFrameCount', {
|
||||
get: () => Math.floor(Math.random() * 10),
|
||||
configurable: true
|
||||
});
|
||||
|
||||
// Enhanced autoplay support
|
||||
Object.defineProperty(element, 'autoplay', {
|
||||
get: function() { return this._autoplay || false; },
|
||||
set: function(value) { this._autoplay = value; },
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
|
||||
return element;
|
||||
};
|
||||
|
||||
// User Activation API (required for autoplay)
|
||||
if (!navigator.userActivation) {
|
||||
Object.defineProperty(navigator, 'userActivation', {
|
||||
get: () => ({
|
||||
hasBeenActive: true,
|
||||
isActive: true
|
||||
}),
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
# 3. Enhanced Media Devices
|
||||
media_devices_script = """
|
||||
() => {
|
||||
// Enhanced MediaDevices for Instagram
|
||||
if (navigator.mediaDevices) {
|
||||
const originalEnumerateDevices = navigator.mediaDevices.enumerateDevices;
|
||||
navigator.mediaDevices.enumerateDevices = function() {
|
||||
return Promise.resolve([
|
||||
{
|
||||
deviceId: 'default',
|
||||
kind: 'audioinput',
|
||||
label: 'Default - Mikrofon (Realtek High Definition Audio)',
|
||||
groupId: 'group_audio_input'
|
||||
},
|
||||
{
|
||||
deviceId: 'communications',
|
||||
kind: 'audioinput',
|
||||
label: 'Kommunikation - Mikrofon (Realtek High Definition Audio)',
|
||||
groupId: 'group_audio_input'
|
||||
},
|
||||
{
|
||||
deviceId: 'default',
|
||||
kind: 'audiooutput',
|
||||
label: 'Standard - Lautsprecher (Realtek High Definition Audio)',
|
||||
groupId: 'group_audio_output'
|
||||
},
|
||||
{
|
||||
deviceId: 'communications',
|
||||
kind: 'audiooutput',
|
||||
label: 'Kommunikation - Lautsprecher (Realtek High Definition Audio)',
|
||||
groupId: 'group_audio_output'
|
||||
},
|
||||
{
|
||||
deviceId: 'video_device_1',
|
||||
kind: 'videoinput',
|
||||
label: 'HD-Webcam (USB)',
|
||||
groupId: 'group_video_input'
|
||||
}
|
||||
]);
|
||||
};
|
||||
|
||||
// Enhanced getUserMedia support
|
||||
if (!navigator.mediaDevices.getUserMedia) {
|
||||
navigator.mediaDevices.getUserMedia = function(constraints) {
|
||||
return Promise.resolve({
|
||||
getTracks: () => [],
|
||||
getAudioTracks: () => [],
|
||||
getVideoTracks: () => [],
|
||||
addTrack: () => {},
|
||||
removeTrack: () => {},
|
||||
addEventListener: () => {},
|
||||
removeEventListener: () => {}
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
# 4. Instagram-spezifische Video Fixes
|
||||
instagram_video_script = """
|
||||
() => {
|
||||
// Instagram-specific video enhancements
|
||||
|
||||
// Simulate proper video loading behavior
|
||||
const originalFetch = window.fetch;
|
||||
window.fetch = function(input, init) {
|
||||
const url = typeof input === 'string' ? input : input.url;
|
||||
|
||||
// Enhance video CDN requests with proper headers
|
||||
if (url.includes('instagram.com') && (url.includes('.mp4') || url.includes('video'))) {
|
||||
const enhancedInit = {
|
||||
...init,
|
||||
headers: {
|
||||
...init?.headers,
|
||||
'Accept': 'video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5',
|
||||
'Accept-Encoding': 'identity;q=1, *;q=0',
|
||||
'Accept-Language': 'de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7',
|
||||
'Cache-Control': 'no-cache',
|
||||
'Pragma': 'no-cache',
|
||||
'Range': 'bytes=0-',
|
||||
'Sec-Fetch-Dest': 'video',
|
||||
'Sec-Fetch-Mode': 'no-cors',
|
||||
'Sec-Fetch-Site': 'cross-site'
|
||||
}
|
||||
};
|
||||
return originalFetch.call(this, input, enhancedInit);
|
||||
}
|
||||
|
||||
return originalFetch.apply(this, arguments);
|
||||
};
|
||||
|
||||
// Override video error handling
|
||||
const originalAddEventListener = HTMLVideoElement.prototype.addEventListener;
|
||||
HTMLVideoElement.prototype.addEventListener = function(type, listener, options) {
|
||||
if (type === 'error' || type === 'abort') {
|
||||
// Wrap error listener to prevent video error displays
|
||||
const wrappedListener = function(event) {
|
||||
console.debug('AccountForger: Video event intercepted:', type);
|
||||
// Prevent error propagation for DRM-related issues
|
||||
if (event.target && event.target.error && event.target.error.code === 3) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
return listener.call(this, event);
|
||||
};
|
||||
return originalAddEventListener.call(this, type, wrappedListener, options);
|
||||
}
|
||||
return originalAddEventListener.call(this, type, listener, options);
|
||||
};
|
||||
|
||||
// Simulate proper video metrics
|
||||
Object.defineProperty(HTMLVideoElement.prototype, 'buffered', {
|
||||
get: function() {
|
||||
return {
|
||||
length: 1,
|
||||
start: () => 0,
|
||||
end: () => this.duration || 30
|
||||
};
|
||||
},
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
"""
|
||||
|
||||
# Alle Skripte anwenden
|
||||
scripts = [drm_script, video_element_script, media_devices_script, instagram_video_script]
|
||||
|
||||
for script in scripts:
|
||||
try:
|
||||
self.context.add_init_script(script)
|
||||
logger.debug("Video stealth script applied successfully")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to apply video stealth script: {e}")
|
||||
|
||||
logger.info("Video stealth enhancement applied - DRM and Instagram compatibility enabled")
|
||||
|
||||
def validate_video_capabilities(self, page: Any) -> Dict[str, bool]:
|
||||
"""Validiert Video-Capabilities des Browsers"""
|
||||
try:
|
||||
result = page.evaluate("""
|
||||
() => {
|
||||
const results = {
|
||||
widevine_support: false,
|
||||
media_devices: false,
|
||||
video_codecs: false,
|
||||
user_activation: false,
|
||||
autoplay_policy: false
|
||||
};
|
||||
|
||||
// Check Widevine support
|
||||
if (navigator.requestMediaKeySystemAccess) {
|
||||
results.widevine_support = true;
|
||||
}
|
||||
|
||||
// Check MediaDevices
|
||||
if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
|
||||
results.media_devices = true;
|
||||
}
|
||||
|
||||
// Check Video Codecs
|
||||
const video = document.createElement('video');
|
||||
if (video.canPlayType('video/mp4; codecs="avc1.42E01E"') === 'probably') {
|
||||
results.video_codecs = true;
|
||||
}
|
||||
|
||||
// Check User Activation
|
||||
if (navigator.userActivation && navigator.userActivation.hasBeenActive) {
|
||||
results.user_activation = true;
|
||||
}
|
||||
|
||||
// Check Autoplay Policy
|
||||
results.autoplay_policy = true; // Always report as supported
|
||||
|
||||
return results;
|
||||
}
|
||||
""")
|
||||
|
||||
logger.info(f"Video capabilities validation: {result}")
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Video capabilities validation failed: {e}")
|
||||
return {}
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren