YouTube Video Downloader

VidSnap — ভিডিও ডাউনলোডার

/* ── Reset & Base ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
–bg: #0a0a0f;
–surface: #12121a;
–card: #1a1a26;
–border: rgba(255,255,255,0.07);
–accent: #00e5ff;
–accent2: #ff3d6e;
–accent3: #a259ff;
–text: #f0f0f8;
–muted: #6b6b8a;
–success: #00e676;
–warning: #ffab00;
–error: #ff3d6e;
–radius: 16px;
–glow: 0 0 40px rgba(0,229,255,0.15);
}

html { scroll-behavior: smooth; }

body {
background: var(–bg);
color: var(–text);
font-family: ‘Hind Siliguri’, sans-serif;
min-height: 100vh;
overflow-x: hidden;
position: relative;
}

/* ── Animated Background ── */
.bg-mesh {
position: fixed; inset: 0; z-index: 0; pointer-events: none;
background:
radial-gradient(ellipse 80% 60% at 20% 10%, rgba(0,229,255,0.06) 0%, transparent 60%),
radial-gradient(ellipse 60% 50% at 80% 80%, rgba(162,89,255,0.07) 0%, transparent 60%),
radial-gradient(ellipse 50% 40% at 50% 50%, rgba(255,61,110,0.04) 0%, transparent 60%);
}

.grid-lines {
position: fixed; inset: 0; z-index: 0; pointer-events: none;
background-image:
linear-gradient(rgba(255,255,255,0.02) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,0.02) 1px, transparent 1px);
background-size: 60px 60px;
mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
}

/* ── Layout ── */
.wrapper {
position: relative; z-index: 1;
max-width: 780px;
margin: 0 auto;
padding: 40px 20px 80px;
}

/* ── Header ── */
header {
text-align: center;
margin-bottom: 48px;
animation: fadeDown 0.8s ease both;
}

.logo-badge {
display: inline-flex;
align-items: center;
gap: 10px;
background: var(–card);
border: 1px solid var(–border);
border-radius: 100px;
padding: 8px 18px;
margin-bottom: 24px;
font-family: ‘Syne’, sans-serif;
font-size: 13px;
color: var(–accent);
letter-spacing: 2px;
text-transform: uppercase;
}

.logo-badge .dot {
width: 7px; height: 7px;
background: var(–accent);
border-radius: 50%;
animation: pulse 2s ease infinite;
}

h1 {
font-family: ‘Syne’, sans-serif;
font-size: clamp(2.2rem, 6vw, 3.8rem);
font-weight: 800;
line-height: 1.05;
letter-spacing: -1px;
margin-bottom: 14px;
}

