From 635906ebe61c063a266aae06eeb51873c833b063 Mon Sep 17 00:00:00 2001 From: Upbeat7898 Date: Fri, 19 Jun 2026 20:17:14 +0200 Subject: [PATCH 1/2] feat: parse HLS codec metadata Expose codec, bandwidth, resolution, and frame rate attributes from HLS stream variants so callers can identify HEVC renditions. --- resources/lib/twitch/parser.py | 42 ++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/resources/lib/twitch/parser.py b/resources/lib/twitch/parser.py index b41345c..08aec02 100644 --- a/resources/lib/twitch/parser.py +++ b/resources/lib/twitch/parser.py @@ -20,15 +20,21 @@ r'#EXT-X-MEDIA:TYPE=VIDEO.*' r'GROUP-ID="(?P[^"]*)",' r'NAME="(?P[^"]*)"[,=\w]*\n' - r'#EXT-X-STREAM-INF:.*' - r'BANDWIDTH=(?P[0-9]+),' - r'(?:.*RESOLUTION="*(?P[0-9xX]+)"*,)?' - r'(?:.*FRAME-RATE=(?P[0-9.]+))?.*\n' + r'#EXT-X-STREAM-INF:(?P[^\n]*)\n' r'(?Phttp.*)') +_m3u_attribute_pattern = re.compile(r'(?P[A-Z-]+)=(?P"[^"]*"|[^,]*)') + _error_pattern = re.compile(r'.*error(?P.+?).*', re.IGNORECASE) +def _find_m3u_attribute(stream_info, key): + for match in re.finditer(_m3u_attribute_pattern, stream_info): + if match.group('key') == key: + return match.group('value').strip('"') + return None + + def _find_frame_rate(group_id, group_name): group_id = group_id.lower() @@ -88,8 +94,13 @@ def m3u8_to_dict(string): else: name = m.group('group_name') - if m.group('fps'): - fps = float(m.group('fps')) + stream_info = m.group('stream_info') + bandwidth = _find_m3u_attribute(stream_info, 'BANDWIDTH') or 0 + resolution = _find_m3u_attribute(stream_info, 'RESOLUTION') + codecs = _find_m3u_attribute(stream_info, 'CODECS') + frame_rate = _find_m3u_attribute(stream_info, 'FRAME-RATE') + if frame_rate: + fps = float(frame_rate) else: fps = _find_frame_rate(m.group('group_id'), m.group('group_name')) @@ -97,9 +108,10 @@ def m3u8_to_dict(string): 'id': m.group('group_id'), 'name': name, 'url': m.group('url'), - 'bandwidth': int(m.group('bandwidth')), + 'bandwidth': int(bandwidth), 'fps': fps, - 'resolution': m.group('resolution') + 'resolution': resolution, + 'codecs': codecs } log.debug('m3u8_to_dict result:\n{0}'.format(d)) return d @@ -117,8 +129,13 @@ def m3u8_to_list(string): else: name = m.group('group_name') - if m.group('fps'): - fps = float(m.group('fps')) + stream_info = m.group('stream_info') + bandwidth = _find_m3u_attribute(stream_info, 'BANDWIDTH') or 0 + resolution = _find_m3u_attribute(stream_info, 'RESOLUTION') + codecs = _find_m3u_attribute(stream_info, 'CODECS') + frame_rate = _find_m3u_attribute(stream_info, 'FRAME-RATE') + if frame_rate: + fps = float(frame_rate) else: fps = _find_frame_rate(m.group('group_id'), m.group('group_name')) @@ -126,9 +143,10 @@ def m3u8_to_list(string): 'id': m.group('group_id'), 'name': name, 'url': m.group('url'), - 'bandwidth': int(m.group('bandwidth')), + 'bandwidth': int(bandwidth), 'fps': fps, - 'resolution': m.group('resolution') + 'resolution': resolution, + 'codecs': codecs }) log.debug('m3u8_to_list result:\n{0}'.format(l)) From a052a8ffab863123592b5d28fe81daa5e08b86f2 Mon Sep 17 00:00:00 2001 From: Upbeat7898 Date: Fri, 19 Jun 2026 20:25:12 +0200 Subject: [PATCH 2/2] chore: bump module version for codec metadata Bump the module version to 3.0.4 so Kodi can detect the parser metadata update and plugin dependencies can target it explicitly. --- addon.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addon.xml b/addon.xml index c9173fc..b661ba8 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + @@ -9,6 +9,7 @@ all +[add] Parse HLS codec metadata for stream quality selection [fix] Following Channels