Skip to content

Commit

Permalink
Merge branch 'refs/heads/nexus-staging'
Browse files Browse the repository at this point in the history
  • Loading branch information
smirgol committed Apr 25, 2024
2 parents 04951fe + 36370ab commit 234c1d7
Show file tree
Hide file tree
Showing 31 changed files with 11,246 additions and 14 deletions.
5 changes: 3 additions & 2 deletions addon.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.crunchyroll" name="Crunchyroll" version="3.3.0.14" provider-name="MrKrabat">
<addon id="plugin.video.crunchyroll" name="Crunchyroll" version="3.3.0.15" provider-name="smirgol">
<requires>
<import addon="xbmc.python" version="3.0.1"/>
<import addon="script.module.inputstreamhelper" version="0.3.3"/>
Expand All @@ -21,6 +21,7 @@
<disclaimer lang="de_DE">HINWEIS: Du MUSST PREMIUM Mitglied sein um dieses Plugin zu benutzen</disclaimer>
<disclaimer lang="es_ES">Atención: Necesitas ser miembro PREMIUM para utilizar este Plugin</disclaimer>
<news>
v3.3.0.15 (2024.04.25)[CR]- update auth, playback of drm streams, cloudflare fix, free streams after watching, update playhead upon skip, support chinese animes, add hindi language support, filter seasons by language configurable
v3.3.0.14 (2023.01.16)[CR]- update auth, add new routing, async data fetching, updated language settings, improved bookmarking/favourite support
v3.3.0.13 (2023.01.05)[CR]- improve listing, add crunchylists
v3.3.0.12 (2023.12.30)[CR]- add resume watching, update settings, add skip intro
Expand All @@ -40,7 +41,7 @@
<license>GNU Affero General Public License, v3</license>
<forum/>
<website>https://www.crunchyroll.com/</website>
<source>https://github.com/MrKrabat/plugin.video.crunchyroll</source>
<source>https://github.com/smirgol/plugin.video.crunchyroll</source>
<email/>
<assets>
<icon>resources/icon.png</icon>
Expand Down
4 changes: 3 additions & 1 deletion resources/language/resource.language.de_de/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -256,4 +256,6 @@ msgctxt "#30071"
msgid "Added to queue"
msgstr "Zur Playlist hinzugefügt"


msgctxt "#30080"
msgid "There are to many active streams. Please try again later."
msgstr "Es sind zu viele Streams aktiv. Bitte probiere es später noch einmal."
6 changes: 5 additions & 1 deletion resources/language/resource.language.en_gb/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -256,4 +256,8 @@ msgstr ""

msgctxt "#30071"
msgid "Added to queue"
msgstr "Added to queue"
msgstr "Added to queue"

msgctxt "#30080"
msgid "There are to many active streams. Please try again later."
msgstr ""
6 changes: 5 additions & 1 deletion resources/language/resource.language.es_es/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -256,4 +256,8 @@ msgstr "Ninguno"

msgctxt "#30071"
msgid "Added to queue"
msgstr "Añadido a la cola"
msgstr "Añadido a la cola"

msgctxt "#30080"
msgid "There are to many active streams. Please try again later."
msgstr ""
4 changes: 4 additions & 0 deletions resources/language/resource.language.fr_fr/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -253,3 +253,7 @@ msgstr "Aucun"
msgctxt "#30071"
msgid "Added to queue"
msgstr "Ajouté à la file d'attente"

msgctxt "#30080"
msgid "There are to many active streams. Please try again later."
msgstr ""
6 changes: 5 additions & 1 deletion resources/language/resource.language.pt_br/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,8 @@ msgstr "Sem Legendas"

msgctxt "#30071"
msgid "Added to queue"
msgstr "Added to queue"
msgstr "Added to queue"

msgctxt "#30080"
msgid "There are to many active streams. Please try again later."
msgstr ""
18 changes: 16 additions & 2 deletions resources/lib/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

from . import utils
from .model import AccountData, Args, LoginError
from ..modules import cloudscraper


class API:
Expand All @@ -41,14 +42,15 @@ class API:
# DEVICE = "com.crunchyroll.windows.desktop"
# TIMEOUT = 30

CRUNCHYROLL_UA = "Crunchyroll/3.51.1 Android/14 okhttp/4.12.0"
CRUNCHYROLL_UA = "Crunchyroll/3.54.0 Android/14 okhttp/4.12.0"

INDEX_ENDPOINT = "https://beta-api.crunchyroll.com/index/v2"
PROFILE_ENDPOINT = "https://beta-api.crunchyroll.com/accounts/v1/me/profile"
TOKEN_ENDPOINT = "https://beta-api.crunchyroll.com/auth/v1/token"
SEARCH_ENDPOINT = "https://beta-api.crunchyroll.com/content/v1/search"
STREAMS_ENDPOINT = "https://beta-api.crunchyroll.com/cms/v2{}/videos/{}/streams"
STREAMS_ENDPOINT_DRM = "https://cr-play-service.prd.crunchyrollsvc.com/v1/{}/android/phone/play"
STREAMS_ENDPOINT_CLEAR_STREAM = "https://cr-play-service.prd.crunchyrollsvc.com/v1/token/{}/{}"
# SERIES_ENDPOINT = "https://beta-api.crunchyroll.com/cms/v2{}/series/{}"
SEASONS_ENDPOINT = "https://beta-api.crunchyroll.com/cms/v2{}/seasons"
EPISODES_ENDPOINT = "https://beta-api.crunchyroll.com/cms/v2{}/episodes"
Expand All @@ -73,7 +75,7 @@ class API:
CRUNCHYLISTS_LISTS_ENDPOINT = "https://beta-api.crunchyroll.com/content/v2/{}/custom-lists"
CRUNCHYLISTS_VIEW_ENDPOINT = "https://beta-api.crunchyroll.com/content/v2/{}/custom-lists/{}"

