Edit: bittvcuri
Nama Worker
Kode Sumber
// Konfigurasi repositori GitHub Anda const GITHUB_USERNAME = 'brodatv1'; const GITHUB_REPO = 'jsonp'; const GITHUB_BRANCH = 'master'; const GITHUB_FOLDER = 'mio'; const JSON_FILES = [ 'AA.json', 'AU.json', 'BR.json', 'EV.json', 'GB.json', 'ID.json', 'JP.json', 'KD.json', 'KR.json', 'LO.json', 'MI.json', 'MY.json', 'RI.json', 'SA.json', 'SG.json', 'SP.json' ]; const BASE_URL = `https://raw.githubusercontent.com/${GITHUB_USERNAME}/${GITHUB_REPO}/${GITHUB_BRANCH}/${GITHUB_FOLDER}/`; // --- Helper Function --- // Fungsi untuk mengubah string Base64URL menjadi HEX function b64urlToHex(b64url) { const base64 = b64url.replace(/-/g, '+').replace(/_/g, '/'); const raw = atob(base64); let hex = ''; for (let i = 0; i < raw.length; i++) { const byte = raw.charCodeAt(i); hex += ('0' + byte.toString(16)).slice(-2); } return hex; } addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)); }); async function handleRequest(request) { try { const allJsonPromises = JSON_FILES.map(file => fetch(BASE_URL + file).then(res => res.ok ? res.json() : null) ); const allJsonData = await Promise.all(allJsonPromises); let m3uContent = '#EXTM3U\n'; allJsonData.forEach(jsonData => { if (jsonData && Array.isArray(jsonData.info)) { const groupName = jsonData.country_name || 'General'; const channels = jsonData.info; channels.forEach(channel => { const isChannelValid = channel && typeof channel === 'object' && channel.name && typeof channel.name === 'string' && channel.name.trim() !== '' && channel.hls && typeof channel.hls === 'string' && channel.hls.trim() !== ''; if (isChannelValid) { const logo = channel.image ? `tvg-logo="${channel.image}"` : ''; m3uContent += `#EXTINF:-1 ${logo} group-title="${groupName}",${channel.name}\n`; // ---- LOGIKA BARU UNTUK LISENSI & HEADER ---- if (channel.jenis === 'dash-clearkey' && channel.url_license) { m3uContent += `#KODIPROP:inputstream.adaptive.license_type=clearkey\n`; let licenseKey = channel.url_license; // Coba konversi dari format JSON Base64 ke KID:KEY HEX try { const decodedLicense = atob(channel.url_license); const licenseJson = JSON.parse(decodedLicense); if (licenseJson.keys && licenseJson.keys[0]) { const kid = b64urlToHex(licenseJson.keys[0].kid); const key = b64urlToHex(licenseJson.keys[0].k); licenseKey = `${kid}:${key}`; } } catch (e) { // Jika gagal (formatnya bukan JSON Base64), gunakan nilai aslinya. } m3uContent += `#KODIPROP:inputstream.adaptive.license_key=${licenseKey}\n`; } if (channel.header_iptv) { try { const headers = JSON.parse(channel.header_iptv); if (headers['User-Agent'] && headers['User-Agent'] !== 'none') { m3uContent += `#EXTVLCOPT:http-user-agent=${headers['User-Agent']}\n`; } if (headers['Referer'] && headers['Referer'] !== 'none') { m3uContent += `#EXTVLCOPT:http-referrer=${headers['Referer']}\n`; } if (headers['Origin'] && headers['Origin'] !== 'none') { m3uContent += `#EXTVLCOPT:http-origin=${headers['Origin']}\n`; } } catch (e) { /* Abaikan jika error */ } } // --------------------------------------------- m3uContent += `${channel.hls}\n`; } }); } }); return new Response(m3uContent, { headers: { 'Content-Type': 'application/vnd.apple.mpegurl; charset=utf-8', 'Access-Control-Allow-Origin': '*' }, }); } catch (error) { return new Response(`Error: ${error.message}`, { status: 500 }); } }
Bindings
Tambah KV
Tambah R2
Tambah D1
← Kembali
Simpan & Deploy
Hapus Script Worker Ini