h1 span.grad {
background: linear-gradient(135deg, var(–accent) 0%, var(–accent3) 50%, var(–accent2) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}

.subtitle {
color: var(–muted);
font-size: 1rem;
max-width: 400px;
margin: 0 auto;
line-height: 1.6;
}

/* ── Supported Platforms ── */
.platforms {
display: flex;
justify-content: center;
gap: 10px;
flex-wrap: wrap;
margin-top: 20px;
}

.platform-pill {
background: var(–card);
border: 1px solid var(–border);
border-radius: 100px;
padding: 5px 14px;
font-size: 12px;
color: var(–muted);
display: flex;
align-items: center;
gap: 5px;
transition: all 0.2s;
}
.platform-pill:hover { border-color: var(–accent); color: var(–accent); }
.platform-pill .icon { font-size: 14px; }

/* ── Main Card ── */
.main-card {
background: var(–card);
border: 1px solid var(–border);
border-radius: 24px;
padding: 32px;
margin-bottom: 24px;
box-shadow: var(–glow), 0 24px 60px rgba(0,0,0,0.4);
animation: fadeUp 0.8s 0.2s ease both;
position: relative;
overflow: hidden;
}

.main-card::before {
content: ”;
position: absolute;
top: 0; left: 0; right: 0;
height: 1px;
background: linear-gradient(90deg, transparent, var(–accent), transparent);
opacity: 0.4;
}

/* ── URL Input Area ── */
.input-label {
font-family: ‘Syne’, sans-serif;
font-size: 11px;
font-weight: 600;
letter-spacing: 2px;
text-transform: uppercase;
color: var(–muted);
margin-bottom: 10px;
display: block;
}

.input-row {
display: flex;
gap: 10px;
margin-bottom: 20px;
}

.url-wrap {
flex: 1;
position: relative;
}

.url-icon {
position: absolute;
left: 16px; top: 50%;
transform: translateY(-50%);
color: var(–muted);
font-size: 16px;
pointer-events: none;
transition: color 0.2s;
}

.link {
width: 100%;
background: var(–surface);
border: 1.5px solid var(–border);
border-radius: var(–radius);
padding: 15px 16px 15px 44px;
color: var(–text);
font-family: ‘Hind Siliguri’, sans-serif;
font-size: 0.95rem;
outline: none;
transition: border-color 0.2s, box-shadow 0.2s;
}

.link:focus {
border-color: var(–accent);
box-shadow: 0 0 0 3px rgba(0,229,255,0.1);
}
.link:focus + .url-icon,
.url-wrap:focus-within .url-icon { color: var(–accent); }

.link::placeholder { color: var(–muted); }

.paste-btn {
background: var(–surface);
border: 1.5px solid var(–border);
border-radius: var(–radius);
padding: 0 18px;
color: var(–muted);
font-size: 12px;
font-family: ‘Syne’, sans-serif;
font-weight: 600;
letter-spacing: 1px;
cursor: pointer;
text-transform: uppercase;
transition: all 0.2s;
white-space: nowrap;
}
.paste-btn:hover { border-color: var(–accent); color: var(–accent); background: rgba(0,229,255,0.05); }

/* ── Options Row ── */
.options-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
margin-bottom: 24px;
}

.opt-group { display: flex; flex-direction: column; gap: 8px; }

.formte, .quality-select {
background: var(–surface);
border: 1.5px solid var(–border);
border-radius: var(–radius);
padding: 13px 16px;
color: var(–text);
font-family: ‘Hind Siliguri’, sans-serif;
font-size: 0.92rem;
outline: none;
cursor: pointer;
appearance: none;
background-image: url(“data:image/svg+xml,%3Csvg xmlns=’http://www.w3.org/2000/svg’ width=’12’ height=’12’ viewBox=’0 0 24 24′ fill=’none’ stroke=’%236b6b8a’ stroke-width=’2’%3E%3Cpolyline points=’6 9 12 15 18 9’%3E%3C/polyline%3E%3C/svg%3E”);
background-repeat: no-repeat;
background-position: right 14px center;
padding-right: 36px;
transition: border-color 0.2s;
}
.formte:focus, .quality-select:focus { border-color: var(–accent); }
.formte option, .quality-select option { background: var(–card); }

/* ── Download Button ── */
.download-btn {
width: 100%;
background: linear-gradient(135deg, var(–accent) 0%, var(–accent3) 100%);
border: none;
border-radius: var(–radius);
padding: 17px 24px;
color: #000;
font-family: ‘Syne’, sans-serif;
font-size: 1rem;
font-weight: 700;
letter-spacing: 0.5px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: transform 0.15s, box-shadow 0.2s;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}

.download-btn::before {
content: ”;
position: absolute; inset: 0;
background: linear-gradient(135deg, rgba(255,255,255,0.2), transparent);
opacity: 0;
transition: opacity 0.2s;
}

.download-btn:hover { transform: translateY(-2px); box-shadow: 0 12px 30px rgba(0,229,255,0.25); }
.download-btn:hover::before { opacity: 1; }
.download-btn:active { transform: translateY(0); }
.download-btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }

.btn-icon { font-size: 18px; }

/* ── Result Area ── */
.result-area {
margin-top: 24px;
animation: fadeUp 0.4s ease both;
}

/* Loading */
.loading-state {
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
padding: 32px;
}

