Self-hosted Node.js HLS stream resolver. Paste a Ployan embed page URL, resolve it to a direct M3U8 master playlist through a local REST API, decode the base64 player origin, build AES-256-GCM session tokens, and play back in the browser. Zero npm runtime dependencies.
- Fetches embed page HTML and extracts
mediaIdfromdata-idattributes or the URL slug - Decodes the base64
plyURLconstant in page JavaScript to discover the player origin - Builds a time-bound token from
{mediaId}+{episode}+{server}+{timestamp}with PBKDF2 and AES-256-GCM - Calls
{origin}/get/{token}and mapsdirectmode to{origin}/hls/{info}/master.m3u8 - Serves a small web UI with Safari native HLS playback and M3U8 copy for other browsers
npm startOpen http://127.0.0.1:8765, paste a Ployan embed page URL, click Resolve.
Requires Node.js 18+ (native fetch). Runs as a local HTTP server on port 8765 by default (PORT env override).
flowchart LR
Browser["Browser UI\npublic/"]
Server["HTTP server\nsrc/server/"]
Routes["API routes\nsrc/api/"]
Embed["Embed parser\nsrc/embed/"]
Ployan["Ployan client\nsrc/ployan/"]
Upstream["Embed + player hosts"]
Browser -->|"/api/stream"| Server
Server --> Routes
Routes -->|resolve| Embed
Routes --> Ployan
Embed --> Upstream
Ployan --> Upstream
- Parse page —
src/embed/parse.jsfetches embed HTML, extractsmediaId, decodesplyURL, reads the page title - Seal token —
src/ployan/stream.jsencrypts{mediaId}+{episode}+1+{unixTimestamp}with PBKDF2-SHA256 and AES-256-GCM - Stream lookup —
GET {origin}/get/{token}with player referer returnsmodeand an opaqueinfovalue - M3U8 URL — when
modeisdirect, the HLS master playlist is{origin}/hls/{info}/master.m3u8 - Response — JSON with
title,url, andmodereturned to the browser or API client
src/
server/index.js HTTP entry, static files, CORS
api/routes.js GET /api/health, GET /api/stream
core/resolve.js parse → fetch orchestration
embed/parse.js embed HTML extraction
ployan/stream.js AES token builder and /get client
lib/
config.js host, port, user-agent
http.js upstream fetch helpers
public/
index.html UI shell and styles
app.js resolve, playback, copy
Resolves a Ployan embed page URL to a direct HLS master playlist link.
| Param | Required | Description |
|---|---|---|
url |
yes | Full embed page URL |
episode |
no | Episode number in the token payload (default 1) |
Response
{
"title": "Show Title",
"url": "https://player.example/hls/abc123/master.m3u8",
"mode": "direct"
}url is set only when /get returns mode: "direct". Resolver errors return HTTP 502 with { "error": "…" }.
{ "ok": true }The embed page must expose a Ployan player script with a base64 plyURL constant and a numeric mediaId via data-id on the player element (or a trailing -{id} slug in the URL path). The embed site and player host must be reachable from the machine running this server.
- Node.js ES modules, zero npm runtime dependencies
- Native
fetch,node:http,node:crypto - Safari native HLS in the web UI; VLC or Stremio for other browsers