Merge branch 'master' into 'main'

Added new channels and modified json generator

See merge request homelabers-premium/tvheadend-nm3u8dl!5
This commit is contained in:
2024-09-10 16:28:42 +00:00
3 changed files with 2065 additions and 19 deletions

View File

@@ -14,9 +14,16 @@ const activeStreams = {}; // Store active stream processes with unique IDs
fs.watch(channelsPath, (eventType, filename) => { fs.watch(channelsPath, (eventType, filename) => {
if (eventType === 'change') { if (eventType === 'change') {
console.log(`====================================`);
console.log(`channels.json was updated, reloading...`); console.log(`channels.json was updated, reloading...`);
try { try {
channels = JSON.parse(fs.readFileSync(channelsPath, 'utf8')); channels = JSON.parse(fs.readFileSync(channelsPath, 'utf8'));
// Log every channel loaded
for (const channel in channels) {
console.log(`Channel loaded: ${channel}`);
}
console.log(`Channels reloaded`);
console.log(`====================================`);
} catch (error) { } catch (error) {
console.log(error.message); console.log(error.message);
} }
@@ -40,7 +47,7 @@ const delay = channel.delay;
let args = [ let args = [
channel.url, channel.url,
'--use-shaka-packager', '--use-shaka-packager',
// '--log-level', 'INFO', '--log-level', 'OFF',
'--no-log', '--no-log',
// '--live-real-time-merge', 'true', // '--live-real-time-merge', 'true',
// '--mp4-real-time-decryption', 'true', // '--mp4-real-time-decryption', 'true',

2002
tools/channels.m3u Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,18 @@
import re import re
import json import json
from unidecode import unidecode from unidecode import unidecode
import base64
m3u_file = "vodafone.m3u" m3u_file = "channels.m3u"
server_nm3u8dl = "tvh_server_nm3u8dl:8080" server_nm3u8dl = "tvh_server_nm3u8dl:8080"
channels = {} channels = {}
tvg_id_regex = re.compile(r'#EXTINF:-1.*tvg-id="([^"]*)"') tvg_id_regex = re.compile(r'#EXTINF:-1.*tvg-id="([^"]*)"')
tvg_logo_regex = re.compile(r'#EXTINF:-1.*tvg-logo="([^"]*)"') tvg_logo_regex = re.compile(r'#EXTINF:-1.*tvg-logo="([^"]*)"')
group_title_regex = re.compile(r'#EXTINF:-1.*group-title="([^"]*)"') group_title_regex = re.compile(r'#EXTINF:-1.*group-title="([^"]*)"')
license_key_regex = re.compile(r'#KODIPROP:inputstream.adaptive.license_key=([^:]+):([^ ]+)') 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?://.*)') url_regex = re.compile(r'^(https?://.*)')
def clean_string(s): def clean_string(s):
@@ -20,6 +23,36 @@ def clean_string(s):
return 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: with open(m3u_file, 'r') as f:
for line in f: for line in f:
# Search tvg-id # Search tvg-id
@@ -38,22 +71,26 @@ with open(m3u_file, 'r') as f:
group_title = match_group_title.group(1) group_title = match_group_title.group(1)
# Search license_key # Search license_key
match_license_key = license_key_regex.search(line) match_license_key = license_regex.search(line)
if match_license_key: if match_license_key:
provider_key = match_license_key.group(1) keys = extract_kid_and_k(line)
content_key = match_license_key.group(2)
# Search URL # Search URL
match_url = url_regex.search(line) match_url = url_regex.search(line)
if match_url: if match_url:
url = match_url.group(0) url = match_url.group(0)
channels[tvg_id] = { if tvg_id not in channels and tvg_id != "":
'group_title': group_title, channels[tvg_id] = {
'tvg_logo': tvg_logo, 'group_title': group_title,
'license_key': f'{provider_key}:{content_key}'.strip(), 'tvg_logo': tvg_logo,
'url': url '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 = {} channels_json = {}
tvheadend_m3u = "#EXTM3U" tvheadend_m3u = "#EXTM3U"
@@ -61,12 +98,12 @@ tvheadend_m3u = "#EXTM3U"
for channel in channels: for channel in channels:
channels_json[clean_string(channel)] = { channels_json[clean_string(channel)] = {
"url": channels[channel]['url'], "url": channels[channel]['url'],
"key1": channels[channel]['license_key'], "key1": channels[channel]['key1'],
"key2": "", "key2": channels[channel]['key2'],
"key3": "", "key3": channels[channel]['key3'],
"key4": "", "key4": channels[channel]['key4'],
"key5": "", "key5": channels[channel]['key5'],
"useragent": "ExoPlayerLib/2.5.3", "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": "", "authorization": "",
"referer": "", "referer": "",
"proxy": "", "proxy": "",