text: import re
  
  from streamlink import PluginError
  from streamlink.plugin import Plugin, PluginArguments, PluginArgument
  from streamlink.plugin.api import validate
  from streamlink.stream import HLSStream
  from streamlink.stream import RTMPStream
  from streamlink.compat import urljoin
  
  
  class LiveEdu(Plugin):
      login_url = "https://www.liveedu.tv/accounts/login/"
      url_re = re.compile(r"https?://(?:\w+\.)?(?:livecoding|liveedu)\.tv/")
      config_re = re.compile(r"""\Wconfig.(?P<key>\w+)\s*=\s*(?P<q>['"])(?P<value>.*?)(?P=q);""")
      csrf_re = re.compile(r'''"csrfToken"\s*:\s*"(\w+)"''')
      api_schema = validate.Schema({
          "viewing_urls": {
              validate.optional("error"): validate.text,
              validate.optional("urls"): [{
                  "src": validate.url(),
                  "type": validate.text,
                  validate.optional("res"): int,
                  validate.optional("label"): validate.text,
              }]
          }
      })
      config_schema = validate.Schema({
          "selectedVideoHID": validate.text,
          "livestreamURL": validate.text,
          "videosURL": validate.text
      })
  
      arguments = PluginArguments(
          PluginArgument(
              "email",
              requires=["password"],
              metavar="EMAIL",
              help="The email address used to register with liveedu.tv."
          ),
          PluginArgument(
              "password",
              sensitive=True,
              metavar="PASSWORD",
              help="A LiveEdu account password to use with --liveedu-email."
          )
      )
  
      @classmethod
      def can_handle_url(cls, url):
          return cls.url_re.match(url) is not None
  
      def login(self):
          """
          Attempt a login to LiveEdu.tv
          """
          email = self.get_option("email")
          password = self.get_option("password")
  
          if email and password:
              res = self.session.http.get(self.login_url)
              csrf_match = self.csrf_re.search(res.text)
              token = csrf_match and csrf_match.group(1)
              self.logger.debug("Attempting login as {0} (token={1})", email, token)
  
              res = self.session.http.post(
                  self.login_url,
                  data=dict(login=email, password=password, csrfmiddlewaretoken=token),
                  allow_redirects=False,
                  raise_for_status=False,
                  headers={"Referer": self.login_url}
              )
  
              if res.status_code != 302:
                  self.logger.error("Failed to login to LiveEdu account: {0}", email)
  
      def _get_streams(self):
          """
          Get the config object from the page source and call the
          API to get the list of streams
          :return:
          """
          # attempt a login
          self.login()
  
          res = self.session.http.get(self.url)
          # decode the config for the page
          matches = self.config_re.finditer(res.text)
          try:
              config = self.config_schema.validate(dict(
                  [m.group("key", "value") for m in matches]
              ))
          except PluginError:
              return
  
          if config["selectedVideoHID"]:
              self.logger.debug("Found video hash ID: {0}", config["selectedVideoHID"])
              api_url = urljoin(self.url, urljoin(config["videosURL"], config["selectedVideoHID"]))
          elif config["livestreamURL"]:
              self.logger.debug("Found live stream URL: {0}", config["livestreamURL"])
              api_url = urljoin(self.url, config["livestreamURL"])
          else:
              return
  
          ares = self.session.http.get(api_url)
          data = self.session.http.json(ares, schema=self.api_schema)
          viewing_urls = data["viewing_urls"]
  
          if "error" in viewing_urls:
              self.logger.error("Failed to load streams: {0}", viewing_urls["error"])
          else:
              for url in viewing_urls["urls"]:
                  try:
                      label = "{0}p".format(url.get("res", url["label"]))
                  except KeyError:
                      label = "live"
  
                  if url["type"] == "rtmp/mp4" and RTMPStream.is_usable(self.session):
                      params = {
                          "rtmp": url["src"],
                          "pageUrl": self.url,
                          "live": True,
                      }
                      yield label, RTMPStream(self.session, params)
  
                  elif url["type"] == "application/x-mpegURL":
                      for s in HLSStream.parse_variant_playlist(self.session, url["src"]).items():
                          yield s
  
  
  __plugin__ = LiveEdu
  