.spinner {
width: 48px; height: 48px;
border: 3px solid var(–border);
border-top-color: var(–accent);
border-radius: 50%;
animation: spin 0.8s linear infinite;
}

.loading-text {
color: var(–muted);
font-size: 0.9rem;
animation: blink 1.5s ease infinite;
}

/* Success Result */
.result-card {
background: var(–surface);
border: 1px solid var(–border);
border-radius: var(–radius);
overflow: hidden;
}

.result-header {
padding: 16px 20px;
background: rgba(0,230,118,0.05);
border-bottom: 1px solid var(–border);
display: flex;
align-items: center;
gap: 10px;
}

.result-title {
font-family: ‘Syne’, sans-serif;
font-size: 0.85rem;
font-weight: 600;
color: var(–success);
letter-spacing: 1px;
text-transform: uppercase;
}

.result-body { padding: 20px; }

/* Single download button */
.dl-btn {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
background: linear-gradient(135deg, rgba(0,230,118,0.1), rgba(0,230,118,0.05));
border: 1px solid rgba(0,230,118,0.3);
border-radius: 12px;
padding: 16px 20px;
color: var(–success);
text-decoration: none;
font-family: ‘Syne’, sans-serif;
font-size: 0.9rem;
font-weight: 600;
transition: all 0.2s;
cursor: pointer;
}
.dl-btn:hover {
background: linear-gradient(135deg, rgba(0,230,118,0.2), rgba(0,230,118,0.1));
border-color: var(–success);
transform: translateX(4px);
}

.dl-btn-left { display: flex; align-items: center; gap: 12px; }
.dl-btn-icon { font-size: 22px; }
.dl-btn-label { display: flex; flex-direction: column; gap: 2px; }
.dl-btn-title { color: var(–text); font-size: 0.95rem; }
.dl-btn-meta { color: var(–muted); font-size: 12px; font-weight: 400; }
.dl-btn-arrow { font-size: 18px; opacity: 0.6; }

/* Picker (multiple formats) */
.picker-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
gap: 10px;
}

.pick-item {
background: var(–card);
border: 1px solid var(–border);
border-radius: 12px;
padding: 14px;
text-align: center;
text-decoration: none;
color: var(–text);
transition: all 0.2s;
display: flex;
flex-direction: column;
gap: 6px;
align-items: center;
}
.pick-item:hover {
border-color: var(–accent);
background: rgba(0,229,255,0.05);
transform: translateY(-3px);
box-shadow: 0 8px 24px rgba(0,229,255,0.1);
}
.pick-icon { font-size: 24px; }
.pick-quality {
font-family: ‘Syne’, sans-serif;
font-size: 0.85rem;
font-weight: 700;
color: var(–accent);
}
.pick-label { font-size: 11px; color: var(–muted); }

/* Error state */
.error-card {
background: rgba(255,61,110,0.05);
border: 1px solid rgba(255,61,110,0.2);
border-radius: var(–radius);
padding: 20px;
display: flex;
align-items: flex-start;
gap: 14px;
}
.error-icon { font-size: 24px; flex-shrink: 0; }
.error-msg { color: var(–muted); font-size: 0.9rem; line-height: 1.6; }
.error-title { font-family: ‘Syne’, sans-serif; font-weight: 600; color: var(–error); margin-bottom: 4px; }

/* ── Stats Bar ── */
.stats-bar {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
margin-bottom: 24px;
animation: fadeUp 0.8s 0.4s ease both;
}

.stat-card {
background: var(–card);
border: 1px solid var(–border);
border-radius: var(–radius);
padding: 20px;
text-align: center;
position: relative;
overflow: hidden;
transition: border-color 0.2s;
}
.stat-card:hover { border-color: rgba(255,255,255,0.12); }

.stat-card::after {
content: ”;
position: absolute;
bottom: 0; left: 50%; transform: translateX(-50%);
width: 40%; height: 2px;
border-radius: 2px;
}
.stat-card:nth-child(1)::after { background: var(–accent); }
.stat-card:nth-child(2)::after { background: var(–accent3); }
.stat-card:nth-child(3)::after { background: var(–accent2); }

