private void decryptRelinker(
      final String relinker_url,
      String title,
      String extension,
      final FilePackage fp,
      final String description)
      throws Exception {
    String dllink = relinker_url;
    if (extension != null && extension.equalsIgnoreCase("wmv")) {
      /* E.g. http://www.tg1.rai.it/dl/tg1/2010/rubriche/ContentItem-9b79c397-b248-4c03-a297-68b4b666e0a5.html */
      logger.info("Download http .wmv video");
    } else {
      final String cont = jd.plugins.hoster.RaiTv.getContFromRelinkerUrl(relinker_url);
      if (cont == null) {
        throw new DecrypterException(DecrypterException.PLUGIN_DEFECT);
      }
      /* Drop previous Headers & Cookies */
      this.br = jd.plugins.hoster.RaiTv.prepVideoBrowser(new Browser());
      jd.plugins.hoster.RaiTv.accessCont(this.br, cont);

      if (this.br.containsHTML("video_no_available\\.mp4")) {
        /* Offline/Geo-Blocked */
        /* XML response with e.g. this (and some more): <url>http://download.rai.it/video_no_available.mp4</url> */
        final DownloadLink offline = this.createOfflinelink(relinker_url);
        if (title == null) {
          title = cont;
        }
        offline.setName("GEOBLOCKED_" + title);
        this.decryptedLinks.add(offline);
        return;
      }

      dllink = jd.plugins.hoster.RaiTv.getDllink(this.br);
      if (dllink == null) {
        throw new DecrypterException(DecrypterException.PLUGIN_DEFECT);
      }
      if (extension == null && dllink.contains(".mp4")) {
        extension = "mp4";
      } else if (extension == null && dllink.contains(".wmv")) {
        extension = "wmv";
      } else if (extension == null) {
        /* Final fallback */
        extension = "mp4";
      }
      if (!jd.plugins.hoster.RaiTv.dllinkIsDownloadable(dllink)) {
        logger.info("Unsupported streaming protocol");
        throw new DecrypterException(DecrypterException.PLUGIN_DEFECT);
      }
    }
    final Regex hdsconvert =
        new Regex(dllink, "(https?://[^/]+/z/podcastcdn/.+\\.csmil)/manifest\\.f4m");
    if (hdsconvert.matches()) {
      /* Convert hds --> hls */
      dllink = hdsconvert.getMatch(0).replace("/z/", "/i/") + "/index_1_av.m3u8";
    }
    if (dllink.contains(".m3u8")) {
      this.br.getPage(dllink);
      final List<HlsContainer> allqualities = HlsContainer.getHlsQualities(this.br);
      for (final HlsContainer singleHlsQuality : allqualities) {
        final DownloadLink dl = this.createDownloadlink(singleHlsQuality.downloadurl);
        final String filename = title + "_" + singleHlsQuality.getStandardFilename();
        dl.setFinalFileName(filename);
        dl._setFilePackage(fp);
        if (description != null) {
          dl.setComment(description);
        }
        decryptedLinks.add(dl);
      }
    } else {
      /* Single http url --> We can sometimes grab multiple qualities */
      if (dllink.contains("_1800.mp4")) {
        /* Multiple qualities availab.e */
        final String[][] bitrates = {{"1800", "_1800.mp4"}, {"800", "_800.mp4"}};
        for (final String[] qualityInfo : bitrates) {
          final String bitrate = qualityInfo[0];
          final String url_bitrate_string = qualityInfo[1];
          final String directlink = dllink.replace("_1800.mp4", url_bitrate_string);
          final DownloadLink dl = this.createDownloadlink("directhttp://" + directlink);
          dl.setFinalFileName(title + "_" + bitrate + "." + extension);
          dl._setFilePackage(fp);
          if (description != null) {
            dl.setComment(description);
          }
          this.decryptedLinks.add(dl);
        }
      } else {
        /* Only one quality available. */
        final DownloadLink dl = this.createDownloadlink("directhttp://" + dllink);
        dl.setFinalFileName(title + "." + extension);
        dl._setFilePackage(fp);
        if (description != null) {
          dl.setComment(description);
        }
        this.decryptedLinks.add(dl);
      }
    }
  }
  private void decryptSingleVideo() throws DecrypterException, Exception {
    String dllink = null;
    String title = null;
    String extension = ".mp4";
    String date = null;
    String date_formatted = null;
    String description = null;

    this.br.getPage(this.parameter);
    final String jsredirect =
        this.br.getRegex("document\\.location\\.replace\\(\\'(http[^<>\"]*?)\\'\\)").getMatch(0);
    if (jsredirect != null) {
      this.br.getPage(jsredirect.trim());
    }
    if (this.br.getHttpConnection().getResponseCode() == 404) {
      decryptedLinks.add(this.createOfflinelink(this.parameter));
      return;
    }
    /* Do NOT use value of "videoURL_MP4" here! */
    /* E.g. http://www.rai.tv/dl/RaiTV/programmi/media/ContentItem-70996227-7fec-4be9-bc49-ba0a8104305a.html */
    dllink =
        this.br
            .getRegex("var[\t\n\r ]*?videoURL[\t\n\r ]*?=[\t\n\r ]*?\"(http://[^<>\"]+)\"")
            .getMatch(0);
    String content_id_from_url = null;
    if (this.parameter.matches(TYPE_CONTENTITEM)) {
      content_id_from_url = new Regex(this.parameter, "(\\-[a-f0-9\\-]+)\\.html$").getMatch(0);
    }
    if (dllink == null) {
      dllink = findRelinkerUrl();
    }
    title = this.br.getRegex("property=\"og:title\" content=\"([^<>\"]+)\"").getMatch(0);
    date =
        this.br
            .getRegex(
                "content=\"(\\d{4}\\-\\d{2}\\-\\d{2}) \\d{2}:\\d{2}:\\d{2}\" property=\"gen\\-date\"")
            .getMatch(0);

    final String contentset_id =
        this.br
            .getRegex(
                "var[\t\n\r ]*?urlTop[\t\n\r ]*?=[\t\n\r ]*?\"[^<>\"]+/ContentSet([A-Za-z0-9\\-]+)\\.html")
            .getMatch(0);
    final String content_id_from_html =
        this.br.getRegex("id=\"ContentItem(\\-[a-f0-9\\-]+)\"").getMatch(0);
    if (br.getHttpConnection().getResponseCode() == 404
        || (contentset_id == null && content_id_from_html == null && dllink == null)) {
      /* Probably not a video/offline */
      decryptedLinks.add(this.createOfflinelink(this.parameter));
      return;
    }
    if (dllink != null) {
      if (title == null) {
        /* Streamurls directly in html */
        title = this.br.getRegex("id=\"idMedia\">([^<>]+)<").getMatch(0);
      }
      if (title == null) {
        title = this.br.getRegex("var videoTitolo\\d*?=\\d*?\"([^<>\"]+)\";").getMatch(0);
      }
      if (date == null) {
        date =
            this.br
                .getRegex("id=\"myGenDate\">(\\d{2}\\-\\d{2}\\-\\d{4} \\d{2}:\\d{2})<")
                .getMatch(0);
      }
      if (date == null) {
        /* 2017-01-06: New */
        date =
            this.br
                .getRegex(
                    "property=\"gen\\-date\" content=\"(\\d{4}\\-\\d{2}\\-\\d{2} \\d{2}:\\d{2}:\\d{2})\"")
                .getMatch(0);
      }
      if (date == null) {
        date = this.br.getRegex("data\\-date=\"(\\d{2}/\\d{2}/\\d{4})\"").getMatch(0);
      }
    } else {
      LinkedHashMap<String, Object> entries = null;
      if (content_id_from_html != null) {
        /* Easiest way to find videoinfo */
        this.br.getPage(
            "http://www.rai.tv/dl/RaiTV/programmi/media/ContentItem"
                + content_id_from_html
                + ".html?json");
        entries =
            (LinkedHashMap<String, Object>) JavaScriptEngineFactory.jsonToJavaObject(br.toString());
      }
      if (entries == null) {
        final ArrayList<Object> ressourcelist;
        final String list_json_from_html =
            this.br
                .getRegex("\"list\"[\t\n\r ]*?:[\t\n\r ]*?(\\[.*?\\}[\t\n\r ]*?\\])")
                .getMatch(0);
        if (list_json_from_html != null) {
          ressourcelist =
              (ArrayList<Object>) JavaScriptEngineFactory.jsonToJavaObject(list_json_from_html);
        } else {
          br.getPage(
              "http://www.rai.tv/dl/RaiTV/ondemand/ContentSet" + contentset_id + ".html?json");
          if (br.getHttpConnection().getResponseCode() == 404) {
            decryptedLinks.add(this.createOfflinelink(this.parameter));
            return;
          }
          entries =
              (LinkedHashMap<String, Object>)
                  JavaScriptEngineFactory.jsonToJavaObject(br.toString());
          ressourcelist = (ArrayList<Object>) entries.get("list");
        }

        if (content_id_from_url == null) {
          /* Hm probably not a video */
          decryptedLinks.add(this.createOfflinelink(this.parameter));
          return;
        }
        String content_id_temp = null;
        boolean foundVideoInfo = false;
        for (final Object videoo : ressourcelist) {
          entries = (LinkedHashMap<String, Object>) videoo;
          content_id_temp = (String) entries.get("itemId");
          if (content_id_temp != null && content_id_temp.contains(content_id_from_url)) {
            foundVideoInfo = true;
            break;
          }
        }
        if (!foundVideoInfo) {
          /* Probably offline ... */
          decryptedLinks.add(this.createOfflinelink(this.parameter));
          return;
        }
      }
      date = (String) entries.get("date");
      title = (String) entries.get("name");
      description = (String) entries.get("desc");
      final String type = (String) entries.get("type");
      if (type.equalsIgnoreCase("RaiTv Media Video Item")) {
      } else {
        /* TODO */
        logger.warning("Unsupported media type!");
        throw new DecrypterException(DecrypterException.PLUGIN_DEFECT);
      }
      extension = "mp4";
      dllink = (String) entries.get("h264");
      if (dllink == null || dllink.equals("")) {
        dllink = (String) entries.get("m3u8");
        extension = "mp4";
      }
      if (dllink == null || dllink.equals("")) {
        dllink = (String) entries.get("wmv");
        extension = "wmv";
      }
      if (dllink == null || dllink.equals("")) {
        dllink = (String) entries.get("mediaUri");
        extension = "mp4";
      }
    }
    if (title == null) {
      title = content_id_from_url;
    }
    date_formatted = jd.plugins.hoster.RaiTv.formatDate(date);
    title = Encoding.htmlDecode(title);
    title = date_formatted + "_raitv_" + title;
    title = encodeUnicode(title);

    final FilePackage fp = FilePackage.getInstance();
    fp.setName(title);

    decryptRelinker(dllink, title, extension, fp, description);
  }