article.tsx: transform Bunny iframe → folxvideos HLS player when S3 available
This commit is contained in:
parent
c8b0989d4c
commit
6c34d44cea
@ -204,6 +204,64 @@ export default function ArticlePage() {
|
|||||||
}
|
}
|
||||||
}, [article?.content]);
|
}, [article?.content]);
|
||||||
|
|
||||||
|
// Replace Bunny iframe embeds with native HLS player (folxvideos S3 origin)
|
||||||
|
useEffect(() => {
|
||||||
|
if (!article?.content) return;
|
||||||
|
let cancelled = false;
|
||||||
|
|
||||||
|
const loadHlsJs = (): Promise<any> => new Promise((resolve, reject) => {
|
||||||
|
if ((window as any).Hls) return resolve((window as any).Hls);
|
||||||
|
const s = document.createElement("script");
|
||||||
|
s.src = "https://cdn.jsdelivr.net/npm/hls.js@1.5.17/dist/hls.min.js";
|
||||||
|
s.async = true;
|
||||||
|
s.onload = () => resolve((window as any).Hls);
|
||||||
|
s.onerror = reject;
|
||||||
|
document.head.appendChild(s);
|
||||||
|
});
|
||||||
|
|
||||||
|
const transform = async () => {
|
||||||
|
const iframes = document.querySelectorAll<HTMLIFrameElement>(
|
||||||
|
'iframe[src*="mediadelivery.net/embed/"], iframe[src*="iframe.mediadelivery.net/embed/"]'
|
||||||
|
);
|
||||||
|
if (iframes.length === 0) return;
|
||||||
|
let Hls: any = null;
|
||||||
|
try { Hls = await loadHlsJs(); } catch {}
|
||||||
|
for (const iframe of Array.from(iframes)) {
|
||||||
|
if (cancelled) break;
|
||||||
|
const m = iframe.src.match(/embed\/\d+\/([a-f0-9-]+)/i);
|
||||||
|
if (!m) continue;
|
||||||
|
const guid = m[1];
|
||||||
|
const folxUrl = `https://folxvideos.b-cdn.net/folx-tv/${guid}/master.m3u8`;
|
||||||
|
try {
|
||||||
|
const head = await fetch(folxUrl, { method: "HEAD" });
|
||||||
|
if (!head.ok) continue;
|
||||||
|
} catch { continue; }
|
||||||
|
const video = document.createElement("video");
|
||||||
|
video.controls = true;
|
||||||
|
video.preload = "metadata";
|
||||||
|
video.playsInline = true;
|
||||||
|
video.style.cssText = iframe.getAttribute("style") || "width:100%;aspect-ratio:16/9;border:none;";
|
||||||
|
video.className = iframe.className || "";
|
||||||
|
if (Hls && Hls.isSupported()) {
|
||||||
|
const hls = new Hls();
|
||||||
|
hls.loadSource(folxUrl);
|
||||||
|
hls.attachMedia(video);
|
||||||
|
} else if (video.canPlayType("application/vnd.apple.mpegurl")) {
|
||||||
|
video.src = folxUrl;
|
||||||
|
} else {
|
||||||
|
continue; // can't play, keep iframe
|
||||||
|
}
|
||||||
|
iframe.replaceWith(video);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Run after content is in DOM (next tick)
|
||||||
|
const t = setTimeout(transform, 50);
|
||||||
|
return () => { cancelled = true; clearTimeout(t); };
|
||||||
|
}, [article?.content]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-background">
|
<div className="min-h-screen bg-background">
|
||||||
|
|||||||
7
package-lock.json
generated
7
package-lock.json
generated
@ -56,6 +56,7 @@
|
|||||||
"express": "^5.0.1",
|
"express": "^5.0.1",
|
||||||
"express-session": "^1.18.1",
|
"express-session": "^1.18.1",
|
||||||
"framer-motion": "^11.13.1",
|
"framer-motion": "^11.13.1",
|
||||||
|
"hls.js": "^1.5.17",
|
||||||
"input-otp": "^1.4.2",
|
"input-otp": "^1.4.2",
|
||||||
"lucide-react": "^0.453.0",
|
"lucide-react": "^0.453.0",
|
||||||
"memorystore": "^1.6.7",
|
"memorystore": "^1.6.7",
|
||||||
@ -6030,6 +6031,12 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/hls.js": {
|
||||||
|
"version": "1.6.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.6.16.tgz",
|
||||||
|
"integrity": "sha512-VSIRpLfRwlAAdGL4wiTucx2ScRipo0ed1FBatWkyt832jC4CReKstga6yIhYVwGu9LOBjuX9wzmRMeQdBJtzEA==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/http_ece": {
|
"node_modules/http_ece": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/http_ece/-/http_ece-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/http_ece/-/http_ece-1.2.0.tgz",
|
||||||
|
|||||||
@ -86,7 +86,8 @@
|
|||||||
"wouter": "^3.3.5",
|
"wouter": "^3.3.5",
|
||||||
"ws": "^8.18.0",
|
"ws": "^8.18.0",
|
||||||
"zod": "^3.25.76",
|
"zod": "^3.25.76",
|
||||||
"zod-validation-error": "^3.5.4"
|
"zod-validation-error": "^3.5.4",
|
||||||
|
"hls.js": "^1.5.17"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@replit/vite-plugin-cartographer": "^0.4.4",
|
"@replit/vite-plugin-cartographer": "^0.4.4",
|
||||||
@ -121,4 +122,4 @@
|
|||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"bufferutil": "^4.0.8"
|
"bufferutil": "^4.0.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user