refactor(iP): Improve availability checks
This commit is contained in:
parent
f7428845e8
commit
e90d4063ac
@ -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()
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user