mirror of https://github.com/streamlink/streamlink
165 lines
6.0 KiB
Python
165 lines
6.0 KiB
Python
"""
|
|
$description Live and on-demand video service from World Wrestling Entertainment, Inc.
|
|
$url network.wwe.com
|
|
$type live, vod
|
|
$account Required
|
|
"""
|
|
|
|
import json
|
|
import logging
|
|
import re
|
|
from functools import lru_cache
|
|
from urllib.parse import parse_qsl, urlparse
|
|
|
|
from streamlink.plugin import Plugin, PluginError, pluginargument, pluginmatcher
|
|
from streamlink.plugin.api import useragents
|
|
from streamlink.stream.hls import HLSStream
|
|
from streamlink.utils.times import seconds_to_hhmmss
|
|
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
@pluginmatcher(re.compile(
|
|
r"https?://watch\.wwe\.com/(channel)?",
|
|
))
|
|
@pluginargument(
|
|
"email",
|
|
required=True,
|
|
requires=["password"],
|
|
metavar="EMAIL",
|
|
help="The email associated with your WWE Network account, required to access any WWE Network stream.",
|
|
)
|
|
@pluginargument(
|
|
"password",
|
|
required=True,
|
|
sensitive=True,
|
|
metavar="PASSWORD",
|
|
help="A WWE Network account password to use with --wwenetwork-email.",
|
|
)
|
|
class WWENetwork(Plugin):
|
|
site_config_re = re.compile(r"""">window.__data = (\{.*?\})</script>""")
|
|
stream_url = "https://dce-frontoffice.imggaming.com/api/v2/stream/{id}"
|
|
live_url = "https://dce-frontoffice.imggaming.com/api/v2/event/live"
|
|
login_url = "https://dce-frontoffice.imggaming.com/api/v2/login"
|
|
page_config_url = "https://cdn.watch.wwe.com/api/page"
|
|
API_KEY = "cca51ea0-7837-40df-a055-75eb6347b2e7"
|
|
|
|
customer_id = 16
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.session.http.headers.update({"User-Agent": useragents.CHROME})
|
|
self.auth_token = None
|
|
|
|
def get_title(self):
|
|
return self.item_config["title"]
|
|
|
|
def request(self, method, url, **kwargs):
|
|
headers = kwargs.pop("headers", {})
|
|
headers.update({"x-api-key": self.API_KEY,
|
|
"Origin": "https://watch.wwe.com",
|
|
"Referer": "https://watch.wwe.com/signin",
|
|
"Accept": "application/json",
|
|
"Realm": "dce.wwe"})
|
|
if self.auth_token:
|
|
headers["Authorization"] = "Bearer {0}".format(self.auth_token)
|
|
|
|
kwargs["raise_for_status"] = False
|
|
log.debug("API request: {0} {1}".format(method, url))
|
|
res = self.session.http.request(method, url, headers=headers, **kwargs)
|
|
data = self.session.http.json(res)
|
|
|
|
if "status" in data and data["status"] != 200:
|
|
log.debug("API request failed: {0}:{1} ({2})".format(
|
|
data["status"],
|
|
data.get("code"),
|
|
"; ".join(data.get("messages", [])),
|
|
))
|
|
return data
|
|
|
|
def login(self, email, password):
|
|
log.debug("Attempting login as {0}".format(email))
|
|
# sets some required cookies to login
|
|
data = self.request("POST", self.login_url,
|
|
data=json.dumps({"id": email, "secret": password}),
|
|
headers={"Content-Type": "application/json"})
|
|
if "authorisationToken" in data:
|
|
self.auth_token = data["authorisationToken"]
|
|
|
|
return self.auth_token
|
|
|
|
@property # type: ignore
|
|
@lru_cache(maxsize=128) # noqa: B019
|
|
def item_config(self):
|
|
log.debug("Loading page config")
|
|
p = urlparse(self.url)
|
|
res = self.session.http.get(self.page_config_url,
|
|
params=dict(device="web_browser",
|
|
ff="idp,ldp",
|
|
item_detail_expand="all",
|
|
lang="en-US",
|
|
list_page_size="1",
|
|
max_list_prefetch="1",
|
|
path=p.path,
|
|
segments="es",
|
|
sub="Registered",
|
|
text_entry_format="html"))
|
|
data = self.session.http.json(res)
|
|
return data["item"]
|
|
|
|
def _get_media_info(self, content_id):
|
|
"""
|
|
Get the info about the content, based on the ID
|
|
:param content_id: contentId for the video
|
|
:return:
|
|
"""
|
|
info = self.request("GET", self.stream_url.format(id=content_id))
|
|
return self.request("GET", info.get("playerUrlCallback"))
|
|
|
|
def _get_video_id(self):
|
|
# check the page to find the contentId
|
|
log.debug("Searching for content ID")
|
|
try:
|
|
if self.item_config["type"] == "channel":
|
|
return self._get_live_id()
|
|
else:
|
|
return "vod/{id}".format(id=self.item_config["customFields"]["DiceVideoId"])
|
|
except KeyError:
|
|
log.error("Could not find video ID")
|
|
return
|
|
|
|
def _get_live_id(self):
|
|
log.debug("Loading live event")
|
|
res = self.request("GET", self.live_url)
|
|
for event in res.get("events", []):
|
|
return "event/{sportId}/{propertyId}/{tournamentId}/{id}".format(**event)
|
|
|
|
def _get_streams(self):
|
|
if not self.login(self.get_option("email"), self.get_option("password")):
|
|
raise PluginError("Login failed")
|
|
|
|
try:
|
|
start_point = int(float(dict(parse_qsl(urlparse(self.url).query)).get("startPoint", 0.0)))
|
|
if start_point > 0:
|
|
log.info("Stream will start at {0}".format(seconds_to_hhmmss(start_point)))
|
|
except ValueError:
|
|
start_point = 0
|
|
|
|
content_id = self._get_video_id()
|
|
|
|
if content_id:
|
|
log.debug("Found content ID: {0}".format(content_id))
|
|
info = self._get_media_info(content_id)
|
|
if info.get("hlsUrl"):
|
|
yield from HLSStream.parse_variant_playlist(
|
|
self.session,
|
|
info["hlsUrl"],
|
|
start_offset=start_point,
|
|
).items()
|
|
else:
|
|
log.error("Could not find the HLS URL")
|
|
|
|
|
|
__plugin__ = WWENetwork
|