Przewodnik
1. Pierwsze kroki
AniRena to indeks torrentów skupiony na anime, mandze, audio i powiązanych mediach. Możesz przeglądać i pobierać torrenty bez konta. Konto jest wymagane do przesyłania torrentów, publikowania w grupach lub korzystania z API.
Pasek nawigacji u góry zapewnia dostęp do głównych obszarów strony:
- Strona główna — strona listy torrentów i wyszukiwania.
- Prześlij — prześlij nowy torrent (wymaga logowania).
- Przewodnik — ta strona.
- Statystyki — statystyki całej strony (torrenty, peerzy, przesyłania w czasie).
- Grupy — katalog grup wydań.
- RSS — kanał RSS ostatnich przesyłań, filtrowalny według kategorii.
Menu konta (górny prawy róg po zalogowaniu) otwiera panel profilu, gdzie możesz dostosować ustawienia, zarządzać opcjami bezpieczeństwa i uzyskać dostęp do klucza API.
2. Przeglądanie i wyszukiwanie
Strona główna wyświetla wszystkie torrenty posortowane według daty przesyłania. Użyj paska wyszukiwania u góry, aby filtrować wyniki.
Podstawowe wyszukiwanie
Wpisz dowolne słowa w pasek wyszukiwania i naciśnij Enter (lub kliknij ikonę wyszukiwania). Wyniki są sortowane według trafności, gdy zapytanie jest aktywne.
Operatory wyszukiwania
Następujące operatory można łączyć z regularnym zapytaniem:
| Operator | Przykład | Efekt |
|---|---|---|
user:"name" | user:"SubsPlease" | Pokaż tylko torrenty przesłane przez tego użytkownika. |
Kliknięcie nazwy przesyłającego na liście torrentów automatycznie uruchamia wyszukiwanie użytkownika.
Kategorie i podkategorie
Użyj selektora kategorii (ikona siatki obok paska wyszukiwania), aby ograniczyć wyniki do jednej kategorii. Dostępne kategorie:
- Anime
- Manga/Manhwa/Komiks
- Audio
- Literatura
- Live Action
- Obrazy
- Oprogramowanie
- Hentai
- Inne
Każda kategoria ma podkategorie (np. Anime do RAW, Sub/Audio, Teledysk) dostępne wewnątrz modalnego okna kategorii.
Sortowanie i filtry
Nagłówki kolumn na liście torrentów są klikalne w celu sortowania według tej kolumny (rosnąco lub malejąco). Dostępne kolumny sortowania: data, nazwa, rozmiar, ukończone pobierania. Uwaga: seederzy i leecherzy to wartości pobierane na żywo z Redis i nie można ich używać do sortowania.
Filtr języka
Użyj selektora języka (ikona flagi), aby pokazać tylko torrenty oznaczone określonym językiem.
Kanał RSS
Kanał RSS pod adresem /rss zawiera najnowsze przesyłania. Dodaj ?category=anime (lub inny slug kategorii), aby filtrować kanał. Większość klientów torrentów obsługuje automatyczne pobieranie RSS bezpośrednio z tego adresu URL.
3. Pobieranie torrentów
Kliknij dowolną nazwę torrenta, aby otworzyć panel szczegółów. Stamtąd możesz:
- Pobierz .torrent — zapisuje plik .torrent bezpośrednio. Bezpośredni adres URL to
/torrents/{id}.torrent - Link magnet — otwiera się bezpośrednio w kliencie torrentów przez protokół URI magnet. Adres URL to
/torrents/{id}/magnet
Panel szczegółów pokazuje również opis torrenta, listę plików, listę trackerów oraz liczby seederów/leecherów.
Starsze linki do pobierania
Stare linki do pobierania AniRena są nadal obsługiwane i automatycznie przekierowują do właściwego pliku .torrent przy użyciu starszego ID: /dl/{old_id}
Polecane klienty BitTorrent
Każdy nowoczesny klient BitTorrent działa. Poniższe klienty są polecane i w pełni obsługują BitTorrent v2 / hybridowe torrenty:
4. Tworzenie konta
Rejestracja
Kliknij Zarejestruj się na pasku nawigacji. Wybierz nazwę użytkownika, podaj adres e-mail i ustaw hasło (minimalna długość jest wymagana). Musisz przeczytać i zaakceptować warunki strony przed utworzeniem konta.
Aktywacja e-mailem
Po rejestracji na Twój adres zostanie wysłany e-mail weryfikacyjny. Kliknij link w e-mailu, aby aktywować konto. Jeśli go nie otrzymałeś, użyj linku Aktywuj konto na stronie logowania, aby poprosić o nowy kod.
Odzyskiwanie hasła
Jeśli zapomnisz hasła, kliknij Zapomniałem hasła na stronie logowania i wprowadź swój adres e-mail. Zostanie Ci wysłany link odzyskiwania. Link jest jednorazowy i wygasa po krótkim czasie.
5. Przesyłanie torrentów
Przejdź do Prześlij na pasku nawigacji. Musisz być zalogowany z aktywnym, niezbanowanym kontem. Strona przesyłania ma dwie zakładki:
Zakładka Prześlij — prześlij istniejący plik .torrent
Przeciągnij i upuść lub wybierz plik .torrent. Po załadowaniu wypełnij pola:
| Pole | Wymagane | Opis |
|---|---|---|
| Plik torrenta | Tak | Plik .torrent do przesłania. |
| Nazwa | Nie | Zastąp wyświetlaną nazwę torrenta. Jeśli pozostawione puste, używana jest nazwa osadzona w pliku torrenta. |
| Kategoria | Tak | Kategoria treści (Anime, Manga, Audio itp.). |
| Podkategoria | Nie | Bardziej konkretny typ w ramach kategorii (np. RAW, Sub/Audio). |
| Języki | Nie | Jeden lub więcej tagów języka opisujących język treści. |
| Grupa | Nie | Powiąż to wydanie z grupą, której jesteś członkiem. |
| Opis | Nie | Opis w formacie Markdown wyświetlany na stronie szczegółów torrenta (maks. 65535 znaków). |
| Prywatny | Nie | Ustawia flagę prywatności w torrencie, wyłączając DHT/PEX. Przydatne dla torrentów tylko dla trackerów. |
| URL ogłoszenia | Nie | Zastąp lub dodaj podstawowy URL ogłoszenia trackera. |
| Dodatkowe trackery | Nie | Odczytane z pliku torrent. Nie można modyfikować podczas przesyłania — użyj zakładki Utwórz, jeśli chcesz dostosować listę trackerów. |
| Komentarz | Nie | Zastąp pole komentarza torrenta osadzone w pliku. |
Twój torrent musi zawierać co najmniej jeden URL trackera AniRena na liście announce (w dowolnym tierze). Strona sprawdza to podczas przesyłania i odrzuci torrenty niezawierające trackera AniRena. Jeśli stworzyłeś torrent bez wcześniejszego dodania trackera AniRena, prześlij go, a następnie pobierz ponownie ze strony — pobrany plik będzie miał automatycznie wstrzyknięte odpowiednie trackery.
Zakładka Utwórz — zbuduj nowy torrent
Zakładka Utwórz pozwala generować nowy .torrent od podstaw przez określenie ścieżek plików, adresów URL trackerów i innych parametrów torrenta bezpośrednio w przeglądarce. Wynikowy torrent jest przesyłany z tymi samymi polami metadanych co powyżej.
Moderacja
Przesyłania są automatycznie sprawdzane pod kątem listy zbanowanych wzorców treści (nazwy, nazwy plików, opisy). Torrenty pasujące do zbanowanego wzorca zostaną odrzucone. Duplikaty torrentów (ten sam info hash) również są odrzucane.
6. Twoje konto
Kliknij swoją nazwę użytkownika w górnym prawym rogu, aby otworzyć panel profilu. Jest on zorganizowany w składane sekcje:
Ustawienia
Zmień motyw interfejsu, rozmiar czcionki, schemat kolorów, język interfejsu i preferencje wyświetlania związane z torrentami. Zmiany są zapisywane automatycznie.
Hasło
Wprowadź obecne hasło i nowe hasło dwukrotnie. Kod weryfikacyjny jest wysyłany na zarejestrowany adres e-mail i musi być wprowadzony w celu potwierdzenia zmiany. Jeśli włączone jest uwierzytelnianie dwuskładnikowe, wymagany jest również kod TOTP.
Uwierzytelnianie dwuskładnikowe (2FA)
Włącz uwierzytelnianie dwuskładnikowe oparte na TOTP przy użyciu dowolnej aplikacji uwierzytelniającej (np. Google Authenticator, Aegis, Bitwarden). Przy włączaniu 2FA:
- Zeskanuj kod QR (lub wprowadź sekret ręcznie) w swojej aplikacji uwierzytelniającej.
- Wprowadź 6-cyfrowy kod wyświetlany w aplikacji, aby potwierdzić konfigurację.
- Zapisz wyświetlone kody odzyskiwania — są to jednorazowe kody do odzyskania dostępu w przypadku utraty urządzenia.
Aby wyłączyć 2FA, wprowadź obecny kod TOTP i potwierdź.
Aktywne sesje
Wyświetl wszystkie aktualnie aktywne sesje logowania, w tym przeglądarkę, system operacyjny, adres IP i czas ostatniej aktywności. Kliknij Unieważnij na dowolnej sesji, której nie rozpoznajesz. Możesz również unieważnić wszystkie sesje jednocześnie, aby wylogować się ze wszystkich urządzeń.
Klucz API
Wygeneruj osobisty klucz API używany do programowego przesyłania torrentów przez AniRena API. Kliknij Generuj klucz, aby go utworzyć — pełny klucz jest wyświetlany raz bezpośrednio po wygenerowaniu. Przechowuj go bezpiecznie; nie zostanie pokazany w pełni ponownie. Użyj Unieważnij, aby trwale unieważnić klucz.
Usuń konto
Żądanie usunięcia konta rozpoczyna 30-dniowy okres karencji. Konto jest natychmiast wyłączone i trwale usuwane po 30 dniach. Możesz anulować usunięcie w dowolnym momencie w tym oknie, logując się i klikając Anuluj usunięcie.
7. AniRena API
AniRena udostępnia JSON API, które pozwala programowo przesyłać torrenty przy użyciu osobistego klucza API. API stosuje te same zasady co interfejs sieciowy: sprawdzenia banów, limity żądań i ograniczenia trybu strony — wszystko to ma zastosowanie. Każde przesyłanie przez API jest rejestrowane w dzienniku audytu.
Uwierzytelnianie
API korzysta z dwuetapowego przepływu uwierzytelniania. Najpierw wymień swój stały klucz API na krótkotrwały token nośnika, a następnie przekazuj ten token w nagłówku Authorization każdego żądania API.
Twój klucz API jest dostępny w sekcji Twoje konto > Klucz API. Zachowaj go w tajemnicy — każdy, kto go posiada, może uzyskać tokeny nośnika i przesyłać pliki w Twoim imieniu. W przypadku naruszenia bezpieczeństwa natychmiast go unieważnij i wygeneruj nowy.
Krok 1 — Pobierz token nośnika
/api/v1/auth/tokenWyślij żądanie POST do endpointu tokenu z kluczem API w nagłówku Authorization. Treść żądania nie jest wymagana.
Authorization: ApiKey <your-api-key>
Odpowiedź tokenu
{
"token": "<bearer-token>",
"token_type": "Bearer",
"expires_in": 3600
}Czas życia tokenu
Tokeny Bearer pozostają ważne do 3600 sekund od momentu ich wydania i można je używać wielokrotnie w każdym wywołaniu, aż wygasną. Po wygaśnięciu tokenu wygeneruj nowy przez POST /api/v1/auth/token. Każda odpowiedź nadal zwraca bieżący token w nagłówku X-New-Token w celu zachowania zgodności wstecznej.
X-New-Token: <next-bearer-token>
Logowanie jednym żądaniem (z 2FA)
/api/v1/auth/loginUwierzytelnij się nazwą użytkownika lub adresem e-mail i hasłem w jednym żądaniu i otrzymaj token bearer bezpośrednio. Jeśli na koncie masz włączone 2FA, dołącz bieżący kod z aplikacji uwierzytelniającej w polu totp_code (lub kod odzyskiwania w recovery_code). Opcjonalnie ustaw new_api_key na true, aby w tej samej odpowiedzi wygenerować również zupełnie nowy stały klucz API.
Treść żądania
{
"login": "username or email",
"password": "your-password",
"totp_code": "123456", // wymagane, jeśli 2FA jest włączone (6 cyfr)
"recovery_code": "", // alternatywa dla totp_code
"new_api_key": false // ustaw true, aby wygenerować też nowy klucz API
}Odpowiedź tokenu
{
"ok": true,
"token": "<bearer-token>",
"token_type": "Bearer",
"expires_in": 3600,
"api_key": "<new-api-key>" // obecne tylko, gdy new_api_key było true
}Token bearer działa dokładnie tak samo jak ten z /api/v1/auth/token. Pole api_key jest zwracane tylko wtedy, gdy new_api_key ma wartość true — zapisz je natychmiast, ponieważ wyświetlane jest tylko raz i zastępuje wszelkie poprzednie klucze.
Przykład — zaloguj się i (opcjonalnie) uzyskaj nowy klucz API
# pip install requests import requests BASE_URL = "https://www.anirena.com" # One request: authenticate (with 2FA if enabled) and get a bearer token. # Set new_api_key=True to also receive a brand-new permanent API key. resp = requests.post( f"{BASE_URL}/api/v1/auth/login", json={ "login": "your-username", # username or email "password": "your-password", "totp_code": "123456", # omit if 2FA is not enabled "new_api_key": True, # optional }, ) resp.raise_for_status() data = resp.json() token = data["token"] # use as: Authorization: Bearer <token> if "api_key" in data: print("New API key — store it now:", data["api_key"])
// Built-in fetch — requires Node.js 18+ const BASE_URL = "https://www.anirena.com"; // One request: authenticate (with 2FA if enabled) and get a bearer token. // Set new_api_key:true to also receive a brand-new permanent API key. const resp = await fetch(`${BASE_URL}/api/v1/auth/login`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ login: "your-username", // username or email password: "your-password", totp_code: "123456", // omit if 2FA is not enabled new_api_key: true, // optional }), }); const data = await resp.json(); const token = data.token; // use as: Authorization: Bearer <token> if (data.api_key) console.log("New API key — store it now:", data.api_key);
// Requires: curl extension (enabled by default in PHP 8+) <?php define("BASE_URL", "https://www.anirena.com"); // One request: authenticate (with 2FA if enabled) and get a bearer token. // Set new_api_key => true to also receive a brand-new permanent API key. $ch = curl_init(BASE_URL . "/api/v1/auth/login"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode([ "login" => "your-username", // username or email "password" => "your-password", "totp_code" => "123456", // omit if 2FA is not enabled "new_api_key" => true, // optional ]), CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Content-Type: application/json"], ]); $data = json_decode(curl_exec($ch), true); curl_close($ch); $token = $data["token"]; // use as: Authorization: Bearer <token> if (isset($data["api_key"])) echo "New API key — store it now: " . $data["api_key"];
// Cargo.toml: // serde_json = "1" // reqwest = { version = "0.12", features = ["blocking", "json"] } const BASE_URL: &str = "https://www.anirena.com"; fn main() { let client = reqwest::blocking::Client::new(); // One request: authenticate (with 2FA if enabled) and get a bearer token. // Set new_api_key:true to also receive a brand-new permanent API key. let data: serde_json::Value = client .post(format!("{BASE_URL}/api/v1/auth/login")) .json(&serde_json::json!({ "login": "your-username", // username or email "password": "your-password", "totp_code": "123456", // omit if 2FA is not enabled "new_api_key": true, // optional })) .send().unwrap() .json().unwrap(); let token = data["token"].as_str().unwrap(); // Authorization: Bearer <token> if let Some(key) = data["api_key"].as_str() { println!("New API key — store it now: {key}"); } }
Krok 2 — Prześlij torrent
/api/v1/torrentsWyślij proste żądanie POST JSON z tokenem nośnika w nagłówku Authorization.
Treść żądania
| Pole | Typ | Wymagane | Opis |
|---|---|---|---|
torrent | string | Tak | Zawartość pliku .torrent zakodowana w Base64. |
category | string | Tak | Slug kategorii: anime, manga, audio, literature, live, pictures, software, hentai, other. |
name | string | Nie | Zastąp wyświetlaną nazwę torrenta. |
sub_category | string | Nie | Slug podkategorii (np. raw, sub-audio). Musi należeć do wybranej kategorii. |
languages | string[] | Nie | Tablica kodów języków BCP 47 (np. en, ja). |
group_id | string | Nie | UUID grupy, której jesteś członkiem, aby powiązać z tym wydaniem. |
description | string | Nie | Opis wydania w formacie Markdown (maks. 65535 znaków). |
comment | string | Nie | Zastąp osadzone pole komentarza torrenta. |
is_private | boolean | Nie | Ustaw na true, aby włączyć flagę prywatności w torrencie. |
comments_enabled | boolean | Nie | Zezwól na komentarze do tego torrenta. Domyślna wartość to true (włączone). |
anime_id | string | Nie | UUID wpisu anime do powiązania z tym torrentem. UUID można uzyskać przez GET /api/v1/anime/search. Zwraca 400, jeśli UUID nie pasuje do żadnego znanego wpisu. |
announce | string | Nie | Zastąp lub dodaj podstawowy URL ogłoszenia. |
trackers | string | Nie | Rozdzielona znakiem nowej linii lista dodatkowych adresów URL trackerów. Pusta linia między adresami URL tworzy nową warstwę trackerów. |
test | boolean | Nie | Ustaw na true, aby wykonać suche uruchomienie: żądanie jest w pełni weryfikowane, ale torrent nie jest zapisywany. Użyj tego, aby sprawdzić poprawność danych przed rzeczywistym przesłaniem. |
Odpowiedź sukcesu suchego uruchomienia — 200 OK
{
"ok": true,
"test": true,
"name": "My Torrent Title",
"info_hash_v1": "aabbccddeeff...",
"info_hash_v2": null
}Dostępne kody języków
abaaafaksqamarar-001anhyasavaeayazbmbaeubebnbhbibsbrbgmyyuecachcenyzhzh-HKzh-Hanszh-SGzh-TWcucvkwcocrhrcsdadvnlnl-BEdzenen-USeoeteefofjfilfifrfr-CAffgllgkadede-ATelgnguhthahehzhihohuisioigidiaieiuikgaitjajvklknkrkskkkmkirwrnkvkgkokjkukylolalvlilnltlulbmkmgmsmlmtgvmimrmhmnnanvngnendsenonbnnocorojomospipsfaplptpt-BRpaqurormrusmsgsascgdsrsr-Latnsniisdsiskslsonrsteses-419es-MXsuswsssvtltytgtatttethbotitotstntrtktwukuruguzvevivowacyfywoxhyiyozazuPrzykładowe żądanie
# pip install requests import base64, pathlib, requests API_KEY = "YOUR_API_KEY" BASE_URL = "https://www.anirena.com" # Step 1: exchange API key for a short-lived bearer token auth = requests.post( f"{BASE_URL}/api/v1/auth/token", headers={"Authorization": f"ApiKey {API_KEY}"}, ) auth.raise_for_status() token = auth.json()["token"] # Step 2: upload — plain JSON with the bearer token torrent_b64 = base64.b64encode(pathlib.Path("file.torrent").read_bytes()).decode() resp = requests.post( f"{BASE_URL}/api/v1/torrents", json={ "torrent": torrent_b64, "category": "anime", "sub_category": "raw", "languages": ["ja"], "description": "# My Release\n\nRelease notes here.", "is_private": False, }, headers={"Authorization": f"Bearer {token}"}, ) resp.raise_for_status() data = resp.json() token = resp.headers.get("X-New-Token", token) # save for next request print(data["id"], data["name"]) # torrent UUID and title
// Built-in modules only — requires Node.js 18+ (for global fetch) const fs = require("fs"); const API_KEY = "YOUR_API_KEY"; const BASE_URL = "https://www.anirena.com"; // Step 1: exchange API key for a short-lived bearer token let authResp = await fetch(`${BASE_URL}/api/v1/auth/token`, { method: "POST", headers: { Authorization: `ApiKey ${API_KEY}` }, }); let { token } = await authResp.json(); // Step 2: upload — plain JSON with the bearer token const torrentB64 = fs.readFileSync("file.torrent").toString("base64"); const resp = await fetch(`${BASE_URL}/api/v1/torrents`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` }, body: JSON.stringify({ torrent: torrentB64, category: "anime", sub_category: "raw", languages: ["ja"], description: "# My Release\n\nRelease notes here.", is_private: false, }), }); const data = await resp.json(); token = resp.headers.get("x-new-token") ?? token; // save for next request console.log(data.id, data.name); // torrent UUID and title
// Requires: curl extension (enabled by default in PHP 8+) <?php define("API_KEY", "YOUR_API_KEY"); define("BASE_URL", "https://www.anirena.com"); // Step 1: exchange API key for a short-lived bearer token $ch = curl_init(BASE_URL . "/api/v1/auth/token"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: ApiKey " . API_KEY], ]); $token = json_decode(curl_exec($ch), true)["token"]; curl_close($ch); // Step 2: upload — plain JSON with the bearer token $torrentB64 = base64_encode(file_get_contents("file.torrent")); $respHeaders = []; $ch = curl_init(BASE_URL . "/api/v1/torrents"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode([ "torrent" => $torrentB64, "category" => "anime", "sub_category" => "raw", "languages" => ["ja"], "description" => "# My Release\n\nRelease notes here.", "is_private" => false, ]), CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADERFUNCTION => function($ch, $h) use (&$respHeaders) { $respHeaders[] = $h; return strlen($h); }, CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "Authorization: Bearer " . $token, ], ]); $data = json_decode(curl_exec($ch), true); curl_close($ch); foreach ($respHeaders as $h) { // save new token for next request if (stripos($h, "X-New-Token:") === 0) $token = trim(substr($h, strlen("X-New-Token:"))); } echo $data["id"] . " " . $data["name"]; // torrent UUID and title
// Cargo.toml: // base64 = "0.22" // serde_json = "1" // reqwest = { version = "0.12", features = ["blocking", "json"] } use base64::{engine::general_purpose::STANDARD as B64, Engine}; const API_KEY: &str = "YOUR_API_KEY"; const BASE_URL: &str = "https://www.anirena.com"; fn main() { let client = reqwest::blocking::Client::new(); // Step 1: exchange API key for a short-lived bearer token let auth: serde_json::Value = client .post(format!("{BASE_URL}/api/v1/auth/token")) .header("Authorization", format!("ApiKey {API_KEY}")) .send().unwrap().json().unwrap(); let mut token = auth["token"].as_str().unwrap().to_string(); // Step 2: upload — plain JSON with the bearer token let torrent_b64 = B64.encode(std::fs::read("file.torrent").unwrap()); let resp = client .post(format!("{BASE_URL}/api/v1/torrents")) .header("Authorization", format!("Bearer {token}")) .json(&serde_json::json!({ "torrent": torrent_b64, "category": "anime", "sub_category": "raw", "languages": ["ja"], "description": "# My Release\n\nRelease notes here.", "is_private": false })) .send().unwrap(); if let Some(t) = resp.headers().get("x-new-token") { token = t.to_str().unwrap().to_string(); // save for next request } let data: serde_json::Value = resp.json().unwrap(); println!("{} {}", data["id"], data["name"]); // torrent UUID and title }
Odpowiedź sukcesu — 200 OK
{
"ok": true,
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "My Torrent Title",
"info_hash_v1": "aabbccddeeff...",
"info_hash_v2": null
}Odpowiedzi błędów
| Status HTTP | Znaczenie |
|---|---|
400 | Nieprawidłowa treść żądania lub brakujące wymagane pole. |
401 | Brakujący, wygasły lub już zrotowany token nośnika. Uwierzytelnij się ponownie przez POST /api/v1/auth/token. |
403 | Konto zbanowane, wyłączone lub IP zablokowane. |
409 | Duplikat torrenta — torrent z tym samym info hash już istnieje. |
422 | Nie udało się przetworzyć pliku torrenta lub nie przeszedł weryfikacji (zbanowany wzorzec, nieprawidłowa struktura). |
429 | Przekroczono limit żądań. Spróbuj ponownie po zresetowaniu okna. |
503 | Strona jest w trybie konserwacji lub tylko do odczytu. |
Ograniczenie żądań
Przesyłania przez API podlegają oddzielnemu, konfigurowalnym limitowi żądań oddzielnemu od interfejsu sieciowego. Limit i okno są ustawiane przez administratora strony. Gdy limit jest przekroczony, API zwraca 429 Too Many Requests. Limit jest na klucz API.
Generowanie plików torrent za pomocą torrent-builder
torrent-builder to narzędzie CLI o otwartym kodzie źródłowym zbudowane na libtorrent-rasterbar, które umożliwia tworzenie plików .torrent BitTorrent v1, v2 i hybrid z wiersza poleceń. Doskonale współpracuje z AniRena upload API — wygeneruj plik lokalnie, a następnie wyślij POST bezpośrednio do trackera. cantalupo555/torrent-builder.
Budowanie ze źródeł
Wymaga CMake >= 3.28.3 i libtorrent-rasterbar >= 2.0.11. Sklonuj repozytorium i zbuduj z CMake:
# Install system dependencies sudo apt-get install build-essential cmake libtorrent-rasterbar-dev # Clone & build git clone https://github.com/cantalupo555/torrent-builder.git cd torrent-builder mkdir build && cd build cmake .. && cmake --build .
# Install dependencies via Homebrew brew install cmake libtorrent-rasterbar # Clone & build git clone https://github.com/cantalupo555/torrent-builder.git cd torrent-builder mkdir build && cd build cmake .. && cmake --build .
Kluczowe flagi
| Pole | Opis |
|---|---|
--path | Ścieżka do pliku lub katalogu do spakowania (wymagane). |
--output | Nazwa pliku wyjściowego .torrent (wymagane). |
--version | Format BitTorrent — 1 = v1, 2 = v2, 3 = hybrid (domyślnie: 3). |
--tracker | Dodaj URL announce trackera. Powtórz flagę, aby dodać wiele trackerów. |
--comment | Osadź ciąg komentarza metadanych w torrencie. |
--private | Ustaw flagę prywatną, aby ograniczyć dystrybucję tylko do wymienionych trackerów. |
--piece-size | Rozmiar kawałka w KB (16-32768). Pozostaw nieustawione dla automatycznego wyboru. |
-i | Uruchom krokowy interaktywny tryb konfiguracji. |
Kompletny przepływ pracy: budowanie -> przesyłanie
Poniższe przykłady budują torrent hybrid za pomocą torrent-builder, następnie uwierzytelniają się w AniRena API i przesyłają wynik w jednym skrypcie.
# pip install requests import base64, subprocess, requests API_KEY = "YOUR_API_KEY" BASE_URL = "https://www.anirena.com" # Step 1: build the torrent with torrent-builder # --version 1=v1 2=v2 3=hybrid (default) subprocess.run([ "./torrent-builder/build/torrent_builder", "--path", "/data/my_release", "--output", "my_release.torrent", "--version", "3", # hybrid "--tracker", "udp://open.tracker.gg:6969/announce", "--comment", "My Release", "--creator", "--creation-date", ], check=True) # Step 2: authenticate token = requests.post( f"{BASE_URL}/api/v1/auth/token", headers={"Authorization": f"ApiKey {API_KEY}"}, ).json()["token"] # Step 3: upload torrent_b64 = base64.b64encode(open("my_release.torrent", "rb").read()).decode() resp = requests.post( f"{BASE_URL}/api/v1/torrents", json={ "torrent": torrent_b64, "category": "anime", "sub_category": "raw", "languages": ["ja"], "comments_enabled": True, }, headers={"Authorization": f"Bearer {token}"}, ) resp.raise_for_status() data = resp.json() print(data["id"], data["name"])
// Built-in modules — Node.js 18+ const fs = require("fs"); const { execFileSync } = require("child_process"); const API_KEY = "YOUR_API_KEY"; const BASE_URL = "https://www.anirena.com"; // Step 1: build the torrent (--version 1=v1, 2=v2, 3=hybrid) execFileSync("./torrent-builder/build/torrent_builder", [ "--path", "/data/my_release", "--output", "my_release.torrent", "--version", "3", "--tracker", "udp://open.tracker.gg:6969/announce", "--comment", "My Release", "--creator", "--creation-date", ]); // Step 2: authenticate let { token } = await (await fetch(`${BASE_URL}/api/v1/auth/token`, { method: "POST", headers: { Authorization: `ApiKey ${API_KEY}` }, })).json(); // Step 3: upload const torrentB64 = fs.readFileSync("my_release.torrent").toString("base64"); const resp = await fetch(`${BASE_URL}/api/v1/torrents`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` }, body: JSON.stringify({ torrent: torrentB64, category: "anime", sub_category: "raw", languages: ["ja"], comments_enabled: true, }), }); const data = await resp.json(); console.log(data.id, data.name);
// PHP 8+ with curl and proc_open <?php define("API_KEY", "YOUR_API_KEY"); define("BASE_URL", "https://www.anirena.com"); // Step 1: build the torrent (version: 1=v1, 2=v2, 3=hybrid) exec(implode(" ", array_map("escapeshellarg", [ "./torrent-builder/build/torrent_builder", "--path", "/data/my_release", "--output", "my_release.torrent", "--version", "3", "--tracker", "udp://open.tracker.gg:6969/announce", "--comment", "My Release", "--creator", "--creation-date", ]))); // Step 2: authenticate $ch = curl_init(BASE_URL . "/api/v1/auth/token"); curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: ApiKey " . API_KEY]]); $token = json_decode(curl_exec($ch), true)["token"]; curl_close($ch); // Step 3: upload $torrentB64 = base64_encode(file_get_contents("my_release.torrent")); $respHeaders = []; $ch = curl_init(BASE_URL . "/api/v1/torrents"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode([ "torrent" => $torrentB64, "category" => "anime", "sub_category" => "raw", "languages" => ["ja"], "comments_enabled" => true, ]), CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADERFUNCTION => function($ch, $h) use (&$respHeaders) { $respHeaders[] = $h; return strlen($h); }, CURLOPT_HTTPHEADER => ["Content-Type: application/json", "Authorization: Bearer " . $token], ]); $data = json_decode(curl_exec($ch), true); curl_close($ch); echo $data["id"] . " " . $data["name"];
// Cargo.toml: // base64 = "0.22" // serde_json = "1" // reqwest = { version = "0.12", features = ["blocking", "json"] } use base64::{engine::general_purpose::STANDARD as B64, Engine}; use std::process::Command; const API_KEY: &str = "YOUR_API_KEY"; const BASE_URL: &str = "https://www.anirena.com"; fn main() { // Step 1: build the torrent (--version 1=v1, 2=v2, 3=hybrid) Command::new("./torrent-builder/build/torrent_builder") .args([ "--path", "/data/my_release", "--output", "my_release.torrent", "--version", "3", "--tracker", "udp://open.tracker.gg:6969/announce", "--comment", "My Release", "--creator", "--creation-date", ]) .status().expect("torrent_builder failed"); let client = reqwest::blocking::Client::new(); // Step 2: authenticate let auth: serde_json::Value = client .post(format!("{BASE_URL}/api/v1/auth/token")) .header("Authorization", format!("ApiKey {API_KEY}")) .send().unwrap().json().unwrap(); let token = auth["token"].as_str().unwrap().to_string(); // Step 3: upload let torrent_b64 = B64.encode(std::fs::read("my_release.torrent").unwrap()); let resp: serde_json::Value = client .post(format!("{BASE_URL}/api/v1/torrents")) .header("Authorization", format!("Bearer {token}")) .json(&serde_json::json!({ "torrent": torrent_b64, "category": "anime", "sub_category": "raw", "languages": ["ja"], "comments_enabled": true, })) .send().unwrap().json().unwrap(); println!("{} {}", resp["id"], resp["name"]); }
Wyszukiwanie metadanych torrentów
/api/v1/torrents/searchWyślij proste żądanie POST JSON, aby pobrać listingi torrentów z tymi samymi opcjami wyszukiwania i filtrowania dostępnymi na stronie internetowej. Sam plik .torrent nie jest zwracany — użyj normalnej trasy pobierania w tym celu.
# pip install requests (token already obtained — see upload example) resp = requests.post( f"{BASE_URL}/api/v1/torrents/search", json={"q": "Sword Art Online", "category": "anime", "per_page": 25}, headers={"Authorization": f"Bearer {token}"}, ) resp.raise_for_status() data = resp.json() token = resp.headers.get("X-New-Token", token) # save for next request for t in data["torrents"]: print(t["title"], "-", t["magnet"])
// token already obtained — see upload example const resp = await fetch(`${BASE_URL}/api/v1/torrents/search`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` }, body: JSON.stringify({ q: "Sword Art Online", category: "anime", per_page: 25 }), }); const data = await resp.json(); token = resp.headers.get("x-new-token") ?? token; // save for next request data.torrents.forEach(t => console.log(t.title, "-", t.magnet));
// token already obtained — see upload example $respHeaders = []; $ch = curl_init(BASE_URL . "/api/v1/torrents/search"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode([ "q" => "Sword Art Online", "category" => "anime", "per_page" => 25 ]), CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADERFUNCTION => function($ch, $h) use (&$respHeaders) { $respHeaders[] = $h; return strlen($h); }, CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "Authorization: Bearer " . $token, ], ]); $data = json_decode(curl_exec($ch), true); curl_close($ch); foreach ($respHeaders as $h) { // save new token for next request if (stripos($h, "X-New-Token:") === 0) $token = trim(substr($h, strlen("X-New-Token:"))); } foreach ($data["torrents"] as $t) { echo $t["title"] . " - " . $t["magnet"] . "\n"; }
// client and token already obtained — see upload example let resp = client .post(format!("{BASE_URL}/api/v1/torrents/search")) .header("Authorization", format!("Bearer {token}")) .json(&serde_json::json!({"q": "Sword Art Online", "category": "anime", "per_page": 25})) .send().unwrap(); if let Some(t) = resp.headers().get("x-new-token") { token = t.to_str().unwrap().to_string(); // save for next request } let data: serde_json::Value = resp.json().unwrap(); for t in data["torrents"].as_array().unwrap() { println!("{} - {}", t["title"], t["magnet"]); }
Parametry wyszukiwania
| Pole | Typ | Wymagane | Opis |
|---|---|---|---|
q | string | Nie | Wyszukiwanie pełnotekstowe. Obsługuje prefiksy group:slug, group:"Name", user:name. |
category | string | Nie | Slug kategorii (np. "anime"). |
sub_category | string | Nie | Slug podkategorii (np. "raw"). |
languages | string[] | Nie | Tablica kodów języków BCP 47 (np. en, ja). |
sort | string | Nie | Pole sortowania: date (domyślnie), size, seeders, leechers, completed, title. |
order | string | Nie | Kierunek sortowania: desc (domyślnie) lub asc. |
page | integer | Nie | Numer strony, zaczynając od 1 (domyślnie 1). |
per_page | integer | Nie | Wyników na stronę, 1–250 (domyślnie 50). |
hide_adult | boolean | Nie | Wyklucz torrenty kategorii dla dorosłych. Domyślnie true dla zwykłych użytkowników. |
show_dead | boolean | Nie | Gdy false (domyślnie), torrenty starsze niż okres karencji dla martwych torrentów i bez aktywnych seedów są wykluczane. Ustaw na true, aby je uwzględnić. |
Odpowiedź
{
"total": 1234,
"page": 1,
"per_page": 50,
"total_pages": 25,
"from": 1,
"to": 50,
"torrents": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My Release Title",
"info_hash_v1": "aabbccddeeff...",
"info_hash_v2": null,
"size_fmt": "1.4 GB",
"completed": 42,
"seeders": 10,
"leechers": 3,
"languages": ["ja", "en"],
"comment_count": 7,
"created_at": "2024-01-15 12:34",
"cat_slug": "anime",
"sub_slug": "raw",
"group_name": null,
"uploader": "username",
"magnet": "magnet:?xt=urn:btih:..."
}
]
}comment_count — Liczba nieusuniętych komentarzy do tego torrenta.
Ograniczenie żądań wyszukiwania
Żądania wyszukiwania podlegają oddzielnemu konfigurowalnemu limitowi żądań (domyślnie 60 żądań na 60 sekund na klucz API). Przekroczenie limitu zwraca 429 Too Many Requests. Konta personelu są zwolnione.
Pobierz szczegóły torrenta
/api/v1/torrent/{id}Pobierz pełne metadane pojedynczego torrenta — w tym pola, które endpoint wyszukiwania pomija, takie jak opis w Markdown, osadzony komentarz pliku .torrent, listę plików z rozmiarem każdego z nich oraz pełny układ warstw trackerów. Gdy są dostępne, liczniki seedów i leechów na żywo są odczytywane z trackera.
Odpowiedź
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My Release Title",
"info_hash_v1": "aabbccddeeff...",
"info_hash_v2": null,
"size_fmt": "1.4 GB",
"completed": 42,
"seeders": 10,
"leechers": 3,
"ext_seeders": 128,
"ext_leechers": 14,
"created_at": "2024-01-15 12:34",
"torrent_created": "2024-01-15 12:30",
"created_by_client": "mktorrent 1.1",
"cat_name": "Anime",
"cat_slug": "anime",
"sub_name": "Raw",
"sub_slug": "raw",
"group_name": null,
"group_slug": null,
"uploader": "username",
"uploader_id": "...",
"description": "# My Release\n\nRelease notes here.",
"comment": "",
"is_private": false,
"magnet": "magnet:?xt=urn:btih:...",
"languages": [
{ "code": "ja", "name": "Japanese", "country_code": "jp" }
],
"tracker_tiers": [
{ "tier": 0, "urls": ["udp://tracker.example.org:6969/announce"] }
],
"files": [
{ "path": "My Release/episode-01.mkv", "size": 1503238553 }
],
"comments_enabled": true,
"comments_locked": false,
"comment_count": 7
}seeders, leechers — Liczniki na żywo z wewnętrznego trackera; oba zwracają 0, gdy magazyn trackera nie zawiera wpisu dla tego info hash lub jest nieosiągalny.
ext_seeders, ext_leechers — Najwyższa liczba seedów i leecherów zgłoszona przez dowolny pojedynczy zewnętrzny tracker, który był scrape'owany dla tego torrenta. Trackery śledzące ten sam swarm pokrywają się, więc używane jest maksimum zamiast sumy; oba zwracają 0, gdy żaden tracker nie posiada danych scrape dla tego info hash.
Odpowiedzi błędów
| Status HTTP | Znaczenie |
|---|---|
400 | Identyfikator torrenta musi być 36-znakowym UUID z myślnikami lub 32-znakowym surowym ciągiem szesnastkowym. |
401 | Brakujący, wygasły lub już zrotowany token nośnika. Uwierzytelnij się ponownie przez POST /api/v1/auth/token. |
404 | Nie znaleziono torrenta. |
429 | Przekroczono limit żądań. Spróbuj ponownie po zresetowaniu okna. |
503 | Strona jest w trybie konserwacji lub tylko do odczytu. |
Pobieranie komentarzy do torrenta
/api/v1/torrents/{id}/commentsPobierz paginowane komentarze dla torrenta. Liczba komentarzy na stronę jest kontrolowana przez ustawienie COMMENT_PER_PAGE w pliku .env serwera (domyślnie 20). Tylko torrenty z włączonymi komentarzami zwrócą wyniki — wszystkie inne zwracają 403.
Parametry zapytania
| Pole | Typ | Wymagane | Opis |
|---|---|---|---|
page | integer | Nie | Numer strony, zaczynając od 1 (domyślnie 1). |
# pip install requests (token already obtained — see upload example) TORRENT_ID = "550e8400-e29b-41d4-a716-446655440000" resp = requests.get( f"{BASE_URL}/api/v1/torrents/{TORRENT_ID}/comments", params={"page": 1}, headers={"Authorization": f"Bearer {token}"}, ) resp.raise_for_status() data = resp.json() token = resp.headers.get("X-New-Token", token) # save for next request for c in data["comments"]: print(c["username"], "-", c["body"])
// token already obtained — see upload example const TORRENT_ID = "550e8400-e29b-41d4-a716-446655440000"; const resp = await fetch(`${BASE_URL}/api/v1/torrents/${TORRENT_ID}/comments?page=1`, { headers: { Authorization: `Bearer ${token}` }, }); const data = await resp.json(); token = resp.headers.get("x-new-token") ?? token; // save for next request data.comments.forEach(c => console.log(c.username, "-", c.body));
// token already obtained — see upload example $torrentId = "550e8400-e29b-41d4-a716-446655440000"; $respHeaders = []; $ch = curl_init(BASE_URL . "/api/v1/torrents/{$torrentId}/comments?page=1"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADERFUNCTION => function($ch, $h) use (&$respHeaders) { $respHeaders[] = $h; return strlen($h); }, CURLOPT_HTTPHEADER => ["Authorization: Bearer " . $token], ]); $data = json_decode(curl_exec($ch), true); curl_close($ch); foreach ($respHeaders as $h) { // save new token for next request if (stripos($h, "X-New-Token:") === 0) $token = trim(substr($h, strlen("X-New-Token:"))); } foreach ($data["comments"] as $c) { echo $c["username"] . " - " . $c["body"] . "\n"; }
// client and token already obtained — see upload example let torrent_id = "550e8400-e29b-41d4-a716-446655440000"; let resp = client .get(format!("{BASE_URL}/api/v1/torrents/{torrent_id}/comments?page=1")) .header("Authorization", format!("Bearer {token}")) .send().unwrap(); if let Some(t) = resp.headers().get("x-new-token") { token = t.to_str().unwrap().to_string(); // save for next request } let data: serde_json::Value = resp.json().unwrap(); for c in data["comments"].as_array().unwrap() { println!("{} - {}", c["username"], c["body"]); }
Odpowiedź
{
"torrent_id": "550e8400-e29b-41d4-a716-446655440000",
"page": 1,
"per_page": 20,
"total": 45,
"total_pages": 3,
"comments": [
{
"id": "...",
"user_id": "...",
"username": "uploader",
"role": "user",
"author_banned": false,
"body": "Great release!",
"created_at": "2024-01-15 12:34:00",
"edited_at": null,
"edited_by_username": null,
"deleted_at": null
}
]
}Pole body jest pustym ciągiem, gdy autor komentarza jest zbanowany lub komentarz został usunięty. Flaga author_banned wskazuje, który przypadek ma zastosowanie.
Odpowiedzi błędów
| Status HTTP | Znaczenie |
|---|---|
401 | Brakujący, wygasły lub już zrotowany token nośnika. Uwierzytelnij się ponownie przez POST /api/v1/auth/token. |
403 | Komentarze są wyłączone dla tego torrenta. |
404 | Torrent nie został znaleziony. |
503 | Strona jest w trybie konserwacji lub tylko do odczytu. |
Wyszukiwanie wpisów anime
/api/v1/anime/search?q=<query>Wyszukuj wpisy anime według tytułu, aby uzyskać ich UUID. UUID można przekazać jako anime_id w treści przesyłania, aby powiązać torrent z wpisem anime podczas przesyłania, lub użyć z PUT /api/torrents/{id}/anime po przesłaniu. Uwierzytelnianie nie jest wymagane. Podlega tym samym ograniczeniom szybkości co wyszukiwanie torrentów (domyślnie 60 żądań na 60 sekund na IP).
# pip install requests (no authentication required)
resp = requests.get(
f"{BASE_URL}/api/v1/anime/search",
params={"q": "Sword Art Online", "page": 1, "per_page": 10},
)
resp.raise_for_status()
for item in resp.json()["results"]:
print(item["id"], "-", item["title"])// No authentication required
const resp = await fetch(
`${BASE_URL}/api/v1/anime/search?q=${encodeURIComponent("Sword Art Online")}&page=1&per_page=10`
);
const data = await resp.json();
data.results.forEach(item => console.log(item.id, "-", item.title));// No authentication required
$ch = curl_init(BASE_URL . "/api/v1/anime/search?" . http_build_query([
"q" => "Sword Art Online", "page" => 1, "per_page" => 10,
]));
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
foreach ($data["results"] as $item) {
echo $item["id"] . " - " . $item["title"] . "\n";
}// No authentication required
let data: serde_json::Value = reqwest::blocking::get(
format!("{BASE_URL}/api/v1/anime/search?q=Sword+Art+Online&page=1&per_page=10")
).unwrap().json().unwrap();
for item in data["results"].as_array().unwrap() {
println!("{} - {}", item["id"], item["title"]);
}Parametry zapytania
| Pole | Typ | Wymagane | Opis |
|---|---|---|---|
q | string | Tak | Ciąg wyszukiwania tytułu (wymagany). Dopasowywany do tytułu i synonimów. |
page | integer | Nie | Numer strony, zaczynając od 1 (domyślnie 1). |
per_page | integer | Nie | Wyników na stronę, 1–50 (domyślnie 10). |
Odpowiedź
{
"total": 42,
"page": 1,
"per_page": 10,
"total_pages": 5,
"results": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"title": "Sword Art Online",
"anime_type": "TV",
"episodes": 25,
"status": "FINISHED",
"season": "FALL",
"season_year": 2012,
"picture": "https://cdn.myanimelist.net/images/anime/...",
"thumbnail": "https://cdn.myanimelist.net/images/anime/...",
"duration_secs": 1440
}
]
}Wyświetlanie i pobieranie grup
/api/v1/groupsZwraca paginowaną listę publicznych grup (aktywnych i niezablokowanych). Wymaga uwierzytelniania tokenem Bearer.
/api/v1/groups/{id_or_slug}Zwraca pojedynczą publiczną grupę na podstawie numerycznego ID lub sluga. Zwraca 404, jeśli grupa jest wyłączona lub zablokowana.
Parametry zapytania (tylko lista)
| Pole | Typ | Wymagane | Opis |
|---|---|---|---|
q | string | Nie | Filtruj według nazwy grupy (opcjonalnie, dopasowanie podciągu). |
page | integer | Nie | Numer strony (domyślnie 1). |
per_page | integer | Nie | Wyniki na stronę, 1–100 (domyślnie 20). |
sort | string | Nie | Kolumna sortowania: name | slug | members | torrents | created (domyślnie name). |
order | string | Nie | Kierunek sortowania: asc lub desc (domyślnie asc). |
Odpowiedź (lista)
{
"total": 12,
"page": 1,
"per_page": 20,
"total_pages": 1,
"groups": [
{
"id": 1,
"name": "SubsPlease",
"slug": "subsplease",
"subdomain_slug": "subsplease",
"description": "Weekly simulcast batches.",
"owner": "admin",
"member_count": 42,
"torrent_count": 1337,
"created_at": "2024-01-15 12:34"
}
]
}Odpowiedź (pojedyncza)
{
"id": 1,
"name": "SubsPlease",
"slug": "subsplease",
"subdomain_slug": "subsplease",
"description": "Weekly simulcast batches.",
"owner": "admin",
"member_count": 42,
"torrent_count": 1337,
"created_at": "2024-01-15 12:34"
}Odpowiedzi błędów
| Status HTTP | Znaczenie |
|---|---|
401 | Brakujący, wygasły lub już zrotowany token nośnika. Uwierzytelnij się ponownie przez POST /api/v1/auth/token. |
404 | Grupa nie została znaleziona lub jest niedostępna publicznie. |
429 | Przekroczono limit żądań. Spróbuj ponownie po zresetowaniu okna. |
503 | Strona jest w trybie konserwacji lub tylko do odczytu. |
8. Darowizny
Jeśli chcesz wesprzeć AniRena i pomóc pokryć koszty hostingu naszych serwerów i usług, zapraszamy do wysłania darowizny na jeden z poniższych portfeli kryptowalut:
bc1qy2h3ddq6ak5damvnf4r5vu3ydehhxrcq8gllwn0xCbaFe03832F95F86AF2536d52710e78C63b62Cd33ucetj2XDGHQg9PVRPMxerNi7c6kX7GJkjQNg9yjwGegLbpt61yX3RjGtB1Ef8vgVz6Hr6baQsTjVkKażda darowizna, duża czy mała, jest bardzo ceniona i trafia bezpośrednio na utrzymanie AniRena. Dziękujemy za wsparcie!
9. Oprogramowanie
AniRena Player to bezpłatna aplikacja na komputery, która umożliwia strumieniowanie wideo bezpośrednio z torrentów indeksowanych w tym serwisie — bez konieczności czekania na zakończenie pełnego pobierania. Wystarczy wkleić link magnet lub otworzyć plik .torrent, a odtwarzanie rozpocznie się, gdy tylko będzie dostępna wystarczająca ilość danych.
Obie wersje są w pełni samodzielne — wszystkie zależności są zawarte wewnątrz pliku wykonywalnego. Bez instalatora i bez konieczności konfigurowania środowiska — wystarczy pobrać i uruchomić.
Instalator (.exe). Aktualizuje się sam w aplikacji.
Obraz dysku (.dmg) dla Maców z Apple Silicon (M1 i nowsze). Aktualizuje się sam w aplikacji.
Obraz dysku (.dmg) dla Maców z Intel. Aktualizuje się sam w aplikacji.
Przenośny pojedynczy plik, instalacja nie jest wymagana. Jedyny format Linux z automatyczną aktualizacją w aplikacji.
Instalacja: sudo apt install ./<file>.deb — aktualizacje przez apt lub nowe pobranie, nie w aplikacji.
Instalacja: sudo dnf install ./<file>.rpm — aktualizacje przez dnf lub nowe pobranie, nie w aplikacji.
Sideload na 64-bitowych urządzeniach Android ARM (większość nowoczesnych telefonów / tabletów). Aktualizacja przez pobranie nowego APK.
Starsze wersje
Zainstaluj ręcznie na 32-bitowych urządzeniach Android ARM (starsze telefony / tablety). Aktualizacja przez pobranie nowego pliku APK.