Advertisement
hdpcnnbn

Huya-Player.py

Feb 13th, 2025
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.51 KB | Source Code | 0 0
  1. # save this file with a .py extension, run using using python from a command prompt > python filename.py
  2.  
  3. import importlib
  4. import subprocess
  5. import os
  6. import sys
  7. import time
  8. import re
  9. import locale
  10. import random
  11. import hashlib
  12.  
  13.  
  14. def check_dependencies():
  15.     global BeautifulSoup, GoogleTranslator, requests
  16.  
  17.     # Check for Python packages
  18.     required_packages = ['bs4', 'deep_translator', 'requests']
  19.     print(f"Checking required packages {required_packages}")
  20.     for package in required_packages:
  21.         try:
  22.             if package == 'bs4':
  23.                 bs4 = importlib.import_module(package)
  24.                 global BeautifulSoup
  25.                 BeautifulSoup = bs4.BeautifulSoup
  26.             elif package == 'deep_translator':
  27.                 deep_translator = importlib.import_module(package)
  28.                 global GoogleTranslator
  29.                 GoogleTranslator = deep_translator.GoogleTranslator
  30.             elif package == 'requests':
  31.                 global requests
  32.                 requests = importlib.import_module(package)
  33.         except ImportError:
  34.             print(f"Error: {package} is not installed. Please install it using pip: pip install {package}")
  35.             return False
  36.  
  37.     # Check for streamlink binary
  38.     print("Checking for streamlink binary")
  39.     try:
  40.         subprocess.run(['streamlink', '--version'], check=True, stdout=subprocess.DEVNULL)
  41.     except FileNotFoundError:
  42.         print("Error: streamlink is not installed. Please download and install it from https://streamlink.github.io/")
  43.         return False
  44.  
  45.     # Check for VLC player
  46.     print("Checking for VLC Player")
  47.     vlc_path = None
  48.     for path in os.environ['PATH'].split(os.pathsep):
  49.         vlc_path = os.path.join(path, 'vlc.exe')
  50.         if os.path.exists(vlc_path):
  51.             break
  52.     if vlc_path is None:
  53.         print("Error: VLC player is not installed. Please download and install it from https://www.videolan.org/vlc/")
  54.         return False
  55.  
  56.     return True
  57.  
  58.  
  59. class VersionCheck:
  60.     def __init__(self, url):
  61.         self.url = url
  62.         self.data = None
  63.         self.values = []
  64.         self.valid_versions = []
  65.         self.current_version = None
  66.         self.run()
  67.  
  68.     def fetch_latest(self):
  69.         try:
  70.             response = requests.get(self.url)
  71.             response.raise_for_status()
  72.             self.data = response.text
  73.         except requests.exceptions.RequestException as err:
  74.             print(f"Error fetching data: {err}")
  75.             self.data = None
  76.  
  77.     def is_valid_version_number(self, version_number):
  78.         # Check if the string is 32 characters long and only contains hexadecimal digits
  79.         pattern = re.compile(r"^[0-9a-f]{32}$")
  80.         return bool(pattern.match(version_number))
  81.  
  82.     def calculate_current_version(self):
  83.         # Open the current script and calculate its version
  84.         with open(__file__, 'rb') as f:
  85.             md5 = hashlib.md5()
  86.             while chunk := f.read(4096):
  87.                 md5.update(chunk)
  88.         self.current_version = md5.hexdigest()
  89.  
  90.     def process_versions(self):
  91.         if self.data is None:
  92.             print("Unable to find current version number.")
  93.             #sys.exit(1)
  94.        
  95.         self.values = [line.strip() for line in self.data.splitlines()]
  96.         self.valid_versions = [value for value in self.values if self.is_valid_version_number(value)]
  97.        
  98.         if not self.valid_versions:
  99.             print("No valid version numbers found.")
  100.             #sys.exit(1)
  101.  
  102.     def compare_versions(self):
  103.         # Calculate the current version
  104.         self.calculate_current_version()
  105.        
  106.         # Print the latest version
  107.         if self.values:
  108.             pass
  109.             #print(f"Latest Version Number {self.values[-1]}")  # Print the latest version
  110.         else:
  111.             print("No data available")
  112.        
  113.         # Compare the current version to the latest version
  114.         if self.is_valid_version_number(self.current_version) and self.valid_versions:
  115.             if self.current_version == self.valid_versions[-1]:
  116.                 print("The current script version is up to date.")
  117.             else:
  118.                 print(" The current script version is outdated.")
  119.                 print(f"Current script version: {self.current_version}")
  120.                 print(f"Latest version: {self.valid_versions[-1]}")
  121.         else:
  122.             print("Cannot compare versions.")
  123.  
  124.     def run(self):
  125.         self.fetch_latest()
  126.         self.process_versions()
  127.         self.compare_versions()
  128.  
  129.  
  130. # Get the current OS language
  131. lang = locale.getdefaultlocale()[0]
  132.  
  133. # Target streams
  134. STREAMS = [
  135.     # Snooker Streams.
  136.     "https://www.huya.com/20072620",
  137.     "https://www.huya.com/20072621",
  138.     "https://www.huya.com/18501408",
  139.     "https://www.huya.com/18501324",
  140.     "https://www.huya.com/17455465",
  141.     "https://www.huya.com/18501329",
  142.     "https://www.huya.com/18501166",
  143.     "https://www.huya.com/17611732",
  144.     # Other streams.
  145. ]
  146.  
  147. browser_headers = [
  148.     {
  149.         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36',
  150.         'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  151.         'Accept-Language': 'en-US,en;q=0.5',
  152.         'Accept-Encoding': 'gzip, deflate, br'
  153.     },
  154.     {
  155.         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0',
  156.         'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  157.         'Accept-Language': 'en-US,en;q=0.5',
  158.         'Accept-Encoding': 'gzip, deflate, br'
  159.     },
  160.     {
  161.         'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36',
  162.         'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  163.         'Accept-Language': 'en-US,en;q=0.5',
  164.         'Accept-Encoding': 'gzip, deflate, br'
  165.     }
  166. ]
  167.  
  168. RETRY_COUNT = 3
  169. RETRY_DELAY = 1
  170.  
  171. # Text variables (English)
  172. GETTING_TITLE = "Getting title for stream : {}"
  173. TRANSLATING_TITLE = "Translating Title {} = {}"
  174. AVAILABLE_TABLES_STATUS = "Available Tables & Status."
  175. ENTER_CHOICE = "Enter your choice ({} of {}) or {} to exit:"
  176. EXITING = "Exiting..."
  177. RETRYING = "retrying"
  178. INVALID_CHOICE = "Invalid choice. Please try again."
  179. AVAILABLE = "Available"
  180. OFFLINE = "offline"
  181. EXIT = "Exit"
  182. LOCAL_LANG = "Translate to"
  183. UPDATE_STREAMS_STATUS = "Update Stream Status "
  184.  
  185. STRIP_FROM_TITLE = [
  186.     "[",
  187.     "Live",
  188.     "broadcast",
  189.     "]",
  190.     "-",
  191.     ]
  192.  
  193. SORTBY_KEYWORDS = [
  194.     "table",
  195.     ]
  196.  
  197. # Create a dictionary to store translations
  198. translations = {}
  199.  
  200. def translate_text(text):
  201.     if text not in translations:
  202.         attempts = 0
  203.         translator = GoogleTranslator(source='auto', target=lang.split('_')[0])
  204.         while attempts < RETRY_COUNT:
  205.             try:
  206.                 translations[text] = translator.translate(text)
  207.                 return translations[text]
  208.             except Exception as e:
  209.                 attempts += 1
  210.                 if attempts < RETRY_COUNT:
  211.                     time.sleep(RETRY_DELAY)
  212.                 else:
  213.                     return f"Translation failed after {RETRY_COUNT} attempts. Please try again later."
  214.     else:
  215.         return translations[text]
  216.  
  217.  
  218. def get_stream_title(stream_url: str) -> str:
  219.     print(f"{translate_text(GETTING_TITLE).format(stream_url)} ", end='', flush=True)
  220.     for _ in range(RETRY_COUNT):  
  221.         try:
  222.             response = requests.get(stream_url, headers=BROWSER_HEADER)
  223.             soup = BeautifulSoup(response.text, 'html.parser')
  224.             title = soup.find('h2', id='J_roomTitle', class_='host-title')
  225.             if title:
  226.                 text = title.text.strip()
  227.                 translator = GoogleTranslator(source='auto', target=lang.split('_')[0])
  228.                 translation = translator.translate(text)
  229.                 print(f"{translate_text(TRANSLATING_TITLE).format(text, translation)} ")
  230.                 return translation
  231.             else:
  232.                 return ""
  233.         except requests.exceptions.RequestException as e:
  234.             print(f" {translate_text(RETRYING)} ")
  235.             time.sleep(RETRY_DELAY)  
  236.     return ""
  237.  
  238.  
  239. def check_stream(stream_url: str) -> bool:
  240.     try:
  241.         output = subprocess.run(['streamlink', stream_url, 'best', '--stream-url'], capture_output=True, text=True)
  242.         if output.returncode == 0:
  243.             return True
  244.         else:
  245.             if "No playable streams found on this URL" in output.stdout:
  246.                 return False
  247.             else:
  248.                 return False
  249.     except FileNotFoundError:
  250.         return False
  251.  
  252.  
  253. def build_stream_menu(streams: list) -> list:
  254.     menu = []
  255.     translated_sortby_keywords = [translate_text(keyword) for keyword in SORTBY_KEYWORDS]
  256.     for i, stream_url in enumerate(streams, start=1):
  257.         title = get_stream_title(stream_url)
  258.         for keyword in STRIP_FROM_TITLE:
  259.             title = re.sub(rf'(?i){re.escape(keyword)}', '', title)
  260.         keyword_matches = []
  261.         for keyword in translated_sortby_keywords:
  262.             match = re.search(rf'(?i)(-?)\s*{re.escape(keyword)}\s*(\d+)', title)
  263.             if match:
  264.                 table_str = match.group(0)
  265.                 title = table_str + title[:match.start()] + title[match.end():]
  266.                 keyword_matches.append((keyword, int(match.group(2))))
  267.  
  268.         status = translate_text(AVAILABLE) if check_stream(stream_url) else translate_text(OFFLINE)
  269.         menu.append((title.strip(), status, i, keyword_matches))
  270.  
  271.     def get_sort_key(x):
  272.         event_name = x[0]
  273.         for keyword, number in x[3]:
  274.             event_name = re.sub(rf'(?i)({re.escape(keyword)})\s*\d+', '', event_name).strip()
  275.         return (event_name.lower(), x[3])
  276.  
  277.     menu.sort(key=get_sort_key)
  278.     return [(x[0], x[1], x[2]) for x in menu]
  279.  
  280.  
  281. def display_menu(menu: list) -> None:
  282.     #os.system('cls' if os.name == 'nt' else 'clear')
  283.     while True:
  284.         print(f"{translate_text(AVAILABLE_TABLES_STATUS)}")
  285.         available_count = 0
  286.         for index, (title, status, original_index) in enumerate(menu, start=1):
  287.             if status == translate_text(AVAILABLE):
  288.                 available_count += 1
  289.                 print(f"{available_count}. {title.strip()} - {status}")
  290.             else:
  291.                 print(f" . {title.strip()} - {status}")
  292.         print(f"{available_count+1}. {translate_text(EXIT)}")
  293.         choice = input(f"{translate_text(ENTER_CHOICE).format(1, available_count, available_count+1)} ")
  294.         if choice == str(available_count+1) or choice.lower() == translate_text(EXIT).lower():
  295.             print(f"{translate_text(EXITING)}")
  296.             break
  297.         elif choice.isdigit() and 1 <= int(choice) <= available_count:
  298.             available_index = 0
  299.             for index, (title, status, original_index) in enumerate(menu, start=1):
  300.                 if status == translate_text(AVAILABLE):
  301.                     available_index += 1
  302.                     if available_index == int(choice):
  303.                         stream_url = STREAMS[menu[index-1][2] - 1]
  304.                         subprocess.run(['streamlink', f'--title={translate_text(menu[index-1][0])}', stream_url, 'best'])
  305.                         print(f"{translate_text(UPDATE_STREAMS_STATUS)}", end='', flush=True)
  306.                         for i, (title, status, original_index) in enumerate(menu):
  307.                             print(".", end='', flush=True)
  308.                             if original_index == menu[index-1][2]:
  309.                                 new_status = translate_text(AVAILABLE) if check_stream(stream_url) else translate_text(OFFLINE)
  310.                                 menu[i] = (title, new_status, original_index)
  311.                         print(f"\nDone.")
  312.                         time.sleep(4)
  313.                         os.system('cls' if os.name == 'nt' else 'clear')
  314.                         break
  315.         else:
  316.             print(translate_text(INVALID_CHOICE))
  317.  
  318.  
  319. def main():
  320.     VersionCheck("https://pastebin.com/raw/bHvTgHht")
  321.     print(f"{translate_text(LOCAL_LANG)} [{lang}]")
  322.     global BROWSER_HEADER
  323.     BROWSER_HEADER = random.choice(browser_headers)
  324.     print(f"Tonight Matthew I'm going to be\n {BROWSER_HEADER}\n")
  325.     menu = build_stream_menu(STREAMS)
  326.     display_menu(menu)
  327.  
  328. if __name__ == "__main__":
  329.     if not check_dependencies():
  330.         print("Please install the required dependencies and try again.")
  331.         sys.exit(1)
  332.     main()
  333.  
  334.  
Tags: huya
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement