Discord Video Converter
Discord Video Converter – darmowe narzędzie webowe do kompresji filmów pod limity rozmiaru pliku na Discordzie. Narzędzie obsługuje konta bez Nitro (9 MB) oraz z Nitro Basic (50 MB), a także dwa presety kodowania. Projekt napisał Shieldziak.
Narzędzie kompresuje wideo pod limity Discorda — wybierasz tier konta i preset, a następnie serwer automatycznie dobiera bitrate i rozdzielczość tak, by plik zmieścił się w limicie. Interfejs nawiązuje stylistycznie do Discorda, natomiast obsługa sprowadza się do: wybór pliku → tier → preset → przycisk „Wyślij i konwertuj” → pasek postępu → pobranie gotowego .mp4. Logowanie przez Discord działa wyłącznie jako zabezpieczenie przed spamem — zakres identify oznacza, że aplikacja nie widzi wiadomości ani serwerów użytkownika.
Informacje ogólne
- Adres:
https://conv.dsh.yt/ - Autoryzacja: wymagane logowanie przez Discord (OAuth2)
- Rate limit: 1 konwersja na 60 sekund per konto Discord
- Limit uploadu: max 250 MB (rozmiar wejściowy)
- Czas przechowywania plików: 10 minut od zakończenia konwersji
- Równoległe konwersje: max 2 jednocześnie (kolejka globalna)
Obsługiwane formaty wejściowe
| Format | Rozszerzenie |
|---|---|
| MP4 | .mp4 |
| MOV | .mov |
| WebM | .webm |
Wyjście zawsze w formacie .mp4.
Tryby Nitro
| Tryb | Docelowy rozmiar wyjściowy |
|---|---|
| Brak Nitro | max 9 MB |
| Nitro Basic | max 50 MB |
Presety kodowania
| Preset | Koder wideo | Audio | Charakterystyka |
|---|---|---|---|
h264 | libx264 / h264_nvenc | AAC | CBR, szybsza konwersja, mniejszy rozmiar |
vp9 | libvpx-vp9 | Opus | Lepsza jakość przy tym samym rozmiarze |
Jeśli serwer posiada kartę NVIDIA z obsługą NVENC, konwersja H.264 odbywa się sprzętowo.
Endpointy
| Metoda | Endpoint | Opis | Wymaga logowania |
|---|---|---|---|
GET | / | Strona główna z interfejsem użytkownika | Nie |
GET | /login | Przekierowanie do Discord OAuth2 | Nie |
GET | /callback | Obsługa powrotu z Discord OAuth2 | Nie |
GET | /logout | Wylogowanie (czyszczenie sesji) | Nie |
POST | /upload | Upload całego pliku jednorazowo | Tak |
POST | /upload_chunk | Upload pojedynczego fragmentu (chunked upload) | Tak |
POST | /merge_chunks/<task_id> | Złączenie fragmentów i dodanie zadania do kolejki | Tak |
POST | /upload_url | Pobranie wideo z podanego URL i konwersja | Tak |
GET | /status/<task_id> | Sprawdzenie postępu konwersji (JSON) | Nie |
GET | /download/<task_id> | Pobranie gotowego pliku .mp4 | Nie |
/upload — upload pliku
Przyjmuje multipart/form-data z następującymi polami:
| Pole | Typ | Opis |
|---|---|---|
file | plik | Plik wideo (.mp4, .mov, .webm) |
task_id | string | Unikalny identyfikator zadania |
tier | string | basic (9 MB) lub nitro (50 MB) |
preset | string | h264 (szybkość) lub vp9 (jakość) |
Zwraca: task_id jako plaintext lub błąd z kodem HTTP.
/upload_chunk — upload fragmentowany
Dla dużych plików frontend może wysyłać plik w kawałkach. Każde żądanie zawiera:
| Pole | Typ | Opis |
|---|---|---|
file | plik | Fragment pliku |
task_id | string | Identyfikator zadania |
chunk_index | int | Numer fragmentu (od 0) |
Po wysłaniu wszystkich fragmentów należy wywołać /merge_chunks/<task_id>.
/upload_url — konwersja z URL
Przyjmuje multipart/form-data:
| Pole | Typ | Opis |
|---|---|---|
url | string | Bezpośredni link do pliku wideo |
task_id | string | Identyfikator zadania |
tier | string | basic lub nitro |
preset | string | h264 lub vp9 |
Serwer weryfikuje URL przez zapytanie HEAD (sprawdza content-type i content-length) przed pobraniem.
/status/<task_id> — status zadania
Zwraca JSON:
{
"progress": 74,
"done": false,
"path_ready": false,
"note": "Trwa konwersja..."
}
| Pole | Typ | Opis |
|---|---|---|
progress | int | Postęp w procentach (0–100) |
done | bool | Czy zadanie zostało zakończone |
path_ready | bool | Czy plik jest gotowy do pobrania |
note | string | Komunikat o aktualnym etapie lub błędzie |
/download/<task_id> — pobranie pliku
Zwraca plik .mp4 jako załącznik (Content-Disposition: attachment).
Jeśli path_ready jest false lub plik wygasł, zwraca 404.
Kody błędów
| Kod HTTP | Znaczenie |
|---|---|
400 | Brak pliku, niedozwolony format, nieprawidłowy task_id |
401 | Brak zalogowania przez Discord |
404 | Plik nie istnieje lub wygasł |
413 | Plik przekracza limit uploadu (250 MB) |
429 | Przekroczono rate limit (60s) lub kolejka konwersji jest pełna |
500 | Błąd serwera / nieudana konwersja |
Przykład użycia (JavaScript)
// 1. Upload pliku
const formData = new FormData();
formData.append("file", fileInput.files[0]);
formData.append("task_id", crypto.randomUUID());
formData.append("tier", "basic");
formData.append("preset", "h264");
const uploadRes = await fetch("https://conv.dsh.yt/upload", {
method: "POST",
body: formData,
credentials: "include"
});
const taskId = await uploadRes.text();
// 2. Polling statusu
let done = false;
while (!done) {
await new Promise(r => setTimeout(r, 1500));
const status = await fetch(`https://conv.dsh.yt/status/${taskId}`).then(r => r.json());
console.log(`Postęp: ${status.progress}%`);
if (status.path_ready) {
done = true;
window.location.href = `https://conv.dsh.yt/download/${taskId}`;
}
}
Ciekawostki
- Serwer automatycznie dobiera rozdzielczość wyjściową na podstawie docelowego bitrate — film może zostać przeskalowany w dół, jeśli bitrate jest zbyt niski dla oryginalnej rozdzielczości (minimum 0,0015 bitów na piksel).
- Jeśli skompresowany plik przekroczy limit o więcej niż 8%, konwersja jest automatycznie powtarzana z niższym bitrate.
- Pliki przechowywane są przez 10 minut — po tym czasie zostają usunięte z serwera.
- Backend napisany w Pythonie z użyciem Flask i FFmpeg.
- Serwis jest chroniony przez Cloudflare.
