artemis/utils/enigma2.py
2024-03-01 20:51:07 +01:00

63 lines
1.8 KiB
Python

from enum import IntEnum
from typing import Literal
# https://github.com/openatv/enigma2/blob/a0979a6091df64d9f1e7283fa9bd40ca3f64d9d8/doc/SERVICEREF#L131
class ServiceType(IntEnum):
TV = 0x01 # digital television
MPEG2HDTV = 0x11 # MPEG-2 HD digital television service
SDTV = 0x16 # H.264/AVC SD digital television service
HDTV = 0x19 # H.264/AVC HD digital television service
HEVC = 0x1F # HEVC digital television service
HEVCUHD = 0x20 # HEVC UHD digital television service
UNKNOWN = -1
class Namespace(IntEnum):
# anything else is a valid satellite position
DVB_C = 0xFFFF0000
DVB_T = 0xEEEE0000
# %d:%d:%x:%x:%x:%x:%x:%x:%x:%x:%d:%s:%s
SREF_FMT = "1:0:{:x}:{:x}:{:x}:{:x}:{:x}:0:0:0:"
# 3600 - west_sat_position
def build_namespace(pos: float, cardinal: Literal["E", "W"]) -> int:
pos = int(pos * 10)
if cardinal == "W":
pos = 3600 - pos
return pos << 16
def pos_from_namespace(ns: int) -> str:
pos = ns >> 16
if pos > 1800:
return f"{(3600 - pos) / 10}W"
return f"{pos / 10}E"
# REFTYPE:FLAGS:STYPE:SID:TSID:ONID:NS:PARENT_SID:PARENT_TSID:UNUSED:PATH:NAME
# we only care about DVB here
def build_sref(service_type, sid, tsid, onid, ns):
return SREF_FMT.format(service_type, sid, tsid, onid, ns).upper()
def parse_sref(sref):
parts = sref.split(":")
service_type = ServiceType._value2member_map_.get((int(parts[2], 16)))
if not service_type:
service_type = ServiceType.UNKNOWN
pos = pos_from_namespace(int(parts[6], 16))
return {
"service_type": service_type.name,
"sid": int(parts[3], 16), # Stream ID
"tsid": int(parts[4], 16), # Transport stream ID (tp xx -> xx00 or TID in ONID-TID)
"onid": int(parts[5], 16), # Originating network ID (ONID in ONIT-TID)
"sat_pos": pos,
}