refactor(iP): Check all available versions instead of just the default
Some titles don't store the HD/FHD/UHD manifests in the default location, so it will now loop through all versions and pick the best one.
This commit is contained in:
parent
03f5a881ee
commit
255a832039
@ -36,7 +36,6 @@ class iP(Service):
|
|||||||
\b
|
\b
|
||||||
Tips:
|
Tips:
|
||||||
- Use full title URL as input for best results.
|
- Use full title URL as input for best results.
|
||||||
- See which titles are available in UHD: https://www.bbc.co.uk/programmes/p0dh39s7
|
|
||||||
\b
|
\b
|
||||||
- An SSL certificate (PEM) is required for accessing the UHD endpoint.
|
- An SSL certificate (PEM) is required for accessing the UHD endpoint.
|
||||||
Specify its path using the service configuration data in the root config:
|
Specify its path using the service configuration data in the root config:
|
||||||
@ -46,6 +45,8 @@ class iP(Service):
|
|||||||
cert: path/to/cert
|
cert: path/to/cert
|
||||||
\b
|
\b
|
||||||
- Use -v H.265 to request UHD tracks
|
- Use -v H.265 to request UHD tracks
|
||||||
|
- See which titles are available in UHD:
|
||||||
|
https://www.bbc.co.uk/iplayer/help/questions/programme-availability/uhd-content
|
||||||
"""
|
"""
|
||||||
|
|
||||||
ALIASES = ("bbciplayer", "bbc", "iplayer")
|
ALIASES = ("bbciplayer", "bbc", "iplayer")
|
||||||
@ -124,37 +125,26 @@ class iP(Service):
|
|||||||
return Series(episodes)
|
return Series(episodes)
|
||||||
|
|
||||||
def get_tracks(self, title: Union[Movie, Episode]) -> Tracks:
|
def get_tracks(self, title: Union[Movie, Episode]) -> Tracks:
|
||||||
playlist = self.session.get(url=self.config["endpoints"]["playlist"].format(pid=title.id)).json()
|
r = self.session.get(url=self.config["endpoints"]["playlist"].format(pid=title.id))
|
||||||
if not playlist["defaultAvailableVersion"]:
|
r.raise_for_status()
|
||||||
self.log.error(" - Title is unavailable")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if self.config.get("cert"):
|
quality = [
|
||||||
url = self.config["endpoints"]["manifest_"].format(
|
connection.get("height")
|
||||||
vpid=playlist["defaultAvailableVersion"]["smpConfig"]["items"][0]["vpid"],
|
for i in (
|
||||||
mediaset="iptv-uhd" if self.vcodec == "H.265" else "iptv-all",
|
self.check_all_versions(version)
|
||||||
|
for version in (x.get("pid") for x in r.json()["allAvailableVersions"])
|
||||||
)
|
)
|
||||||
|
for connection in i
|
||||||
|
if connection.get("height")
|
||||||
|
]
|
||||||
|
max_quality = max((h for h in quality if h < "1080"), default=None)
|
||||||
|
|
||||||
session = self.session
|
media = next((i for i in (self.check_all_versions(version)
|
||||||
session.mount("https://", SSLCiphers())
|
for version in (x.get("pid") for x in r.json()["allAvailableVersions"]))
|
||||||
session.mount("http://", SSLCiphers())
|
if any(connection.get("height") == max_quality for connection in i)), None)
|
||||||
manifest = session.get(
|
|
||||||
url, headers={"user-agent": self.config["user_agent"]}, cert=self.config["cert"]
|
|
||||||
).json()
|
|
||||||
|
|
||||||
if "result" in manifest:
|
|
||||||
self.log.error(f" - Failed to get manifest [{manifest['result']}]")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
else:
|
|
||||||
url = self.config["endpoints"]["manifest"].format(
|
|
||||||
vpid=playlist["defaultAvailableVersion"]["smpConfig"]["items"][0]["vpid"],
|
|
||||||
mediaset="iptv-all",
|
|
||||||
)
|
|
||||||
manifest = self.session.get(url).json()
|
|
||||||
|
|
||||||
connection = {}
|
connection = {}
|
||||||
for video in [x for x in manifest["media"] if x["kind"] == "video"]:
|
for video in [x for x in media if x["kind"] == "video"]:
|
||||||
connections = sorted(video["connection"], key=lambda x: x["priority"])
|
connections = sorted(video["connection"], key=lambda x: x["priority"])
|
||||||
if self.vcodec == "H.265":
|
if self.vcodec == "H.265":
|
||||||
connection = connections[0]
|
connection = connections[0]
|
||||||
@ -211,7 +201,7 @@ class iP(Service):
|
|||||||
video.codec = Video.Codec.from_codecs(video.data["hls"]["playlist"].stream_info.codecs)
|
video.codec = Video.Codec.from_codecs(video.data["hls"]["playlist"].stream_info.codecs)
|
||||||
video.bitrate = int(self.find(r"-video=(\d+)", as_list(video.url)[0]) or 0)
|
video.bitrate = int(self.find(r"-video=(\d+)", as_list(video.url)[0]) or 0)
|
||||||
|
|
||||||
for caption in [x for x in manifest["media"] if x["kind"] == "captions"]:
|
for caption in [x for x in media if x["kind"] == "captions"]:
|
||||||
connection = sorted(caption["connection"], key=lambda x: x["priority"])[0]
|
connection = sorted(caption["connection"], key=lambda x: x["priority"])[0]
|
||||||
tracks.add(
|
tracks.add(
|
||||||
Subtitle(
|
Subtitle(
|
||||||
@ -255,6 +245,35 @@ class iP(Service):
|
|||||||
|
|
||||||
return r.json()["data"]["programme"]
|
return r.json()["data"]["programme"]
|
||||||
|
|
||||||
|
def check_all_versions(self, vpid: str) -> list:
|
||||||
|
if self.config.get("cert"):
|
||||||
|
url = self.config["endpoints"]["manifest_"].format(
|
||||||
|
vpid=vpid,
|
||||||
|
mediaset="iptv-uhd" if self.vcodec == "H.265" else "iptv-all",
|
||||||
|
)
|
||||||
|
|
||||||
|
session = self.session
|
||||||
|
session.mount("https://", SSLCiphers())
|
||||||
|
session.mount("http://", SSLCiphers())
|
||||||
|
manifest = session.get(
|
||||||
|
url, headers={"user-agent": self.config["user_agent"]}, cert=self.config["cert"]
|
||||||
|
).json()
|
||||||
|
|
||||||
|
if "result" in manifest:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
else:
|
||||||
|
url = self.config["endpoints"]["manifest"].format(
|
||||||
|
vpid=vpid,
|
||||||
|
mediaset="iptv-all",
|
||||||
|
)
|
||||||
|
manifest = self.session.get(url).json()
|
||||||
|
|
||||||
|
if "result" in manifest:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
return manifest["media"]
|
||||||
|
|
||||||
def create_episode(self, episode):
|
def create_episode(self, episode):
|
||||||
title = episode["episode"]["title"]["default"].strip()
|
title = episode["episode"]["title"]["default"].strip()
|
||||||
subtitle = episode["episode"]["subtitle"]
|
subtitle = episode["episode"]["subtitle"]
|
||||||
@ -283,9 +302,7 @@ class iP(Service):
|
|||||||
r = self.session.get(url)
|
r = self.session.get(url)
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
|
|
||||||
redux = re.search(
|
redux = re.search("window.__IPLAYER_REDUX_STATE__ = (.*?);</script>", r.text).group(1)
|
||||||
"window.__IPLAYER_REDUX_STATE__ = (.*?);</script>", r.text
|
|
||||||
).group(1)
|
|
||||||
data = json.loads(redux)
|
data = json.loads(redux)
|
||||||
subtitle = data["episode"].get("subtitle")
|
subtitle = data["episode"].get("subtitle")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user