MovixOpenSource/extension/Chrome/injected.js
Movix eae5a24c51 feat: ajoute KissKH et fiabilise les sources, les sous-titres et le Cast — Android 2.5.8
- corrige l’extraction Fsvid/Vidzy dans proxiesembed, les extensions et le userscript avec un décodage XOR/P.A.C.K.E.R plus robuste
- rejette les URL « troll » et supprime les résultats Fsvid/Vidzy contaminés des caches
- ajoute KissKH pour les films et séries avec matching TMDB, catalogue, cache distribué, verrouillage, rotation des proxys et fallback sécurisé
- ajoute le relais KissKH HLS/MP4 dans proxiesembed, avec retry SOCKS5 sur les erreurs 403 et streaming des segments BYTERANGE
- prend en charge les sous-titres KissKH SRT/TXT/TXT2, leur déchiffrement AES et leur conversion en WebVTT
- intègre KissKH au lecteur, aux priorités de sources, aux extensions Chrome/Firefox et au userscript
- améliore la sélection, le formatage sécurisé, la traduction et l’affichage Picture-in-Picture des sous-titres
- corrige le Cast web et Android pour transmettre les sous-titres internes, externes, KissKH et traduits
- ajoute le support des pistes WebVTT inline via le relais LAN Android et améliore le suivi des sessions Cast
- protège les liens jouables des caches Cpasmal et Coflix contre les rafraîchissements vides ou concurrents
- fiabilise la sélection des saisons FStream et améliore le matching DarkiWorld par TMDB, titre et année
- simplifie les nouvelles URL TMDB tout en conservant le décodage des anciens identifiants encodés
- corrige l’opacité des icônes SVG dans toute l’interface en séparant la couleur de leur niveau d’opacité
- met à jour le Dockerfile vers Node.js 22 et installe uniquement les dépendances runtime du workspace Hono
- ajoute le workspace server avec ses dépendances dédiées et un arrêt gracieux sur SIGTERM/SIGINT
- accélère le healthcheck Docker et évite de recopier tous les node_modules du builder dans l’image finale
- retire les migrations et créations de tables automatiques au démarrage de la Main API au profit de db:init
- attribue un port CycleTLS distinct à chaque worker pour éviter les conflits en mode cluster
- ajoute des tests de non-régression pour KissKH, les caches de sources, CycleTLS et le Cast Android
- publie Android 2.5.8 build 17 avec le nouvel APK
- met à jour les extensions Chrome 1.3.13 et Firefox 1.5.10

Co-authored-by: GPT-5.6 Sol <noreply@openai.com>
2026-08-03 21:37:41 +02:00

177 lines
6.6 KiB
JavaScript

