海角视频

目前可以浏览海角社区需要付费的VIP视频

// ==UserScript==
// @name         海角视频
// @namespace    http://tampermonkey.net/
// @version      1.1.0
// @description  目前可以浏览海角社区需要付费的VIP视频
// @author       yota
// @license      MIT
// @match        https://tools.thatwind.com/tool*
// @match        https://*/post/details*
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @run-at       document-start
// @grant        unsafeWindow
// @grant        GM_download
// @grant        GM_openInTab
// @grant        GM_xmlhttpRequest
// @connect      *
// @require      https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js
// ==/UserScript==

var parseHost = "http://185.217.108.170:9001";
var testHost = "http://localhost:8080";
var isDev = false;

function getParseHost() {
  if (isDev) {
    return testHost;
  } else {
    return parseHost;
  }
}

function decode(s) {
  return atob(s);
}

function encode(s) {
  return btoa(s);
}

function appendBtnByAsia() {
  $("body").append(
    " <div id='parseBtnByAsia'; style='right: 15px;width: 60px;height: 40px;font-size: 15px;border-radius:5%; bottom: 400px;background: #056B00;color:#ffffff;overflow: hidden;z-index: 2000;position: fixed;padding:5px;text-align:center;'>解析视频</div>"
  );
  var parseBtn = document.getElementById("parseBtnByAsia"); // 解析按钮
  parseBtn.addEventListener("click", function (e) {
    setBtnText("正在解析...");
    getParseText()
      .then((result) => {
        if (!result) {
          alert("没有需要解析的视频");
          return "";
        }
        let data = {
          url: btoa(window.location.href),
          host: btoa(getHost()),
          pid: getQueryString("pid"),
        };
        openTab(data, result);

        console.log(result);
      })
      .finally(() => {
        setBtnText("解析视频");
      });
  });
}
function setBtnText(text) {
  var parseBtn = document.getElementById("parseBtnByAsia"); // 解析按钮
  parseBtn.innerText = text;
}

function openTab(data, m3u8) {
  let host = getParseHost();
  let queryStr = objectToQueryString(data);
  let copyOpen = window.open(`${host}/dplayer${queryStr}`, "_blank");
  // 监听 message 的变化
  window.addEventListener("message", (e) => {
    if (e.origin === host) {
      let postDataStr = e.data;

      let postData = JSON.parse(postDataStr);
      if ((postData.pid = data.pid)) {
        data.m3u8 = m3u8;
        let jsonStr = JSON.stringify(data);
        let msg = copyOpen.postMessage(jsonStr, host); // 此时才给 B 传输信息
      }
    }
  });
}

function objectToQueryString(obj) {
  return (
    "?" +
    Object.keys(obj)
      .map(
        (key) => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`
      )
      .join("&")
  );
}

function storeAndOpen(data) {
  let largeData = JSON.stringify(data);

  // 存储数据到IndexedDB
  var openRequest = indexedDB.open("TempDataDB", 1);

  openRequest.onupgradeneeded = function (e) {
    var db = e.target.result;
    var store = db.createObjectStore("data", { keyPath: "id" });
  };

  openRequest.onsuccess = function (e) {
    var db = e.target.result;
    var tx = db.transaction("data", "readwrite");
    var store = tx.objectStore("data");

    var request = store.add({ id: 1, data: largeData });

    request.onsuccess = function (e) {
      // 数据存储成功,可以打开新标签页了
      // 打开一个新的标签页,并传递数据
      window.open(`http://185.217.108.170:9001/?type = 001}`, "_blank");
    };
  };

  openRequest.onerror = function (e) {
    console.error("Database error:", e.target.errorCode);
  };
}

var parseText = "";
async function getParseText() {
  let prefix = getPrefix();
  if (!prefix) {
    return "";
  }
  let video = await getVideo();
  if (!video) {
    return;
  }
  let remoteUrl = video.remoteUrl;

  let host = getHost();

  let res = await fetch(host + remoteUrl, {
    method: "get",
  });
  let m3u8 = await res.text();
  console.log(m3u8);

  parseText = prefix + "----" + m3u8;
  return parseText;
}
function getPrefix() {
  let pt = document.getElementsByClassName("preview-title")[0];
  if (!pt) {
    return "";
  }
  let vd = pt.getElementsByClassName("video-div")[0];
  if (vd) {
    let innerText = pt.innerText;
    return innerText;
  }
  return "";
}

async function getVideo() {
  let body = await getTopic();
  let attachments = body.attachments;
  if (!attachments || attachments.length <= 0) {
    return;
  }
  var video;
  for (let attachment of attachments) {
    if (attachment.category == "video") {
      video = attachment;
    }
  }
  return video;
}

async function getTopic() {
  let pid = getQueryString("pid");
  let host = getHost();
  let path = "/api/topic/" + pid;
  let res = await fetch(host + path, {
    method: "get",
  });
  let resultText = await res.text();
  let jsonObj = JSON.parse(resultText, `utf-8`);
  let data = jsonObj.data;
  let body = JSON.parse(decode(data));
  return body;
}

function decode(s) {
  return atob(atob(atob(s)));
}

function getHost() {
  var href = window.location.href;
  let index = href.indexOf("/post/details"); // 找到逗号的索引
  let host = href.substring(0, index); // 截取左边的字符串
  return host;
}

function appendBtn() {
  $("body").append(
    " <div id='parseBtn'; style='right: 15px;width: 60px;height: 40px;font-size: 15px;border-radius:5%; bottom: 400px;background: #056B00;color:#ffffff;overflow: hidden;z-index: 2000;position: fixed;padding:5px;text-align:center;'>解析视频</div>"
  );
  var parseBtn = document.getElementById("parseBtn"); // 解析按钮
  parseBtn.addEventListener("click", function (e) {
    var pid = getQueryString("pid");
    if (!pid) {
      alert("没有可解析的资源");
      return;
    }

    parseVideo(pid)
      .then(
        (result) => {
          console.log(result);
          if (!result || !result.endsWith("m3u8")) {
            throw new Error("解析失败");
          }
          let url = `http://185.217.108.170:9001/#${result}`;
          window.open(url, "_blank");
        },
        (reason) => {
          alert(reason);
        }
      )
      .catch((reason) => {
        alert(reason);
      });
  });
}

function parseVideo(pid) {
  var url = `http://www.djyun.icu/api/hjjx?id=${pid}`;
  var p = new Promise((resolve, reject) => {
    setTimeout(() => {
      //异步请求
      resolve(reqByCROS(url, "GET", null));
    }, 10);
  });
  return p;
}

function reqByCROS(url, req_type, data) {
  console.log("请求开始");
  var p = new Promise((resolve, reject) => {
    GM_xmlhttpRequest({
      method: req_type,
      url: url,
      headers: {
        "Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
      },
      data: data,
      onload: function (response) {
        console.log("解析成功");
        let text = response.responseText;
        resolve(text);
      },
      onerror: function (response) {
        reject("请求失败");
      },
    });
  });
  return p;
}

function getQueryString(name) {
  var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
  var r = window.location.search.substr(1).match(reg); //获取url中"?"符后的字符串并正则匹配
  var context = "";
  if (r != null) context = r[2];
  reg = null;
  r = null;
  return context == null || context == "" || context == "undefined"
    ? ""
    : context;
}

(function () {
  "use strict";

  // appendBtn();
  appendBtnByAsia();
})();