refactor(iP): Improve availability checks

This commit is contained in:
stabbedbybrick 2024-07-04 10:52:44 +02:00
parent f7428845e8
commit e90d4063ac
2 changed files with 37 additions and 39 deletions

View File

@ -63,15 +63,18 @@ class iP(Service):
def __init__(self, ctx: Context, title: str): def __init__(self, ctx: Context, title: str):
self.title = title self.title = title
super().__init__(ctx)
self.vcodec = ctx.parent.params.get("vcodec") self.vcodec = ctx.parent.params.get("vcodec")
self.range = ctx.parent.params.get("range_") self.range = ctx.parent.params.get("range_")
super().__init__(ctx)
if self.range[0].name == "HLG" and not self.config.get("cert"): self.session.headers.update({"user-agent": "BBCiPlayer/5.17.2.32046"})
self.log.error("UHD tracks cannot be selected without an SSL certificate")
if self.range and self.range[0].name == "HLG" and not self.config.get("cert"):
self.log.error("HLG tracks cannot be requested without an SSL certificate")
sys.exit(1) sys.exit(1)
elif self.range[0].name == "HLG" and self.config.get("cert"): elif self.range and self.range[0].name == "HLG" and self.config.get("cert"):
self.session.headers.update({"user-agent": self.config["user_agent"]})
self.vcodec = "H.265" self.vcodec = "H.265"
def search(self) -> Generator[SearchResult, None, None]: def search(self) -> Generator[SearchResult, None, None]:
@ -94,9 +97,10 @@ class iP(Service):
) )
def get_titles(self) -> Union[Movies, Series]: def get_titles(self) -> Union[Movies, Series]:
kind, pid = (re.match(self.TITLE_RE, self.title).group(i) for i in ("kind", "id")) try:
if not pid: kind, pid = (re.match(self.TITLE_RE, self.title).group(i) for i in ("kind", "id"))
raise ValueError("Unable to parse title ID - is the URL or id correct?") except Exception:
raise ValueError("Could not parse ID from title - is the URL correct?")
data = self.get_data(pid, slice_id=None) data = self.get_data(pid, slice_id=None)
if data is None and kind == "episode": if data is None and kind == "episode":
@ -138,25 +142,17 @@ class iP(Service):
data = json.loads(redux) data = json.loads(redux)
versions = [{"pid": x.get("id") for x in data["versions"] if not x.get("kind") == "audio-described"}] versions = [{"pid": x.get("id") for x in data["versions"] if not x.get("kind") == "audio-described"}]
quality = [ connections = [self.check_all_versions(version) for version in (x.get("pid") for x in versions)]
connection.get("height") quality = [connection.get("height") for i in connections for connection in i if connection.get("height")]
for i in (self.check_all_versions(version) for version in (x.get("pid") for x in versions))
for connection in i
if connection.get("height")
]
max_quality = max((h for h in quality if h < "1080"), default=None) max_quality = max((h for h in quality if h < "1080"), default=None)
media = next( media = next(
( (i for i in connections if any(connection.get("height") == max_quality or "2160" for connection in i)),
i
for i in (self.check_all_versions(version) for version in (x.get("pid") for x in versions))
if any(connection.get("height") == max_quality for connection in i)
),
None, None,
) )
if not media: if not media:
self.log.error("No media found. If you're behind a VPN/proxy, you might be blocked") self.log.error(" - Selection unavailable. Title doesn't exist or your IP address is blocked")
sys.exit(1) sys.exit(1)
connection = {} connection = {}
@ -266,33 +262,35 @@ class iP(Service):
return r.json()["data"]["programme"] return r.json()["data"]["programme"]
def check_all_versions(self, vpid: str) -> list: def check_all_versions(self, vpid: str) -> list:
if self.config.get("cert"): media = None
url = self.config["endpoints"]["manifest_"].format(
vpid=vpid,
mediaset="iptv-uhd" if self.vcodec == "H.265" else "iptv-all",
)
if self.vcodec == "H.265":
session = self.session session = self.session
session.mount("https://", SSLCiphers()) session.mount("https://", SSLCiphers())
session.mount("http://", SSLCiphers()) session.mount("http://", SSLCiphers())
manifest = session.get( mediaset = "iptv-uhd"
url, headers={"user-agent": self.config["user_agent"]}, cert=self.config["cert"]
).json()
if "result" in manifest: for mediator in ["securegate.iplayer.bbc.co.uk", "ipsecure.stage.bbc.co.uk"]:
return {} availability = session.get(
self.config["endpoints"]["secure"].format(mediator, vpid, mediaset),
cert=self.config["cert"],
).json()
if availability.get("media"):
media = availability["media"]
break
else: else:
url = self.config["endpoints"]["manifest"].format( mediaset = "iptv-all"
vpid=vpid,
mediaset="iptv-all",
)
manifest = self.session.get(url).json()
if "result" in manifest: for mediator in ["open.live.bbc.co.uk", "open.stage.bbc.co.uk"]:
return {} availability = self.session.get(
self.config["endpoints"]["open"].format(mediator, mediaset, vpid),
).json()
if availability.get("media"):
media = availability["media"]
break
return manifest["media"] return media
def create_episode(self, episode: dict, data: dict) -> Episode: def create_episode(self, episode: dict, data: dict) -> Episode:
title = episode["episode"]["title"]["default"].strip() title = episode["episode"]["title"]["default"].strip()

View File

@ -6,6 +6,6 @@ endpoints:
episodes: https://ibl.api.bbci.co.uk/ibl/v1/episodes/{pid}?rights=mobile&availability=available episodes: https://ibl.api.bbci.co.uk/ibl/v1/episodes/{pid}?rights=mobile&availability=available
metadata: https://graph.ibl.api.bbc.co.uk/ metadata: https://graph.ibl.api.bbc.co.uk/
playlist: https://www.bbc.co.uk/programmes/{pid}/playlist.json playlist: https://www.bbc.co.uk/programmes/{pid}/playlist.json
manifest: https://open.live.bbc.co.uk/mediaselector/6/select/version/2.0/mediaset/{mediaset}/vpid/{vpid}/ open: https://{}/mediaselector/6/select/version/2.0/mediaset/{}/vpid/{}/
manifest_: https://securegate.iplayer.bbc.co.uk/mediaselector/6/select/version/2.0/vpid/{vpid}/format/json/mediaset/{mediaset}/proto/https secure: https://{}/mediaselector/6/select/version/2.0/vpid/{}/format/json/mediaset/{}/proto/https
search: https://search.api.bbci.co.uk/formula/iplayer-ibl-root search: https://search.api.bbci.co.uk/formula/iplayer-ibl-root