import re import json from unidecode import unidecode import base64 m3u_file = "channels.m3u" server_nm3u8dl = "tvh_server_nm3u8dl:8080" channels = {} tvg_id_regex = re.compile(r'#EXTINF:-1.*tvg-id="([^"]*)"') tvg_logo_regex = re.compile(r'#EXTINF:-1.*tvg-logo="([^"]*)"') group_title_regex = re.compile(r'#EXTINF:-1.*group-title="([^"]*)"') license_regex = re.compile(r'#KODIPROP:inputstream.adaptive.license_key=(.+)') license_list_regex = re.compile(r'#KODIPROP:inputstream.adaptive.license_key=\{(.+)\}') colon_sep_regex = re.compile(r'#KODIPROP:inputstream.adaptive.license_key=([^:]+):([^ ]+)') url_regex = re.compile(r'^(https?://.*)') def clean_string(s): s = s.lower() s = s.replace(" ", "_") s = re.sub(r'[^\w\s]', '', s) s = unidecode(s) return s def base64_to_hex(b64_string): return base64.b64decode(b64_string).hex() def extract_kid_and_k(input_string): keys = [] list_match = license_list_regex.search(input_string) if list_match: json_str = '{' + list_match.group(1) + '}' data = json.loads(json_str) try: for key_pair in data['keys']: kid = base64_to_hex(f"{key_pair['kid']}==") k = base64_to_hex(f"{key_pair['k']}==") keys.append(f'{kid}:{k}'.strip()) except: for key_pair in data: kid = key_pair k = data[key_pair] keys.append(f'{kid}:{k}'.strip()) else: colon_sep_match = colon_sep_regex.search(input_string) if colon_sep_match: kid = colon_sep_match.group(1) k = colon_sep_match.group(2) keys.append(f'{kid}:{k}'.strip()) return keys with open(m3u_file, 'r') as f: for line in f: # Search tvg-id match_tvg_id = tvg_id_regex.search(line) if match_tvg_id: tvg_id = match_tvg_id.group(1) # Search tvg-logo match_tvg_logo = tvg_logo_regex.search(line) if match_tvg_logo: tvg_logo = match_tvg_logo.group(1) # Search group-title match_group_title =group_title_regex.search(line) if match_group_title: group_title = match_group_title.group(1) # Search license_key match_license_key = license_regex.search(line) if match_license_key: keys = extract_kid_and_k(line) # Search URL match_url = url_regex.search(line) if match_url: url = match_url.group(0) if tvg_id not in channels and tvg_id != "": channels[tvg_id] = { 'group_title': group_title, 'tvg_logo': tvg_logo, 'key1': keys[0], 'key2': keys[1] if len(keys) > 1 else "", 'key3': keys[2] if len(keys) > 2 else "", 'key4': keys[3] if len(keys) > 3 else "", 'key5': keys[4] if len(keys) > 4 else "", 'url': url } channels_json = {} tvheadend_m3u = "#EXTM3U" for channel in channels: channels_json[clean_string(channel)] = { "url": channels[channel]['url'], "key1": channels[channel]['key1'], "key2": channels[channel]['key2'], "key3": channels[channel]['key3'], "key4": channels[channel]['key4'], "key5": channels[channel]['key5'], "useragent": "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36 WebAppManager" if "dazn" in channel.lower() else "ExoPlayerLib/2.5.3", "authorization": "", "referer": "", "proxy": "", "resolution": "" } tvheadend_m3u += f'\n#EXTINF:-1 tvg-id="{channel}" tvg-name="{channel}" group-title="{channels[channel]["group_title"]}" tvg-logo="{channels[channel]["tvg_logo"]}",{channel}' tvheadend_m3u += f'\nhttp://{server_nm3u8dl}/stream/{clean_string(channel)}' with open("../channels/channels.json", "w") as nm3u8dl_channels_file: nm3u8dl_channels_file.write(json.dumps(channels_json, indent=4)) with open("../channels/tvheadend.m3u", "w") as tvheadend_channels_file: tvheadend_channels_file.write(tvheadend_m3u)