.stat-num {
font-family: ‘Syne’, sans-serif;
font-size: 1.6rem;
font-weight: 800;
background: linear-gradient(135deg, var(–text), var(–muted));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.stat-label { font-size: 12px; color: var(–muted); margin-top: 4px; }

/* ── Tips Section ── */
.tips-card {
background: var(–card);
border: 1px solid var(–border);
border-radius: var(–radius);
padding: 24px;
animation: fadeUp 0.8s 0.6s ease both;
}

.tips-title {
font-family: ‘Syne’, sans-serif;
font-size: 0.8rem;
font-weight: 600;
letter-spacing: 2px;
text-transform: uppercase;
color: var(–muted);
margin-bottom: 16px;
display: flex;
align-items: center;
gap: 8px;
}

.tips-list {
display: flex;
flex-direction: column;
gap: 10px;
list-style: none;
}

.tip-item {
display: flex;
align-items: flex-start;
gap: 12px;
font-size: 0.88rem;
color: var(–muted);
line-height: 1.5;
}

.tip-dot {
width: 6px; height: 6px;
background: var(–accent);
border-radius: 50%;
flex-shrink: 0;
margin-top: 6px;
}

/* ── Footer ── */
footer {
text-align: center;
margin-top: 40px;
color: var(–muted);
font-size: 12px;
line-height: 1.8;
animation: fadeUp 0.8s 0.8s ease both;
}

footer a { color: var(–accent); text-decoration: none; }

/* ── History ── */
.history-section { margin-top: 24px; }

.history-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12px;
}

.history-title {
font-family: ‘Syne’, sans-serif;
font-size: 0.8rem;
font-weight: 600;
letter-spacing: 2px;
text-transform: uppercase;
color: var(–muted);
}

.clear-btn {
background: none;
border: none;
color: var(–muted);
font-size: 12px;
cursor: pointer;
padding: 4px 8px;
border-radius: 6px;
transition: all 0.2s;
font-family: ‘Hind Siliguri’, sans-serif;
}
.clear-btn:hover { color: var(–error); background: rgba(255,61,110,0.1); }

.history-list { display: flex; flex-direction: column; gap: 8px; }