window.hasMovixExtension = true;
window.hasMovixNexusExtractor = true; // Signals that M3U8 extraction is available locally
window.dispatchEvent(new CustomEvent('movix-extension-loaded'));
console.log("Movix Extension loaded in page context (with Nexus M3U8 extractors)");
window.movixKisskhFallback = function(request) {
return new Promise((resolve) => {
const messageId = 'kisskh_' + Date.now() + '_' + Math.random().toString(36).substr(2, 8);
let settled = false;
let timeoutId;
const cleanup = () => {
window.removeEventListener('message', handler);
if (timeoutId !== undefined) clearTimeout(timeoutId);
};
const finish = (result) => {
if (settled) return;
settled = true;
cleanup();
resolve(result);
};
const handler = (event) => {
if (event.data && event.data.source === 'MOVIX_EXTENSION' && event.data.messageId === messageId) {
finish(event.data.success
? event.data.data
: { success: false, code: 'unsupported_transport' });
}
};
window.addEventListener('message', handler);
timeoutId = setTimeout(() => {
finish({ success: false, code: 'timeout' });
}, 15000);
window.postMessage({
source: 'MOVIX_WEB',
type: 'EXTENSION_REQUEST',
action: 'KISSKH_FALLBACK',
messageId,
payload: request
}, '*');
});
};
/**
* Helper: Extract M3U8 from a single embed URL via the extension
* Usage: const result = await window.movixExtractM3u8('voe', 'https://voe.sx/xxx');
* or: const result = await window.movixExtractM3u8(null, 'https://vidzy.org/xxx'); // auto-detect
* Returns: { success, hlsUrl?, m3u8Url?, source?, error? }
*/
window.movixExtractM3u8 = function(type, url) {
return new Promise((resolve, reject) => {
const messageId = 'nexus_' + Date.now() + '_' + Math.random().toString(36).substr(2, 6);
const handler = (event) => {
if (event.data && event.data.source === 'MOVIX_EXTENSION' && event.data.messageId === messageId) {
window.removeEventListener('message', handler);
if (event.data.success) {
resolve(event.data.data);
} else {
resolve({ success: false, error: event.data.error });
}
}
};
window.addEventListener('message', handler);
// Timeout after 15s
setTimeout(() => {
window.removeEventListener('message', handler);
resolve({ success: false, error: 'Extraction timeout' });
}, 15000);
window.postMessage({
source: 'MOVIX_WEB',
type: 'EXTENSION_REQUEST',
action: 'EXTRACT_M3U8',
messageId,
payload: { type, url }
}, '*');
});
};
/**
* Helper: Extract all M3U8 from a list of embed sources in parallel
* Usage: const results = await window.movixExtractAllM3u8(['https://voe.sx/x', 'https://vidzy.org/y']);
* or with player info: await window.movixExtractAllM3u8([{link:'url', player:'voe'}]);
* Returns: { success, total, successCount, results: [...] }
*/
window.movixExtractAllM3u8 = function(sources) {
return new Promise((resolve, reject) => {
const messageId = 'nexus_all_' + Date.now() + '_' + Math.random().toString(36).substr(2, 6);
const handler = (event) => {
if (event.data && event.data.source === 'MOVIX_EXTENSION' && event.data.messageId === messageId) {
window.removeEventListener('message', handler);
if (event.data.success) {
resolve(event.data.data);
} else {
resolve({ success: false, error: event.data.error, results: [] });
}
}
};
window.addEventListener('message', handler);
// Timeout after 30s for batch extraction
setTimeout(() => {
window.removeEventListener('message', handler);
resolve({ success: false, error: 'Bulk extraction timeout', results: [] });
}, 30000);
window.postMessage({
source: 'MOVIX_WEB',
type: 'EXTENSION_REQUEST',
action: 'EXTRACT_ALL_M3U8',
messageId,
payload: { sources }
}, '*');
});
};
/**
* Helper: Detect supported embed types from a list of URLs
* Usage: const embeds = await window.movixDetectEmbeds(['url1', 'url2']);
* Returns: { embeds: [{type, url, priority}, ...] }
*/
window.movixDetectEmbeds = function(sources) {
return new Promise((resolve) => {
const messageId = 'nexus_detect_' + Date.now() + '_' + Math.random().toString(36).substr(2, 6);
const handler = (event) => {
if (event.data && event.data.source === 'MOVIX_EXTENSION' && event.data.messageId === messageId) {
window.removeEventListener('message', handler);
resolve(event.data.success ? event.data.data : { embeds: [] });
}
};
window.addEventListener('message', handler);
setTimeout(() => { window.removeEventListener('message', handler); resolve({ embeds: [] }); }, 5000);
window.postMessage({
source: 'MOVIX_WEB',
type: 'EXTENSION_REQUEST',
action: 'DETECT_EMBEDS',
messageId,
payload: { sources }
}, '*');
});
};
/**
* Helper: Setup DNR headers for a service URL (e.g. cinep for PurStream)
* Usage: await window.movixSetupHeaders('cinep', 'https://zebi.xalaflix.design/...');
*/
window.movixSetupHeaders = function(type, url) {
return new Promise((resolve) => {
const messageId = 'nexus_headers_' + Date.now() + '_' + Math.random().toString(36).substr(2, 6);
const handler = (event) => {
if (event.data && event.data.source === 'MOVIX_EXTENSION' && event.data.messageId === messageId) {
window.removeEventListener('message', handler);
resolve(event.data.success ? event.data.data : { success: false, error: event.data.error });
}
};
window.addEventListener('message', handler);
setTimeout(() => { window.removeEventListener('message', handler); resolve({ success: false, error: 'Timeout' }); }, 3000);
window.postMessage({
source: 'MOVIX_WEB',
type: 'EXTENSION_REQUEST',
action: 'SETUP_HEADERS',
messageId,
payload: { type, url }
}, '*');
});
};