Skip to content

vixsrc proxy #55

@francescodg89-crypto

Description

@francescodg89-crypto

Fix

Fix: HLS Proxy Rewriting for Vixsrc (and similar providers)

Problem Summary

When using the built-in stream proxy (enableProxy: true), streams from Vixsrc (and potentially other providers using similar HLS structures) failed to play with the following errors:

HTTP error 403 Forbidden — sub-playlist video renditions (480p/720p/1080p)
HTTP error 404 Not Found — /storage/enc.key (AES-128 encryption key)

Both errors caused complete playback failure in any HLS-capable player (mpv, VLC, ffmpeg).


Root Cause Analysis

Bug 1 — Video sub-playlists not proxied (403)

The rewriteM3u8 function in proxy/proxyServer.js rewrites URLs found in plain lines (non-# lines) of the master playlist. However, it only proxied URLs ending in .m3u8 or .ts:

if (/\.m3u8(\?|$)/i.test(abs)) {
    out.push(`${baseProxyUrl}/m3u8-proxy?url=...`);
} else if (/\.ts(\?|$)/i.test(abs)) {
    out.push(`${baseProxyUrl}/ts-proxy?url=...`);
} else out.push(line); // ← BUG: URL without extension passed through as-is

Vixsrc sub-playlist URLs look like:

https://vixsrc.to/playlist/214325?type=video&rendition=1080p&token=...&expires=...&edge=sc-u16-01

These have no .m3u8 extension, so they fell into the else branch and were written directly into the rewritten playlist — causing the player to request them without the required Referer and User-Agent headers, resulting in 403 Forbidden.

Bug 2 — AES-128 encryption key not proxied (404)

The #EXT-X-KEY handler used a regex to find the key URL:

const regex = /https?:\/\/[^""\s]+/g;
const keyUrl = regex.exec(line)?.[0];

This regex only matches absolute URLs starting with http:// or https://. However, Vixsrc uses a relative path for the encryption key:

#EXT-X-KEY:METHOD=AES-128,URI="/storage/enc.key",IV=0x...

Since /storage/enc.key doesn't match the regex, keyUrl was null and the line was passed through unchanged. The player then requested /storage/enc.key directly from the proxy server, which has no such route, resulting in 404 Not Found and making all segments undecryptable.


Fix

Fix 1 — Proxy all sub-playlist URLs regardless of extension

In rewriteM3u8, change the fallback else branch to proxy any non-.ts URL as an m3u8:

// Before
} else out.push(line);

// After
} else {
    // Proxy any other URL (e.g. Vixsrc sub-playlists without .m3u8 extension)
    out.push(`${baseProxyUrl}/m3u8-proxy?url=${encodeURIComponent(abs)}&headers=${encodeURIComponent(JSON.stringify(headers))}`);
}

Fix 2 — Handle relative URIs in #EXT-X-KEY

Replace the absolute-only regex with a URI-aware extraction that resolves relative paths against the playlist's base URL:

// Before
if (line.startsWith('#EXT-X-KEY:')) {
    const regex = /https?:\/\/[^""\s]+/g;
    const keyUrl = regex.exec(line)?.[0];
    if (keyUrl) {
        const proxyUrl = `${baseProxyUrl}/ts-proxy?url=${encodeURIComponent(keyUrl)}&headers=...`;
        out.push(line.replace(keyUrl, proxyUrl));
    } else out.push(line);
}

// After
if (line.startsWith('#EXT-X-KEY:')) {
    const uriMatch = line.match(/URI="([^"]+)"/);
    const rawKeyUrl = uriMatch?.[1];
    const keyUrl = rawKeyUrl
        ? (rawKeyUrl.startsWith('http') ? rawKeyUrl : new URL(rawKeyUrl, targetUrl).href)
        : null;
    if (keyUrl) {
        const proxyUrl = `${baseProxyUrl}/ts-proxy?url=${encodeURIComponent(keyUrl)}&headers=...`;
        out.push(line.replace(rawKeyUrl, proxyUrl)); // replace rawKeyUrl, not resolved keyUrl
    } else out.push(line);
}

Key detail: line.replace(rawKeyUrl, proxyUrl) replaces the original string (e.g. /storage/enc.key) in the m3u8 line, not the resolved absolute URL — otherwise the substitution would fail to match.


Result

After both fixes, the full HLS chain passes through the proxy correctly:

Master playlist     → /m3u8-proxy  ✓
Audio sub-playlist  → /m3u8-proxy  ✓
Subtitle playlist   → /m3u8-proxy  ✓
Video sub-playlist  → /m3u8-proxy  ✓  (was bypassing proxy → 403)
AES-128 key         → /ts-proxy    ✓  (was 404, relative URI not resolved)
Video segments (.ts)→ /ts-proxy    ✓

Tested with Vixsrc provider, movie TMDB ID 603 (The Matrix), 1080p stream with Italian audio and subtitles. Playback confirmed working in mpv and VLC.


Affected Providers

Any provider whose master playlist contains:

  • Sub-playlist URLs without .m3u8 extension (query-string based routing)
  • #EXT-X-KEY with a relative URI path

Known affected: Vixsrc. Potentially others with similar CDN setups.


Files Changed

  • proxy/proxyServer.jsrewriteM3u8 function, two locations

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions