UNPKG

kodikwrapper

Version:
2 lines (1 loc) 3.58 kB
"use strict";var u=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var v=Object.prototype.hasOwnProperty;var m=(i,t)=>u(i,"name",{value:t,configurable:!0});var S=(i,t)=>{for(var e in t)u(i,e,{get:t[e],enumerable:!0})},I=(i,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of b(t))!v.call(i,n)&&n!==e&&u(i,n,{get:()=>t[n],enumerable:!(s=E(t,n))||s.enumerable});return i};var V=i=>I(u({},"__esModule",{value:!0}),i);var O={};S(O,{KODIK_PLAYER_DOMAIN:()=>K,KODIK_VIDEO_INFO_ENDPOINT:()=>y,VideoLinks:()=>P,kodikPlayerLinkRegexp:()=>L});module.exports=V(O);var a=require("./errors");const K="kodik.info",y="/ftor",L=/^(?<protocol>http[s]?:|)\/\/(?<host>[a-z0-9]+\.[a-z]+)\/(?<type>[a-z]+)\/(?<id>\d+)\/(?<hash>[0-9a-z]+)\/(?<quality>\d+p)(?:.*)$/;class P{static{m(this,"VideoLinks")}static async parseLink({extended:t,link:e}){if(!e)throw new a.VideoLinksError({code:"parse-link-invalid",description:"link is not provided",data:{link:e}});const s=this.normalizeKodikLink(e);if(!L.test(e))throw new a.VideoLinksError({code:"parse-link-invalid",description:"link is not valid",data:{link:e}});const n=L.exec(s).groups,{host:x,hash:f,id:d,quality:o,type:l}=n,g={host:x,hash:f,id:d,quality:o,type:l};if(!t)return g;const r=await fetch(s).then(w=>w.text()),c=r.match(/var\s+urlParams\s*=\s*'(?<urlParams>[^']+)';/)?.groups?.urlParams,k=r.match(/var\s+translationId\s*=\s*(?<id>\d+);\s*var\s+translationTitle\s*=\s*"(?<title>[^"]+)";/is)?.groups,h=r.match(/parseSkipButtons?\("(?<data>[^"]+)"\s*,\s*"(?<type>[^"]+)"\)/is)?.groups,p=r.match(/src="(?<link>\/assets\/js\/app\.player_single\.[a-z0-9]+\.js)"/is)?.groups?.link;if(!c)throw new a.VideoLinksError({code:"parse-link-ex-invalid",description:"cannot get url params",data:{link:e,page:r}});if(!k)throw new a.VideoLinksError({code:"parse-link-ex-invalid",description:"cannot get translation",data:{link:e,page:r}});return{...g,ex:{urlParams:JSON.parse(c),translation:{id:+k.id,title:k.title},skipButtons:{...h},playerSingleUrl:p}}}static normalizeKodikLink(t){return t.startsWith("//")?`https:${t}`:t.startsWith("http")?t:new URL(t,`https://${K}`).toString()}static async getActualVideoInfoEndpoint(t){const e=await fetch(this.normalizeKodikLink(t)).then(n=>n.text());return atob(e.match(/type:"POST",url:atob\("(?<b64str>[^"]+)"\)/i)?.groups?.b64str??"")||"/kor"}static async getLinks({link:t,videoInfoEndpoint:e=y}){const{host:s,quality:n,...x}=await P.parseLink({link:t}),f=new URL(`${e}?${new URLSearchParams(x).toString()}`,`https://${s}`),d=await fetch(f);if(d.headers.get("content-type")!=="application/json")throw new a.VideoLinksError({code:"get-links-invalid-response",description:"videoInfoResponse is not json",data:{videoInfoResponse:d}});const o=await d.json();if(typeof o!="object"||o===null)throw new a.VideoLinksError({code:"get-links-invalid-response",description:"videoInfoJson is not object",data:{videoInfoResponse:d,videoInfoJson:o}});if(typeof o.links!="object")throw new a.VideoLinksError({code:"get-links-invalid-response",description:"videoInfoJson.links is not object",data:{videoInfoResponse:d,videoInfoJson:o}});const l=o.links,g="Z".charCodeAt(0);for(const[,r]of Object.entries(l))for(const c of r){const k=c.src.replace(/[a-zA-Z]/g,h=>{let p=h.charCodeAt(0);return String.fromCharCode((p<=g?90:122)>=(p=p+18)?p:p-26)});c.src=atob(k)}return l}static parseSkipButtons=t=>t.data.split(",").map(e=>{const[s,n]=e.split("-");return{from:s,to:n}})}0&&(module.exports={KODIK_PLAYER_DOMAIN,KODIK_VIDEO_INFO_ENDPOINT,VideoLinks,kodikPlayerLinkRegexp});