Guest User

fuckme.py

a guest
Apr 19th, 2026
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.04 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. """
  3. AudioChan Stream Capture Tool (Manual Mode Only)
  4. Uses Playwright to capture stream URLs and full headers (including HttpOnly cookies).
  5. Generates the robust FFmpeg command for manual copy-pasting.
  6. """
  7. import argparse
  8. import asyncio
  9. from playwright.async_api import async_playwright
  10. import os
  11. import re
  12. import sys
  13.  
  14. # Path to store browser session (cookies, etc.) so you don't have to login every time
  15. USER_DATA_DIR = os.path.join(os.getcwd(), 'playwright_data')
  16.  
  17. async def capture_stream_manual(url):
  18. print(f"šŸš€ Launching browser for: {url}")
  19. print(f"šŸ“‚ User Data Dir: {USER_DATA_DIR}")
  20.  
  21. async with async_playwright() as p:
  22. # Launch persistent context to save login state
  23. context = await p.chromium.launch_persistent_context(
  24. user_data_dir=USER_DATA_DIR,
  25. headless=False, # Change if cloudflare is an issue
  26. channel="chrome", # Try to use installed Chrome if available for better realism
  27. args=[
  28. '--disable-blink-features=AutomationControlled', # Hide automation flag
  29. ]
  30. )
  31.  
  32. page = await context.new_page()
  33.  
  34. # storage for captured info
  35. stream_info = {
  36. 'url': None,
  37. 'headers': None
  38. }
  39.  
  40. # Event listener for requests
  41. async def handle_request(request):
  42. try:
  43. # Filter strictly for the stream URL
  44. if 'stream.audiochan.com' in request.url and '&st=' in request.url:
  45. print(f"\nāœ… CAPTURED STREAM REQUEST! (Updating...)")
  46. stream_info['url'] = request.url
  47. try:
  48. # This can sometimes fail if the request is closed too quickly
  49. stream_info['headers'] = await request.all_headers()
  50. except Exception as e:
  51. print(f"āš ļø Warning: Could not fetch full headers: {e}")
  52. # Fallback to basic headers if available, or just use what we have
  53. if not stream_info['headers']: # Only overwrite if we don't have good headers yet
  54. stream_info['headers'] = request.headers
  55. except Exception as e:
  56. # Catch-all for any other issues in the handler to prevent loop crash
  57. pass
  58.  
  59. page.on("request", handle_request)
  60.  
  61. try:
  62. print("ā³ Navigating to page...")
  63. await page.goto(url)
  64.  
  65. print("šŸ‘€ Waiting for stream to start... (Press Play on the page if needed)")
  66.  
  67. # Wait until we capture the stream AND it stabilizes
  68. stability_count = 0
  69. required_stability = 3
  70.  
  71. for _ in range(60):
  72. if stream_info['url'] and stream_info['headers']:
  73. stability_count += 1
  74. print(f" Stream detected... stabilizing ({stability_count}/{required_stability})")
  75. if stability_count >= required_stability:
  76. break
  77. else:
  78. stability_count = 0 # Reset if lost (unlikely but good safety)
  79.  
  80. await asyncio.sleep(1)
  81.  
  82. if stream_info['url'] and stream_info['headers']:
  83. title = await page.title()
  84.  
  85. # Sanitize title: Replace invalid Windows filename characters with underscore
  86. # Invalid characters for Windows filenames: < > : " / \ | ? *
  87. invalid_chars = r'[<>:"/\\|?*]'
  88. safe_title = re.sub(invalid_chars, '_', title).strip()
  89. # Also remove any trailing periods or spaces that Windows dislikes
  90. safe_title = re.sub(r'[ .]+$', '', safe_title)
  91.  
  92. print("\n" + "="*80)
  93. print("šŸŽ‰ SUCCESS! Stream info captured.")
  94. print("="*80)
  95.  
  96. # Construct FFmpeg Command
  97. headers_dict = stream_info['headers']
  98.  
  99. # Format headers for FFmpeg (-headers "Key: Value\r\nKey: Value\r\n")
  100. ffmpeg_headers = ""
  101.  
  102. # Critical headers
  103. keys_to_keep = ['user-agent', 'referer', 'cookie', 'accept', 'accept-language', 'origin']
  104.  
  105. for key, value in headers_dict.items():
  106. if key.lower() in keys_to_keep:
  107. # Escape double quotes inside header values with a backslash
  108. safe_val = value.replace('"', '\\"')
  109. # Capitalize keys nicely
  110. nice_key = key.title()
  111. ffmpeg_headers += f"{nice_key}: {safe_val}\r\n"
  112.  
  113. # Add connection keep-alive if missing
  114. if 'connection' not in headers_dict:
  115. ffmpeg_headers += "Connection: keep-alive\r\n"
  116.  
  117. # Construct the full command
  118. # Note: We use .mp4 container for better compatibility with streams
  119. output_filename = f"{safe_title}.mp4"
  120.  
  121. # String version for manual copy-pasting
  122. cmd_str = f'ffmpeg -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5 -headers "{ffmpeg_headers}" -i "{stream_info["url"]}" -c copy "{output_filename}"'
  123.  
  124. print("\nšŸ“‹ FFmpeg Command (Auto-Generated):")
  125. print("-" * 20)
  126. print(cmd_str)
  127. print("-" * 20)
  128. print("\nāš ļø Copy the command above and run it in your terminal.")
  129. else:
  130. print("\nāŒ Timeout: Stream request not found.")
  131. print("Did you play the audio? Is the site asking for login?")
  132.  
  133. except Exception as e:
  134. print(f"\nāŒ Error: {e}")
  135.  
  136. finally:
  137. # Safely close the browser context
  138. try:
  139. if context.pages: # Simple check if it might still be open
  140. print("\nClosing browser...")
  141. await context.close()
  142. except Exception as e:
  143. # Ignore errors during shutdown (e.g., Target closed, Loop closed)
  144. pass
  145.  
  146. def main():
  147. if sys.platform == 'win32':
  148. asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
  149.  
  150. parser = argparse.ArgumentParser(description="AudioChan Stream Capture Tool (Manual Mode Only)")
  151. parser.add_argument('url', nargs='?', help='The URL of the AudioChan page (optional)')
  152. args = parser.parse_args()
  153.  
  154. target_url = args.url
  155.  
  156. # Interactive URL Input if not provided
  157. if not target_url:
  158. print("Enter the AudioChan URL:")
  159. target_url = input("> ").strip()
  160. if not target_url:
  161. print("Error: No URL provided. Exiting.")
  162. return
  163.  
  164. asyncio.run(capture_stream_manual(target_url))
  165.  
  166. if __name__ == "__main__":
  167. main()
  168.  
Advertisement
Add Comment
Please, Sign In to add comment