Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions plugin.video.retrospect/addon.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.retrospect"
version="5.7.29"
version="5.7.31"
name="Retrospect"
provider-name="Bas Rieter">

Expand Down Expand Up @@ -133,20 +133,20 @@
<platform>all</platform>
<license>GPL-3.0-or-later</license>
<language>en nl de sv no lt lv fi</language>
<news>[B]Retrospect v5.7.29 - Changelog - 2025-09-18[/B]
<news>[B]Retrospect v5.7.31 - Changelog - 2025-10-02[/B]

Quick workaround for InputStream Adaptive Helper not working which prevented playback of all videos.
Fixed Kijk.nl and Vier.be playback.

[B]Framework related[/B]
* Fixed: Temporarily fix ISA Helper issue (Fixes #1916).
* Fixed: Restored ISA Helper (See #1916).

[B]GUI/Settings/Language related[/B]
_None_

[B]Channel related[/B]
* Fixed: TV4 Play `playable from`-parsing.
* Fixed: OpenRegio format JSON glitch fixed.

* Fixed: Kijk.nl broke playback (Fixes #1916).
* Fixed: Vier.be parsing (Fixes #1919).
* Fixed: UR Play categories.
</news>
<assets>
<icon>resources/media/icon.png</icon>
Expand Down
17 changes: 13 additions & 4 deletions plugin.video.retrospect/channels/channel.be/vier/chn_vier.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,13 @@ def __call__(self, data: str) -> Tuple[JsonHelper, List[MediaItem]]:
nextjs_regex = self.__regex
try:
result = Regexer.do_regex(nextjs_regex, data)
nextjs_data = result[0]
if len(result) == 1:
nextjs_data = result[0]
else:
nextjs_json = [JsonHelper.loads(j) for j in result]
helper = JsonHelper("{}")
helper.json = nextjs_json
return helper, []
except:
Logger.debug(f"RAW NextJS: {data}")
raise
Expand Down Expand Up @@ -107,13 +113,13 @@ def __init__(self, channel_info):
parser=[], creator=self.create_typed_nextjs_item)

self._add_data_parser("https://www.goplay.be/", json=True, name="Main show parser",
preprocessor=NextJsParser(r"{\"playlists\":(.+}\]).+?}\]}\]\][\r\n]"),
preprocessor=NextJsParser(r"{\"playlists\":([^\n\r]+}\])[^}\]]+?}\]}\]"),
parser=[], creator=self.create_season_item,
postprocessor=self.show_single_season)

self._add_data_parser("https://www.goplay.be/tv-gids/", json=True, name="TV Guides",
preprocessor=NextJsParser(
r"children\":(\[\[\"\$\",[^{]+{\"program.+\])}\]\]}\]"),
r"({\"program\":{\"classification\".+?})\]"),
parser=[], creator=self.create_epg_item)

self._add_data_parser("https://api.goplay.be/web/v1/search", json=True,
Expand Down Expand Up @@ -384,7 +390,10 @@ def create_search_result(self, result_set: dict) -> MediaItemResult:
return item

def create_epg_item(self, result_set: dict) -> MediaItemResult:
data = result_set[-1]["program"]
if isinstance(result_set, str):
return None

data = result_set["program"]
if not data["video"]:
return None

Expand Down
60 changes: 45 additions & 15 deletions plugin.video.retrospect/channels/channel.sbsnl/kijknl/chn_kijknl.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# SPDX-License-Identifier: GPL-3.0-or-later

import datetime
import json
import random
import sys
from typing import List, Optional

import pytz
Expand Down Expand Up @@ -796,6 +799,8 @@ def create_api_episode_type(self, result_set):
item.set_date(date_time.year, date_time.month, date_time.day, date_time.hour,
date_time.minute,
date_time.second)
if date_time > datetime.datetime.now():
return None

# DRM only
no_drm_items = [src for src in result_set["sources"] if not src["drm"]]
Expand Down Expand Up @@ -836,23 +841,48 @@ def update_graphql_item(self, item):
bitrate = 0 if hls_over_dash else 1
stream = item.add_stream(url, bitrate)

# fetch the authentication token:
# url = self.__get_api_persisted_url("drmToken", "634c83ae7588a877e2bb67d078dda618cfcfc70ac073aef5e134e622686c0bb6", variables={})
url = self.__get_api_query_url("drmToken", "{token,expiration}")
token_data = UriHandler.open(url, no_cache=True)
token_json = JsonHelper(token_data)
token = token_json.get_value("data", "drmToken", "token")

# we need to POST to this url using this wrapper:
key_url = drm["widevine"]["url"]
release_pid = drm["widevine"]["releasePid"]
encryption_json = '{{"getRawWidevineLicense":{{"releasePid":"{}","widevineChallenge":"b{{SSM}}"}}}}'.format(release_pid)
encryption_key = Mpd.get_license_key(
key_url=key_url,
key_type="b",
key_value=encryption_json,
key_headers={"Content-Type": "application/json", "authorization": "Basic {}".format(token)}
)

# fetch the authentication token:
if "vudrm" in key_url:
# url = self.__get_api_query_url(
# f"drmToken(drmProvider:JWP)", "{token,expiration}")
# url = f"{url}&rnd={random.randint(0, sys.maxsize)}"
# token_data = UriHandler.open(url, no_cache=True)
url = "https://graph.kijk.nl/graphql"
data = {
"query": "query DrmTokenQuery($provider: DrmProvider) {drmToken(drmProvider:$provider) {expiration,token}}",
"variables": {"provider": "JWP"}}
token_data = UriHandler.open(url, json=data)
token_json = JsonHelper(token_data)
token = token_json.get_value("data", "drmToken", "token")
encryption_key = Mpd.get_license_key(
key_url=key_url,
key_type="R",
key_headers={
"x-vudrm-token": token,
# "user-agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 (.NET CLR 3.5.30729)",
# "origin": "https://kijk.nl",
# "referer": "https://kijk.nl/"
}
)
else:
# url = self.__get_api_persisted_url("drmToken", "634c83ae7588a877e2bb67d078dda618cfcfc70ac073aef5e134e622686c0bb6", variables={})
url = self.__get_api_query_url("drmToken", "{token,expiration}")
token_data = UriHandler.open(url, no_cache=True)
token_json = JsonHelper(token_data)
token = token_json.get_value("data", "drmToken", "token")

# we need to POST to this url using this wrapper:
encryption_json = '{{"getRawWidevineLicense":{{"releasePid":"{}","widevineChallenge":"b{{SSM}}"}}}}'.format(release_pid)
encryption_key = Mpd.get_license_key(
key_url=key_url,
key_type="b",
key_value=encryption_json,
key_headers={"Content-Type": "application/json", "authorization": "Basic {}".format(token)}
)

Mpd.set_input_stream_addon_input(
stream, license_key=encryption_key,
stream_headers={"user-agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 (.NET CLR 3.5.30729)"})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def __init__(self, channel_info):
self._add_data_parser("*", updater=self.update_video_item)

self._add_data_parser("/bladdra/alla-kategorier.json", match_type=ParserData.MatchEnd, json=True,
parser=["pageProps", "categoriesForMenu"], creator=self.create_category_item)
parser=["pageProps", "highlightedCategories"], creator=self.create_category_item)

self._add_data_parser("/bladdra/", json=True, match_type=ParserData.MatchContains,
preprocessor=self.iterate_page_props,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ def __convert_web_vtt_to_srt(webvvt):
result = ""
for line in webvvt.split("\n"):
line = line.strip()
if line.endswith("WEBVTT") or line.startswith("X-TIMESTAMP"):
if line.startswith("WEBVTT") or line.startswith("X-TIMESTAMP"):
continue
if not line:
continue
Expand Down
14 changes: 7 additions & 7 deletions plugin.video.retrospect/resources/lib/streams/mpd.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ def set_input_stream_addon_input(strm: MediaStream,

if license_key is not None:
# Local import to make sure the overhead is low
#import inputstreamhelper
#from resources.lib.logger import Logger
import inputstreamhelper
from resources.lib.logger import Logger
pass

#is_helper = inputstreamhelper.Helper("mpd", drm=license_type)
#if is_helper.check_inputstream():
# Logger.info("Widevine library was already installed or installed successfully.")
#else:
# Logger.error("Widevine was not installed or failed to install.")
is_helper = inputstreamhelper.Helper("mpd", drm=license_type)
if is_helper.check_inputstream():
Logger.info("Widevine library was already installed or installed successfully.")
else:
Logger.error("Widevine was not installed or failed to install.")

return Adaptive.set_input_stream_addon_input(strm,
stream_headers=stream_headers,
Expand Down