مفت ٹول - کوئی اکاؤنٹ ضروری نہیں

مفت M3U اور IPTV پلے لسٹ ویلیڈیٹر

اپنی M3U، M3U8 یا IPTV پلے لسٹ آن لائن چیک اور تصدیق کریں۔ غلطیاں، گمشدہ ہیڈرز، غلط URLs اور ڈپلیکیٹ چینلز فوری طور پر ڈیٹیکٹ کرتا ہے۔

اپنی M3U فائل یہاں ڈریگ اینڈ ڈراپ کریں

یا

.m3u اور .m3u8 سپورٹڈ - آپ کے براؤزر میں مقامی طور پر پروسیس - ہمارے سرورز پر کبھی اپلوڈ نہیں

100% نجی

آپ کی فائل آپ کے براؤزر سے کبھی نہیں نکلتی۔ تمام پروسیسنگ مقامی طور پر چلتی ہے - ہمارے سرورز کو کچھ نہیں بھیجا جاتا۔

فوری نتائج

تصدیق ملی سیکنڈ میں مکمل ہوتی ہے، یہاں تک کہ ہزاروں چینلز والی بڑی پلے لسٹ کے لیے بھی۔

تفصیلی رپورٹ

#EXTM3U ہیڈر کی غیر موجودگی، غلط URLs، group-title صفات کی غیر موجودگی اور ڈپلیکیٹ چینلز کی جانچ کرتا ہے۔

اپنی پلے لسٹ کے ساتھ مزید کرنا چاہتے ہیں؟

چینلز فلٹر کرنے، کسٹم پلے لسٹ بنانے اور انہیں سورس فائل کے ساتھ خودکار طور پر مطابقت پذیر رکھنے کے لیے مفت M3U Maker اکاؤنٹ بنائیں۔