AUTHORIZATION = "Basic OTQzcTkxX3NtMXVhbnZiX3ppbjQ6bDZ5cXJTQ1NPNzZNeXFVZ295c19SQVFKcWsyemU3YnE="
AUTHORIZATION = "Basic bm12anNoZmtueW14eGtnN2ZiaDk6WllJVnJCV1VQYmNYRHRiRDIyVlNMYTZiNFdRb3Mzelg="
LICENSE_ENDPOINT = "https://cr-license-proxy.prd.crunchyrollsvc.com/v1/license/widevine"

def __init__(
Expand Down Expand Up @@ -155,6 +157,18 @@ def create_session(self, refresh=False) -> None:
raise LoginError("Failed to authenticate twice")
return self.create_session()

if r.status_code == 403:
utils.crunchy_log(self.args, "Possible cloudflare shenanigans")
scraper = cloudscraper.create_scraper(delay=10, browser={'custom': self.CRUNCHYROLL_UA})
r = scraper.post(
url=API.TOKEN_ENDPOINT,
headers=headers,
data=data
)

if 'access_token' not in r.text:
raise LoginError("Failed to bypass cloudflare")

r_json = get_json_from_response(r)

self.api_headers.clear()
Expand Down
5 changes: 4 additions & 1 deletion resources/lib/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ def show_resume_episodes(args, api: API):
args=args,
api=api,
listables=get_listables_from_response(args, req.get('data')),
is_folder=False
is_folder=False,
options=view.OPT_CTX_SEASONS | view.OPT_CTX_EPISODES
)

# pagination
Expand Down Expand Up @@ -473,6 +474,8 @@ def start_playback(args, api: API):

utils.crunchy_log(args, "playback stopped", xbmc.LOGINFO)

video_player.clear_active_stream()


def add_to_queue(args, api: API) -> bool:
# api request
Expand Down
30 changes: 26 additions & 4 deletions resources/lib/videoplayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from resources.lib import utils
from resources.lib.api import API
from resources.lib.gui import SkipModalDialog, _show_modal_dialog
from resources.lib.model import Object, Args, CrunchyrollError
from resources.lib.model import Object, Args, CrunchyrollError, LoginError
from resources.lib.videostream import VideoPlayerStreamData, VideoStream


Expand Down Expand Up @@ -88,11 +88,17 @@ def _get_video_stream_data(self) -> bool:
xbmcgui.Dialog().ok(self._args.addon_name, self._args.addon.getLocalizedString(30064))
return False

except (CrunchyrollError, requests.exceptions.RequestException):
except (CrunchyrollError, requests.exceptions.RequestException) as e:
utils.log_error_with_trace(self._args, "Failed to prepare stream info data", False)
xbmcplugin.setResolvedUrl(int(self._args.argv[1]), False, item)
xbmcgui.Dialog().ok(self._args.addon_name,
self._args.addon.getLocalizedString(30064))

# check for TOO_MANY_ACTIVE_STREAMS
if 'TOO_MANY_ACTIVE_STREAMS' in str(e):
xbmcgui.Dialog().ok(self._args.addon_name,
self._args.addon.getLocalizedString(30080))
else:
xbmcgui.Dialog().ok(self._args.addon_name,
self._args.addon.getLocalizedString(30064))
return False

return True
Expand Down Expand Up @@ -304,6 +310,22 @@ def _ask_to_skip(self, section):
}
).start()

def clear_active_stream(self):
if not self._args.get_arg('episode_id') or not self._stream_data.token:
return

try:
self._api.make_request(
method="DELETE",
url=self._api.STREAMS_ENDPOINT_CLEAR_STREAM.format(self._args.get_arg('episode_id'), self._stream_data.token),
)
except (CrunchyrollError, LoginError, requests.exceptions.RequestException):
# catch timeout or any other possible exception
utils.crunchy_log(None, "Failed to clear active stream for episode: %s" % self._args.get_arg('episode_id'))
return

utils.crunchy_log(None, "Cleared active stream for episode: %s" % self._args.get_arg('episode_id'))


def update_playhead(args: Args, api: API, content_id: str, playhead: int):
""" Update playtime to Crunchyroll """
Expand Down
2 changes: 1 addition & 1 deletion resources/lib/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ async def complement_listables(
listable.rating = float(result_obj.get('objects').get(listable.id).get('rating').get('average')) * 2.0
elif result_obj.get('objects').get(listable.id).get('rating').get('up') and result_obj.get('objects').get(
listable.id).get('rating').get('down'):
# these are user ratings and they are pretty weird (overly positive)
# these are user ratings, and they are pretty weird (overly positive)
ups_obj = result_obj.get('objects').get(listable.id).get('rating').get('up')
downs_obj = result_obj.get('objects').get(listable.id).get('rating').get('down')
ups = float(ups_obj.get('displayed'))
Expand Down
Loading

0 comments on commit 234c1d7

Please sign in to comment.