.history-item {
background: var(–card);
border: 1px solid var(–border);
border-radius: 10px;
padding: 12px 16px;
display: flex;
align-items: center;
gap: 12px;
cursor: pointer;
transition: all 0.2s;
font-size: 0.85rem;
}
.history-item:hover { border-color: var(–accent); background: rgba(0,229,255,0.03); }
.history-icon { font-size: 16px; flex-shrink: 0; }
.history-url { flex: 1; color: var(–muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.history-time { color: var(–muted); font-size: 11px; opacity: 0.6; flex-shrink: 0; }

/* ── Animations ── */
@keyframes fadeDown {
from { opacity: 0; transform: translateY(-20px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes fadeUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.5; transform: scale(0.8); }
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0.4; }
}
@keyframes shimmer {
from { background-position: -200% center; }
to { background-position: 200% center; }
}

/* ── Responsive ── */
@media (max-width: 600px) {
.wrapper { padding: 24px 16px 60px; }
.options-row { grid-template-columns: 1fr; }
.stats-bar { grid-template-columns: 1fr 1fr; }
.stats-bar .stat-card:last-child { grid-column: span 2; }
.input-row { flex-direction: column; }
.paste-btn { padding: 14px; }
h1 { font-size: 2rem; }
.main-card { padding: 20px; }
.picker-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ── Notification toast ── */
.toast {
position: fixed;
bottom: 24px; right: 24px;
background: var(–card);
border: 1px solid var(–border);
border-radius: 12px;
padding: 14px 20px;
display: flex;
align-items: center;
gap: 10px;
font-size: 0.88rem;
box-shadow: 0 8px 30px rgba(0,0,0,0.4);
z-index: 1000;
transform: translateY(80px);
opacity: 0;
transition: all 0.3s ease;
}
.toast.show { transform: translateY(0); opacity: 1; }
.toast.success { border-color: rgba(0,230,118,0.3); }
.toast.error { border-color: rgba(255,61,110,0.3); }


VidSnap Pro

যেকোনো ভিডিও
ডাউনলোড করুন

YouTube, TikTok, Instagram, Facebook সহ ১০০+ প্ল্যাটফর্ম থেকে HD মানের ভিডিও সংরক্ষণ করুন।

YouTube
TikTok
📸 Instagram
👥 Facebook
🐦 Twitter/X

0
আজকের ডাউনলোড

100+
সাপোর্টেড সাইট

4K
সর্বোচ্চ মান

ভিডিও লিংক

🔗

ফরম্যাট

🎬 ভিডিও (MP4)
🎵 অডিও (MP3)

মান (Quality)

✨ সর্বোচ্চ (4K/1080p)
🖥 1080p Full HD
📺 720p HD
📱 480p
💾 360p

💡 ব্যবহার নির্দেশিকা
  • YouTube, TikTok, Instagram, Facebook, Twitter/X এবং আরও অনেক সাইটের URL সাপোর্ট করে।
  • ভিডিও ডাউনলোডের জন্য MP4 ফরম্যাট এবং শুধু শব্দের জন্য MP3 বেছে নিন।
  • মোবাইলে ডাউনলোড করতে “ডাউনলোড” বাটনে চেপে ধরুন এবং “Save” সিলেক্ট করুন।
  • ব্যক্তিগত ব্যবহারের জন্য কপিরাইট আইন মেনে চলুন।

শুধুমাত্র ব্যক্তিগত ব্যবহারের জন্য। কপিরাইটযুক্ত কনটেন্ট ডাউনলোড করা আইনের বিরুদ্ধে হতে পারে।

Powered by VidSnap Pro — 2024

/* ────────────────────────────────────────────
CONFIG — proxy.php এর সঠিক পাথ দিন
──────────────────────────────────────────── */
const PROXY_URL = ‘/proxy.php’; // আপনার সার্ভারে proxy.php এর পাথ

/* ── DOM Refs ── */
const linkInput = document.querySelector(‘.link’);
const formSelect = document.querySelector(‘.formte’);
const qualSelect = document.querySelector(‘.quality-select’);
const dlBtn = document.getElementById(‘dl-btn’);
const btnText = document.getElementById(‘btn-text’);
const resultArea = document.getElementById(‘result-area’);
const pasteBtn = document.getElementById(‘paste-btn’);
const dlCount = document.getElementById(‘dl-count’);
const toast = document.getElementById(‘toast’);

/* ── State ── */
let downloadCount = parseInt(localStorage.getItem(‘vidsnap_count’) || ‘0’);
let history_arr = JSON.parse(localStorage.getItem(‘vidsnap_history’) || ‘[]’);
dlCount.textContent = downloadCount;

/* ── Toast ── */
function showToast(msg, type = ‘success’) {
toast.innerHTML = (type === ‘success’ ? ‘✅ ‘ : ‘❌ ‘) + msg;
toast.className = ‘toast ‘ + type + ‘ show’;
setTimeout(() => { toast.className = ‘toast’; }, 3000);
}

/* ── Paste ── */
pasteBtn.addEventListener(‘click’, async () => {
try {
const text = await navigator.clipboard.readText();
linkInput.value = text;
linkInput.focus();
showToast(‘URL পেস্ট হয়েছে’);
} catch {
linkInput.focus();
showToast(‘ম্যানুয়ালি পেস্ট করুন (Ctrl+V)’, ‘error’);
}
});

/* ── History ── */
function saveHistory(url) {
history_arr = history_arr.filter(h => h.url !== url);
history_arr.unshift({ url, time: Date.now() });
if (history_arr.length > 5) history_arr.pop();
localStorage.setItem(‘vidsnap_history’, JSON.stringify(history_arr));
renderHistory();
}

function renderHistory() {
const section = document.getElementById(‘history-section’);
const list = document.getElementById(‘history-list’);
if (!history_arr.length) { section.style.display = ‘none’; return; }
section.style.display = ‘block’;
list.innerHTML = history_arr.map((h, i) => {
const ago = timeAgo(h.time);
const short = h.url.length > 50 ? h.url.slice(0, 50) + ‘…’ : h.url;
return `

🔗
${short}
${ago}

`;
}).join(”);
}

function useHistory(el) {
linkInput.value = decodeURIComponent(el.dataset.url);
linkInput.scrollIntoView({ behavior: ‘smooth’, block: ‘center’ });
linkInput.focus();
}

function timeAgo(ts) {
const diff = Math.floor((Date.now() – ts) / 1000);
if (diff < 60) return 'এইমাত্র';
if (diff < 3600) return Math.floor(diff/60) + ' মিনিট আগে';
if (diff {
history_arr = [];
localStorage.removeItem(‘vidsnap_history’);
renderHistory();
});

renderHistory();

/* ── Loading State ── */
function showLoading() {
dlBtn.disabled = true;
btnText.textContent = ‘প্রক্রিয়া চলছে…’;
resultArea.style.display = ‘block’;
resultArea.innerHTML = `

ভিডিও তথ্য সংগ্রহ করা হচ্ছে…

`;
}

function resetBtn() {
dlBtn.disabled = false;
btnText.textContent = ‘ডাউনলোড শুরু করুন’;
}

/* ── Show Result ── */
function showSuccess(data, format) {
downloadCount++;
localStorage.setItem(‘vidsnap_count’, downloadCount);
dlCount.textContent = downloadCount;

if (data.status === ‘stream’ || data.status === ‘redirect’) {
const isAudio = format === ‘audio’;
resultArea.innerHTML = `

`;
showToast(‘ডাউনলোড লিংক পাওয়া গেছে!’);

} else if (data.status === ‘picker’) {
const items = data.picker.map((item, i) => `

🎬
${item.quality ? item.quality + ‘p’ : ‘Option ‘ + (i+1)}
ডাউনলোড
`).join(”);

resultArea.innerHTML = `


মান বেছে নিন
${items}

`;
showToast(‘একাধিক মান পাওয়া গেছে!’);
}
}

function showError(msg) {
resultArea.innerHTML = `

⚠️

ডাউনলোড ব্যর্থ

${msg}

`;
showToast(msg, ‘error’);
}

/* ── Main Download ── */
async function doDownload() {
const url = linkInput.value.trim();
const format = formSelect.value;
const qual = qualSelect.value;

if (!url) {
showToast(‘একটি URL দিন!’, ‘error’);
linkInput.focus();
return;
}

try { new URL(url); } catch {
showToast(‘সঠিক URL দিন’, ‘error’);
return;
}

saveHistory(url);
showLoading();

const body = new FormData();
body.append(‘url’, url);
body.append(‘quality’, qual);
body.append(‘isAudio’, format === ‘audio’ ? ‘true’ : ‘false’);

try {
const res = await fetch(PROXY_URL, { method: ‘POST’, body });
const data = await res.json();

if (data.status === ‘error’) {
showError(data.text || ‘অজানা সমস্যা হয়েছে। আবার চেষ্টা করুন।’);
} else {
showSuccess(data, format);
}
} catch (err) {
showError(‘সার্ভারের সাথে সংযোগ ব্যর্থ। proxy.php সঠিকভাবে আপলোড করা আছে কিনা যাচাই করুন।’);
console.error(‘[VidSnap]’, err);
} finally {
resetBtn();
}
}

/* ── Event Listeners ── */
dlBtn.addEventListener(‘click’, doDownload);

linkInput.addEventListener(‘keydown’, e => {
if (e.key === ‘Enter’) doDownload();
});

/* Auto-detect audio/video from quality select */
qualSelect.addEventListener(‘change’, () => {
if (qualSelect.value === ‘max’) {
formSelect.value = formSelect.options[0].value;
}
});