(function() { var zone = document.getElementById('uploadZone'); var fileInput = document.getElementById('fileInput'); var results = document.getElementById('results'); var resetBtn = document.getElementById('resetBtn'); var browseBtn = document.getElementById('browseBtn'); browseBtn.addEventListener('click', function(e) { e.stopPropagation(); fileInput.click(); }); zone.addEventListener('click', function() { fileInput.click(); }); zone.addEventListener('dragover', function(e) { e.preventDefault(); zone.classList.add('drag-over'); }); zone.addEventListener('dragleave', function() { zone.classList.remove('drag-over'); }); zone.addEventListener('drop', function(e) { e.preventDefault(); zone.classList.remove('drag-over'); if (e.dataTransfer.files[0]) processFile(e.dataTransfer.files[0]); }); fileInput.addEventListener('change', function() { if (fileInput.files[0]) processFile(fileInput.files[0]); }); resetBtn.addEventListener('click', function() { results.style.display = 'none'; loading.style.display = 'none'; zone.style.display = ''; fileInput.value = ''; }); var loading = document.getElementById('loading'); function processFile(file) { zone.style.display = 'none'; loading.style.display = ''; var reader = new FileReader(); reader.onload = function(e) { validateM3U(e.target.result, file.name); }; reader.readAsText(file, 'UTF-8'); } function validateM3U(content, filename) { var lines = content.split(/\r?\n/); var errors = [], warnings = []; var channelCount = 0; var urls = {}, names = {}; var i = 0; if (lines[0] && lines[0].trim().startsWith('#EXTM3U')) { i = 1; } else { errors.push({ line: 1, msg: 'Missing #EXTM3U header on line 1' }); } while (i < lines.length) { var line = lines[i].trim(); if (!line || line === '#EXTM3U') { i++; continue; } if (line.startsWith('#EXTINF:')) { channelCount++; var lineNum = i + 1; var nameMatch = line.match(/,(.+)$/); var name = nameMatch ? nameMatch[1].trim() : ''; if (!name) { warnings.push({ line: lineNum, msg: 'Channel #' + channelCount + ': missing name after comma in #EXTINF' }); } if (line.indexOf('group-title') === -1) { warnings.push({ line: lineNum, msg: 'Channel #' + channelCount + (name ? ' "' + name + '"' : '') + ': missing group-title attribute' }); } if (name) { var lname = name.toLowerCase(); if (names[lname] !== undefined) { warnings.push({ line: lineNum, msg: 'Duplicate channel name: "' + name + '" (also on line ' + names[lname] + ')' }); } else { names[lname] = lineNum; } } i++; while (i < lines.length && !lines[i].trim()) i++; var urlLine = lines[i] ? lines[i].trim() : ''; var urlLineNum = i + 1; if (!urlLine || urlLine.startsWith('#')) { errors.push({ line: lineNum, msg: 'Channel #' + channelCount + (name ? ' "' + name + '"' : '') + ': no stream URL found after #EXTINF' }); } else { if (!/^(https?|rtsp|rtp|udp|igmp|mms|rtmp):\/\//i.test(urlLine)) { warnings.push({ line: urlLineNum, msg: 'Channel #' + channelCount + (name ? ' "' + name + '"' : '') + ': unusual URL format' }); } if (urls[urlLine] !== undefined) { warnings.push({ line: urlLineNum, msg: 'Duplicate stream URL for "' + name + '" (also on line ' + urls[urlLine] + ')' }); } else { urls[urlLine] = urlLineNum; } } } i++; } showResults(filename, channelCount, errors, warnings); } function showResults(filename, channelCount, errors, warnings) { document.getElementById('resultsFilename').textContent = filename; var statsRow = document.getElementById('statsRow'); var dupeCount = warnings.filter(function(w) { return w.msg.indexOf('Duplicate') === 0; }).length; statsRow.textContent = ''; [ { val: channelCount.toLocaleString(), label: 'Channels', cls: '' }, { val: errors.length, label: 'Errors', cls: errors.length > 0 ? 'tool-stat--error' : '' }, { val: warnings.length, label: 'Warnings', cls: warnings.length > 0 ? 'tool-stat--warning' : '' }, { val: dupeCount, label: 'Duplicates', cls: '' } ].forEach(function(s) { var div = document.createElement('div'); div.className = 'tool-stat ' + s.cls; var val = document.createElement('span'); val.className = 'tool-stat-value'; val.textContent = s.val; var lbl = document.createElement('span'); lbl.className = 'tool-stat-label'; lbl.textContent = s.label; div.appendChild(val); div.appendChild(lbl); statsRow.appendChild(div); }); var total = errors.length * 3 + warnings.length; var score = Math.max(0, Math.min(100, Math.round(100 - (total / Math.max(channelCount, 1)) * 200))); var scoreColor = score >= 80 ? 'var(--accent-success)' : score >= 50 ? 'var(--accent-warning)' : 'var(--accent-danger)'; document.getElementById('scoreText').textContent = score + '/100 - ' + (score >= 80 ? 'Good' : score >= 50 ? 'Fair' : 'Poor'); var fill = document.getElementById('scoreFill'); fill.style.width = '0%'; setTimeout(function() { fill.style.width = score + '%'; fill.style.background = scoreColor; }, 50); var issueList = document.getElementById('issueList'); issueList.textContent = ''; function renderGroup(items, type) { if (!items.length) return; var group = document.createElement('div'); group.className = 'tool-issue-group'; var header = document.createElement('div'); header.className = 'tool-issue-group-header tool-issue--' + type; header.textContent = (type === 'error' ? 'Errors' : 'Warnings') + ' (' + items.length + ')'; group.appendChild(header); var list = document.createElement('div'); list.className = 'tool-issue-list'; items.slice(0, 50).forEach(function(issue) { var item = document.createElement('div'); item.className = 'tool-issue-item'; var lineSpan = document.createElement('span'); lineSpan.className = 'tool-issue-line'; lineSpan.textContent = 'L' + issue.line; var msgSpan = document.createElement('span'); msgSpan.className = 'tool-issue-msg'; msgSpan.textContent = issue.msg; item.appendChild(lineSpan); item.appendChild(msgSpan); list.appendChild(item); }); if (items.length > 50) { var more = document.createElement('div'); more.className = 'tool-issue-more'; more.textContent = '… and ' + (items.length - 50) + ' more ' + type + 's'; list.appendChild(more); } group.appendChild(list); issueList.appendChild(group); } renderGroup(errors, 'error'); renderGroup(warnings, 'warning'); document.getElementById('successMsg').style.display = (errors.length + warnings.length === 0) ? '' : 'none'; loading.style.display = 'none'; results.style.display = ''; } })();