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]);
|
||||
|
||||
// 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) {
|
||||
return (
|
||||
<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-session": "^1.18.1",
|
||||
"framer-motion": "^11.13.1",
|
||||
"hls.js": "^1.5.17",
|
||||
"input-otp": "^1.4.2",
|
||||
"lucide-react": "^0.453.0",
|
||||
"memorystore": "^1.6.7",
|
||||
@ -6030,6 +6031,12 @@
|
||||
"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": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http_ece/-/http_ece-1.2.0.tgz",
|
||||
|
||||
@ -86,7 +86,8 @@
|
||||
"wouter": "^3.3.5",
|
||||
"ws": "^8.18.0",
|
||||
"zod": "^3.25.76",
|
||||
"zod-validation-error": "^3.5.4"
|
||||
"zod-validation-error": "^3.5.4",
|
||||
"hls.js": "^1.5.17"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@replit/vite-plugin-cartographer": "^0.4.4",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user