RapidVideoMaker
Utwórz konto

API RapidVideoMaker

The REST API lets you process video files from any HTTP client — Python scripts, n8n workflows, third-party tools. Five modes available: Merge videos (multiple MP4/MOV), Edit audio (1 MP4/MOV + 1 MP3), Create a video (1 JPG/PNG + 1 MP3), Overlay video (2 MP4/MOV picture-in-picture). Processing is asynchronous: submit files, then poll for the result.

Pobierz swój token API bezpłatnie
Utwórz konto, aby uzyskać token API — 20 żądań dziennie w zestawie, do użytku przez interfejs lub API.
Utwórz bezpłatne konto Masz już konto? Zaloguj się

Pełny przepływ pracy

Każda integracja przebiega według tej samej sekwencji 4 kroków:

1
Utwórz zadanie — POST /api/v1/render.php
Wyślij pliki jako multipart/form-data z tokenem Bearer. 1 JPG/PNG + 1 MP3 + mode=image_to_video → generowanie wideo. 1 MP4/MOV + 1 MP3 → edycja audio (mode=mix_audio do nakładania). Wiele MP4/MOV → scalenie. Serwer zwraca unikalny job_id.
2
Monitoruj zadanie — GET /api/v1/jobs.php?job_id=…
Odpytuj ten endpoint regularnie (co 5–10 sek.). Zadanie przechodzi przez queuedprocessingready (lub error). Odpowiedź zawiera pozycję w kolejce i szacowany czas.
3
Pobierz URL do pobrania
Gdy status to ready, odpowiedź zawiera gotowe pole download_url.
4
Pobierz plik — GET /api/download.php?job_id=…
Pobierz gotowy plik MP4/MOV. Plik jest dostępny przez 2 godziny po zakończeniu zadania, potem automatycznie usuwany. Po wygaśnięciu API odpowiada 410 Gone.

Uwierzytelnianie

Każde żądanie musi zawierać token API. Akceptowane są dwa formaty:

# Uwierzytelnianie — Każde żądanie musi zawierać token API. Akceptowane są dwa formaty: Authorization: Bearer rvm_your_token_here # Alternative X-API-Key: rvm_your_token_here

Twój token jest dostępny w przestrzeni członkowskiejjeden token na konto, tworzony automatycznie przy rejestracji. Jest wyświetlany w postaci jawnej tylko raz — przechowuj go bezpiecznie. W razie utraty możesz go zregenerować ze swojej przestrzeni członkowskiej.

Limit

Każde konto członkowskie ma 20 żądań dziennie, wspólnych dla interfejsu webowego i API. Nieudane zadania nie zużywają limitu. Licznik resetuje się o północy UTC.

Odpowiedzi POST zawierają quota_used i quota_remaining. Po przekroczeniu limitu serwer odpowiada 429.

Interfejs + API = ten sam licznik. Wideo created przez interfejs webowy i żądanie API zużywają każde po 1 kredycie z tego samego dziennego limitu.

Kolejka

Jedno zadanie jest przetwarzane na raz. Jeśli kilka zadań zostanie przesłanych jednocześnie, są kolejkowane w kolejności przyjęcia. Podczas oczekiwania odpowiedź statusu zawiera:

Zastosowano limit szybkości: endpoint /api/v1/jobs.php akceptuje maksymalnie 12 wywołań na minutę na token. Powyżej serwer odpowiada 429 z nagłówkiem Retry-After: 5. Zalecenie: 10 sekund między wywołaniami.

Dostępne przejścia

Przekaż transition_type=none (domyślnie) dla bezpośredniego scalenia lub jeden z poniższych typów dla przejścia między klipami:

none fade fadeblack dissolve wipeleft wiperight slideleft slideright zoomin circleclose

Czas trwania (transition_duration) wynosi między 0,2 a 2,0 sekundy. Jeśli klip jest za krótki, przejście jest ignorowane.

Endpointy

POST /api/v1/render.php Tworzy zadanie przetwarzania wideo

Five modes, accessible via the mode field (omit mode with multiple MP4s to auto-detect fusion):

UżycieTryb APIWymagane plikiOpis
Scal wideo fusion 2–20 plików MP4/MOV Klipy są składane sekwencyjnie w podanej kolejności. Opcjonalne przejścia między klipami.
Edytuj audio add_audio lub mix_audio 1 MP4/MOV + 1 MP3 Zastępuje lub wzbogaca ścieżkę audio wideo. Ścieżka wideo nigdy nie jest ponownie kodowana (-c:v copy).

add_audio — oryginalne audio jest usuwane i zastępowane MP3.
mix_audio — oryginalne audio jest zachowywane i MP3 jest nakładane (amix).
Utwórz wideo image_to_video 1 JPG/PNG + 1 MP3 Generuje wideo ze statycznego obrazu i pliku audio. Nakładka tekstowa, zanikanie, rozdzielczość i FPS konfigurowalne przez pole options.
Overlay video overlay_video 2 MP4/MOV Nakłada drugi film na film główny. Pozycja, rozmiar, przezroczystość i dźwięk konfigurowalne przez pole options.
Tekst na MP3 text_to_mp3 (tylko tekst) Konwertuje tekst na mowę i zwraca plik MP3. Nie trzeba przesyłać pliku — wyślij mode=text_to_mp3, text i lang jako pola formularza. Obsługuje wszystkie 20 języków witryny.
Ścisła walidacja: każdy tryb wymaga dokładnej liczby i typu plików. add_audio i mix_audio akceptują tylko 1 MP4/MOV + 1 MP3. image_to_video tylko 1 JPG/PNG + 1 MP3. Typy MIME są weryfikowane przez magic bytes.
Reguła czasu trwania: w trybach audio i image_to_video czas trwania wyniku jest równy czasowi trwania MP3. Ścieżka wideo nigdy nie jest ponownie kodowana (-c:v copy).

Wspólne parametry (multipart/form-data)

PoleTypWym.Opis
videos[]File[]TAKPliki do przetworzenia. W zależności od trybu: 2–20 MP4/MOV, lub 1 MP4/MOV + 1 MP3, lub 1 obraz (JPG/PNG) + 1 MP3. Max. 500 MB na plik.
modestring*image_to_video | add_audio | mix_audio | overlay_video | text_to_mp3. Wymagane dla tych trybów innych niż fusion. Pominięcie mode przy samych plikach MP4/MOV zawsze uruchamia fusion (łączenie przez kopiowanie strumienia) — nigdy overlay_video, nawet przy przesłaniu dokładnie 2 plików MP4/MOV. Do edycji audio: add_audio usuwa oryginał, mix_audio zachowuje go i nakłada. Jeśli podano pole mode, przesłane pliki muszą dokładnie pasować — w przeciwnym razie żądanie zostanie odrzucone.
orderJSONTylko tryb fusion — tablica JSON indeksów definiujących kolejność klipów.
transition_typestringTylko tryb fusion. Domyślnie: none. Zobacz listę dostępnych przejść.
transition_durationfloatTylko tryb fusion. Czas trwania 0,2–2,0 sek. Domyślnie: 0.5.
optionsJSONTylko tryb image_to_video — obiekt JSON parametrów renderowania (patrz poniżej).
callback_urlstringPubliczny URL (http/https) wywoływany po zakończeniu zadania. Odpowiedź zawiera webhook_secret.

Parametry options — tryb image_to_video

Wszystkie opcjonalne. Niepodane wartości → domyślne workera.

KluczTypDomyślnieOpis
textstring""Tekst wyświetlany jako nakładka. Puste = brak tekstu. Max. 500 znaków.
font_sizeint60Rozmiar czcionki w pikselach. Zakres: 10–300. Zalecane: 36, 48, 60, 72, 96.
text_colorstring"white"Kolor tekstu (np. white, yellow, #ffffff).
text_positionstring"center"Pozycja tekstu: center, top, bottom.
boxbooltruePółprzezroczyste tło za tekstem.
box_colorstring"black@0.4"Kolor + krycie w formacie FFmpeg: kolor@krycie. Krycie: 0,0–1,0 (np. black@0.4 = 40% czerni).
fade_durationfloat0.5Czas trwania wejścia/wyjścia w sekundach (0–2). 0 = brak zanikania.
widthint1080Szerokość wideo w pikselach (64–3840, parzysta). Standard: 1080/1920/720/1280.
heightint1920Wysokość wideo w pikselach (64–3840, parzysta).
fpsint24Liczba klatek na sekundę (1–60).
image_fitstring"contain"Tryb kadrowania: contain = pełny obraz widoczny, puste obszary wypełnione bg_color; cover = obraz powiększony, nadmiar przycinany. bg_color ignorowane w cover.
bg_colorstring"black"Kolor tła gdy obraz nie wypełnia rozdzielczości — tylko przy image_fit=contain (np. black, white, #1a1a2e).
enable_image_motionboolfalseWłącza animację zdjęcia. Przy false obraz pozostaje statyczny. Przy true efekt image_motion_effect jest stosowany przez FFmpeg zoompan.
image_motion_effectstring"ken_burns"Efekt animacji. Wartości: zoom_in, zoom_out, pan_left_to_right, pan_right_to_left, pan_top_to_bottom, pan_bottom_to_top, zoom_pan_soft, ken_burns. Domyślnie: ken_burns.
motion_intensityfloat1.0Intensywność animacji zdjęcia (0,25–2,0). Mnoży amplitudę zoomu i prędkość panoramy.
text_effectstring"none"Animacja tekstu. Wartości: none, fade_in, slide_up, slide_down, slide_left, bounce.
text_effect_intensityfloat1.0Intensywność animacji tekstu (0,25–2,0).
text_border_widthint0Grubość czarnego obrysu w pikselach (0 = wyłączone, 1–10). Poprawia czytelność.
text_modestring"static"Tryb wyświetlania tekstu. static (domyślny): pełny tekst widoczny od pierwszej klatki. word_by_word: słowa pojawiają się jedno po drugim w tempie word_reveal_speed. Wyklucza text_effect: gdy text_mode=word_by_word, text_effect jest ignorowany.
word_reveal_speedfloat1.5Prędkość odkrywania słów na sekundę (0,3–5,0, domyślnie 1,5). Tylko z text_mode=word_by_word. Zalecana wartość do synchronizacji z OpenAI TTS: 2,0.
word_animstring"none"Animacja pojawiania się każdego słowa. none (domyślnie): natychmiastowe wyświetlenie. fade: każde nowe słowo pojawia się z zanikaniem 0.2s i crossfade. Tylko przy text_mode=word_by_word.

Parametry options — tryb overlay_video

Wszystkie opcjonalne. Kolejność przesyłania ma znaczenie: pierwszy plik to główny film (tło), drugi plik to nakładka (pierwszy plan). Użyj chroma_key, aby usunąć zielone tło z nakładki.

KluczTypDomyślnieOpis
positionstring"bottom-right"Narożnik, w którym umieszczana jest nakładka: top-left, top-right, bottom-left, bottom-right lub center.
scalefloat0.30Rozmiar nakładki jako ułamek szerokości głównego filmu. 0.25 = 25% szerokości. Zakres: 0.05–1.0.
opacityfloat1.0Przezroczystość nakładki. 1.0 = całkowicie nieprzezroczysta, 0.0 = niewidoczna.
marginint10Odstęp w pikselach między nakładką a krawędzią kadru. Ignorowany przy position=center. Zakres: 0–200.
audiostring"main"Która ścieżka audio ma pozostać. main: tylko audio głównego filmu. overlay: tylko audio nakładki. mix: obie ścieżki zmiksowane.
chroma_keyboolfalseUstaw true, aby usunąć czyste zielone tło (#00FF00) z nakładki — przydatne dla kamerki lub animacji nagranych na zielonym ekranie.
chroma_similarityfloat0.20Tolerancja chromakey. Niska = ścisłe dopasowanie. Wysoka = szersze usuwanie. Zalecane: 0.10–0.20 dla zieleni cyfrowej, 0.25–0.45 dla ekranu fizycznego. Zakres: 0.01–0.60.

Parametry options — Edycja audio (mix_audio)

Dostępne tylko z mode=mix_audio. Ignorowane dla add_audio.

KluczTypDomyślnieOpis
mp3_volumefloat1.0Głośność nakładanego MP3 (0,0 = wyciszony, 1,0 = oryginał, 2,0 = podwójny). Wartości powyżej 1,0 mogą powodować przesterowanie.

Tryb text_to_mp3 — bezpośrednie parametry (bez JSON options)

W przeciwieństwie do innych trybów, te pola są wysyłane bezpośrednio jako pola formularza, a nie wewnątrz obiektu JSON options. Wymagane jest tylko pole text.

KluczTypDomyślnieOpis
textstringTekst do zamiany na mowę. Wymagane. Maksymalnie 5000 znaków.
langstring"en"Kod języka używany do wyboru domyślnego głosu, gdy voice jest pominięte lub nieprawidłowe. Jeden z 20 języków witryny (zobacz tabelę poniżej). W przypadku nieznanego kodu używane jest en.
voicestringautomatycznieID głosu edge-tts (zobacz tabelę poniżej). Jeśli pominięte lub nieprawidłowe, automatycznie używany jest pierwszy głos dla lang.
slowboolfalseUstaw na true (lub 1), aby zwolnić tempo mowy o 25%. Każda inna wartość jest traktowana jako false.
Nie wymaga przesyłania pliku: w przeciwieństwie do innych trybów, text_to_mp3 nie wymaga videos[]. Wyślij mode=text_to_mp3 razem z text / lang / voice / slow jako zwykłe pola formularza.

Dostępne głosy (edge-tts, Microsoft Neural), pogrupowane według kodu języka:

JęzykDostępne głosy
en en-US-AvaNeural, en-US-AndrewNeural, en-GB-LibbyNeural
fr fr-FR-DeniseNeural, fr-FR-HenriNeural, fr-FR-EloiseNeural
es es-ES-ElviraNeural, es-ES-AlvaroNeural, es-MX-DaliaNeural
ar ar-SA-ZariyahNeural, ar-SA-HamedNeural, ar-EG-SalmaNeural
pt pt-BR-FranciscaNeural, pt-BR-AntonioNeural, pt-PT-RaquelNeural
de de-DE-KatjaNeural, de-DE-ConradNeural, de-DE-AmalaNeural
it it-IT-ElsaNeural, it-IT-DiegoNeural, it-IT-IsabellaNeural
nl nl-NL-ColetteNeural, nl-NL-MaartenNeural
ru ru-RU-SvetlanaNeural, ru-RU-DmitryNeural
tr tr-TR-EmelNeural, tr-TR-AhmetNeural
hi hi-IN-SwaraNeural, hi-IN-MadhurNeural
bn bn-IN-TanishaaNeural, bn-IN-BashkarNeural
ur ur-PK-UzmaNeural, ur-PK-AsadNeural
id id-ID-GadisNeural, id-ID-ArdiNeural
ja ja-JP-NanamiNeural, ja-JP-KeitaNeural
ko ko-KR-SunHiNeural, ko-KR-InJoonNeural
zh-CN zh-CN-XiaoxiaoNeural, zh-CN-YunxiNeural, zh-CN-XiaoyiNeural
zh-TW zh-TW-HsiaoChenNeural, zh-TW-YunJheNeural
vi vi-VN-HoaiMyNeural, vi-VN-NamMinhNeural
pl pl-PL-ZofiaNeural, pl-PL-MarekNeural

Odpowiedź sukcesu (HTTP 200)

{ "success": true, "job_id": "a3f1c8d2e5b09471...", "mode": "fusion", // "fusion" | "add_audio" | "mix_audio" | "image_to_video" | "overlay_video" | "text_to_mp3" "file_count": 2, "transition": null, "quota_used": 1, "quota_remaining": 9, "status_url": "https://rapidvideomaker.com/api/v1/jobs.php?job_id=a3f1c8..." }
W przypadku text_to_mp3 odpowiedź nie zawiera pól file_count ani transition (żaden plik nie został przesłany) — reszta jest identyczna: job_id, quota_used, quota_remaining, status_url, webhook_secret.

Przykład curl — tryb image_to_video

curl -X POST https://rapidvideomaker.com/api/v1/render.php \ -H "Authorization: Bearer rvm_your_token" \ -F "videos[]=@scene.jpg" \ -F "videos[]=@narration.mp3" \ -F "mode=image_to_video" \ -F 'options={"text":"Chapter 1","font_size":72,"text_color":"white","text_position":"bottom","box":true,"box_color":"black@0.4","fade_duration":0.5,"width":1080,"height":1920,"image_fit":"contain","bg_color":"black","enable_image_motion":true,"image_motion_effect":"ken_burns","motion_intensity":1.0,"text_effect":"slide_up","text_effect_intensity":1.0}' # image_fit : "contain" | "cover" # bg_color : ignored if image_fit="cover" # enable_image_motion : true = animation on, false (default) = static image # image_motion_effect : zoom_in | zoom_out | pan_left_to_right | pan_right_to_left | pan_top_to_bottom | pan_bottom_to_top | zoom_pan_soft | ken_burns # motion_intensity : 0.25–2.0 — photo animation amplitude (default 1.0) # text_effect : none | fade_in | slide_up | slide_down | slide_left | bounce (ignored if text_mode=word_by_word) # text_effect_intensity : 0.25–2.0 — text animation intensity (default 1.0) # text_border_width : 0–10 px — black outline around characters (0 = disabled) # text_mode : "static" (default) | "word_by_word" — reveal words one by one # word_reveal_speed : 0.3–5.0 w/s — speed for word_by_word mode (default 1.5, ~2.0 for OpenAI TTS) # word_anim : "none" (default) | "fade" — fade-in crossfade on each word (word_by_word only)

Przykład curl — Edycja audio

# Replace audio (deletes original) curl -X POST https://rapidvideomaker.com/api/v1/render.php \ -H "Authorization: Bearer rvm_your_token" \ -F "videos[]=@my_video.mp4" \ -F "videos[]=@my_music.mp3" \ -F "mode=add_audio" # Keep original audio + overlay MP3 curl -X POST https://rapidvideomaker.com/api/v1/render.php \ -H "Authorization: Bearer rvm_your_token" \ -F "videos[]=@my_video.mp4" \ -F "videos[]=@my_music.mp3" \ -F "mode=mix_audio" \ -F 'options={"mp3_volume":0.7}' # mp3_volume : 0.0 (muted) → 1.0 (original volume, default) → 2.0 (amplified)

Przykład curl — tryb overlay_video

curl -X POST https://rapidvideomaker.com/api/v1/render.php \ -H "Authorization: Bearer rvm_your_token" \ -F "videos[]=@main_video.mp4" \ -F "videos[]=@overlay_video.mp4" \ -F "mode=overlay_video" \ -F 'options={"position":"bottom-right","scale":0.25,"opacity":1.0,"margin":20,"audio":"main"}' # Green screen overlay curl -X POST https://rapidvideomaker.com/api/v1/render.php \ -H "Authorization: Bearer rvm_your_token" \ -F "videos[]=@main_video.mp4" \ -F "videos[]=@webcam_greenscreen.mp4" \ -F "mode=overlay_video" \ -F 'options={"position":"bottom-left","scale":0.35,"chroma_key":true,"chroma_similarity":0.15,"audio":"mix"}' # position : top-left | top-right | bottom-left | bottom-right | center (default: bottom-right) # scale : 0.05–1.0 — overlay width as fraction of main video (default 0.30) # opacity : 0.0–1.0 — overlay transparency (default 1.0) # margin : 0–200 px — gap from frame edge, ignored if center (default 10) # audio : main | overlay | mix — audio to keep (default: main) # chroma_key : true | false — remove green (#00FF00) background from overlay (default false) # chroma_similarity : 0.01–0.60 — green screen tolerance (default 0.20)

Przykład curl — Scalanie wideo

curl -X POST https://rapidvideomaker.com/api/v1/render.php \ -H "Authorization: Bearer rvm_your_token" \ -F "videos[]=@clip1.mp4" \ -F "videos[]=@clip2.mp4" \ -F "transition_type=fade" \ -F "transition_duration=0.5"

Przykład curl — tryb text_to_mp3

# No file upload — text + lang + voice as plain form fields curl -X POST https://rapidvideomaker.com/api/v1/render.php \ -H "Authorization: Bearer rvm_your_token" \ -F "mode=text_to_mp3" \ -F "text=Welcome to Rapid Video Maker." \ -F "lang=en" \ -F "voice=en-US-AvaNeural" \ -F "slow=false" # voice omitted or invalid -> falls back to the first voice of "lang" curl -X POST https://rapidvideomaker.com/api/v1/render.php \ -H "Authorization: Bearer rvm_your_token" \ -F "mode=text_to_mp3" \ -F "text=Bienvenue sur Rapid Video Maker." \ -F "lang=fr"
GET /api/v1/jobs.php?job_id=<hex32> Status zadania

Możliwe statusy

StatusZnaczenieDodatkowe pola
queued W kolejce, jeszcze nie przetworzone queue_position, queue_total, eta_minutes
processing Przetwarzanie FFmpeg w toku
ready Ukończone — plik dostępny download_url, created_at, expires_at
error Przetwarzanie nie powiodło się error (message)

Odpowiedzi według statusu

{ "job_id": "a3f1c8...", "status": "queued", "queue_position": 2, "queue_total": 3, "eta_minutes": 7 }
{ "job_id": "a3f1c8...", "status": "ready", "download_url": "https://rapidvideomaker.com/api/download.php?job_id=a3f1c8...", "created_at": "2026-06-02T10:00:00+00:00", "expires_at": "2026-06-02T12:00:00+00:00" }

Przykład curl

curl -H "Authorization: Bearer rvm_your_token" \ "https://rapidvideomaker.com/api/v1/jobs.php?job_id=a3f1c8..."
GET /api/v1/jobs.php List all jobs created with this token (paginated, sorted by date desc)

Wspólne parametry (multipart/form-data)

ParametrTypDomyślnieOpis
pageinteger1Page number (starts at 1)
limitinteger20Results per page (max 50, default 20)

Odpowiedzi według statusu

{ "success": true, "jobs": [ { "job_id": "a3f1c8...", "status": "ready", "mode": "fusion", "created_at": "2026-06-02T10:00:00+00:00", "expires_at": "2026-06-02T12:00:00+00:00", "download_url": "https://..." }, ... ], "total": 12, "page": 1, "limit": 20 }
POST /api/v1/publish.php Publikuj wideo na YouTube lub TikTok

Publikuje ukończone zadanie (status=ready) na jednym lub kilku kontach społecznościowych. Token musi należeć do konta członka (nie token administratora).

Wymaganie wstępne: Konta społecznościowe (YouTube, TikTok) muszą być wcześniej połączone przez OAuth na stronie Publikacji w obszarze członkowskim. account_id każdego konta jest tam wyświetlane.

Wspólne parametry (multipart/form-data)

ParametrTypWymaganeOpis
job_idstringTAKID zadania (hex 32 znaki) ukończonego wideo
publicationsarrayTAKTablica obiektów publikacji (maks. 10)

Obiekt publikacji

ParametrTypWymaganeOpis
account_idintegerTAKID połączonego konta społecznościowego — widoczne na stronie Publikacji w obszarze członkowskim
titlestringTytuł wideo (maks. 512 znaków)
descriptionstringOpis wideo (maks. 5 000 znaków)
tagsstringTagi oddzielone przecinkami (maks. 1 024 znaki)
visibilitystringpublic | private | unlisted — Domyślnie: public
tiktok_modestringdraft | direct — Tylko TikTok — domyślnie: draft
tiktok_privacystringtryb directTylko TikTok — wymagane w trybie direct
allow_commentbooleanTylko TikTok — zezwalaj na komentarze
allow_duetbooleanTylko TikTok — zezwalaj na duety
allow_stitchbooleanTylko TikTok — zezwalaj na stitche
your_brandbooleanTylko TikTok — organiczne treści promocyjne ("Twoja marka").
branded_contentbooleanTylko TikTok — ujawnienie treści markowych
tiktok_cover_msintegerTylko TikTok — znacznik czasu klatki okładki w ms (0–60 000, domyślnie 1 000)

Odpowiedzi według statusu

{ "success": true, "results": [ { "account_id": 12, "pub_id": 47, "status": "published", "provider": "youtube", "url": "https://youtu.be/abc123" } ] }

Kody błędów dla każdej publikacji

KodZnaczenie
job_not_readyZadanie nie zostało jeszcze ukończone
mode_not_supportedZadania text_to_mp3 nie mogą być publikowane
account_not_foundKonto nie znalezione lub rozłączone
tiktok_privacy_requiredPoziom prywatności wymagany w trybie direct
publication_failedDostawca zwrócił błąd podczas przesyłania

Przykład cURL

curl -X POST https://rapidvideomaker.com/api/v1/publish.php \ -H "Authorization: Bearer rvm_your_token" \ -H "Content-Type: application/json" \ -d '{ "job_id": "a3f1c8...", "publications": [ { "account_id": 12, "title": "My video", "description": "Created with RapidVideoMaker", "visibility": "public" } ] }'
GET /api/download.php?job_id=<hex32> Pobierz gotowy plik

Przesyła strumieniowo gotowy plik. Content-Type to video/mp4 dla trybów wideo lub audio/mpeg dla text_to_mp3. Nie wymaga tokenu. Dostępny tylko gdy status to ready.

Plik jest przechowywany przez 2 godziny po zakończeniu, potem usuwany. Pobierz go, gdy tylko status stanie się ready.

Opcjonalne parametry

ParametrOpis
filenameSugerowana nazwa pobieranego pliku (np. moje-wideo.mp4)
previewUstaw na 1, aby odtwarzać w linii (pomija Content-Disposition: attachment) zamiast wywoływać pobieranie — używane do podglądu w przeglądarce.

Przykład curl

curl -o "output.mp4" \ "https://rapidvideomaker.com/api/download.php?job_id=a3f1c8...&filename=output.mp4"

Webhooki

Webhooki są alternatywą dla pollingu: zamiast sprawdzać status co X sekund, podajesz URL i serwer automatycznie Cię powiadamia, gdy zadanie jest gotowe.

Jak to działa

  1. Przekaż callback_url w POST do /api/v1/render.php
  2. Odpowiedź zawiera webhook_secret — zachowaj go do weryfikacji podpisów
  3. Gdy zadanie osiągnie ready lub error, serwer wysyła podpisany JSON-POST na Twój URL
  4. Zweryfikuj podpis za pomocą HMAC-SHA256(webhook_secret, raw_body)
Ograniczenia: callback_url musi być publicznie dostępnym URL. Prywatne i loopback IP są zablokowane. Timeout: 10 sekund.

Otrzymany payload

{ "job_id": "a3f1c8...", "status": "ready", "download_url": "https://rapidvideomaker.com /api/download.php?job_id=a3f1c8...", "timestamp": "2026-04-04T12:00:00+00:00" }
{ "job_id": "a3f1c8...", "status": "error", "error": "FFmpeg xfade failed:...", "timestamp": "2026-04-04T12:00:00+00:00" }

Nagłówki wysyłane przez serwer

NagłówekWartość
Content-Typeapplication/json
X-RVM-Signaturesha256=<hmac_hex> — podpis HMAC-SHA256 surowego body
X-RVM-Job-IdOdpowiedni job_id

Weryfikacja podpisu

# Python import hmac, hashlib def verify_webhook(secret: str, body: bytes, signature_header: str) -> bool: expected = "sha256=" + hmac.new( secret.encode(), body, hashlib.sha256 ).hexdigest() return hmac.compare_digest(expected, signature_header) # Flask/FastAPI endpoint: sig = request.headers.get("X-RVM-Signature", "") if not verify_webhook(WEBHOOK_SECRET, request.data, sig): return "Invalid signature", 403 data = request.get_json()

Kody błędów

HTTPKod JSONPrzyczyna
401unauthorizedBrak tokenu, nieprawidłowy lub odwołany
400missing_filesNie otrzymano plików
400too_few_filesWysłano mniej niż 2 pliki
400too_many_filesWysłano więcej niż 20 plików
400invalid_mimeNieobsługiwany plik — akceptowane tylko MP4, MP3 i JPG/PNG (MIME weryfikowany przez magic bytes)
400wrong_file_countLiczba plików nie odpowiada wybranemu trybowi
400wrong_file_typesTypy plików nie odpowiadają wybranemu trybowi
400invalid_file_combinationKombinacja plików bez trybu nie odpowiada żadnemu obsługiwanemu trybowi
400invalid_optionsPole options nie jest prawidłowym JSON lub nie zawiera obiektu
400invalid_optionWartość w options jest nieprawidłowa (kolor, czcionka, pozycja…)
400file_too_largePlik przekracza 500 MB
400invalid_orderTablica order nie jest prawidłową permutacją
400invalid_job_idNieprawidłowy format job_id (musi być 32-znakowym szesnastkowym)
404job_not_foundZadanie nie znalezione — job_id nieznany lub nigdy nie istniał
410job_expiredZadanie wygasło — istniało, ale 2-godzinne okno minęło
429quota_exceededOsiągnięto 20 udanych zadań/dzień
429rate_limitedPonad 12 wywołań/min na /api/v1/jobs.php — poczekaj Retry-After sekund
500server_errorWewnętrzny błąd serwera

Przykłady integracji

Przykłady dla każdego trybu — zainstaluj requests przez pip install requests.

Wspólna konfiguracja

import requests, time, sys, json API_BASE = "https://rapidvideomaker.com" API_TOKEN = "rvm_your_token_here" HEADERS = {"Authorization": f"Bearer {API_TOKEN}"}

Tryb image_to_video — obraz + audio → wideo

with open("scene.jpg", "rb") as fi, open("narration.mp3", "rb") as fa: resp = requests.post( f"{API_BASE}/api/v1/render.php", headers=HEADERS, files=[ ("videos[]", ("scene.jpg", fi, "image/jpeg")), ("videos[]", ("narration.mp3", fa, "audio/mpeg")), ], data={ "mode": "image_to_video", "options": json.dumps({ "text": "Chapter 1", "font_size": 72, "text_color": "white", "text_position": "bottom", "box": True, "box_color": "black@0.4", "fade_duration": 0.5, "width": 1080, "height": 1920, "image_fit": "contain", # "contain" | "cover" "bg_color": "black", # ignored if image_fit="cover" "enable_image_motion": True, "image_motion_effect": "ken_burns", "motion_intensity": 1.0, # 0.25–2.0 — photo animation amplitude "text_effect": "slide_up", # none | fade_in | slide_up | slide_down | slide_left | bounce (ignored if text_mode=word_by_word) "text_effect_intensity": 1.0, # 0.25–2.0 — text animation intensity # word-by-word reveal (mutually exclusive with text_effect): # "text_mode": "word_by_word", "word_reveal_speed": 2.0, "word_anim": "fade" }), }, )

Edycja audio

# Replace audio (deletes original) — mode=add_audio with open("video.mp4", "rb") as fv, open("music.mp3", "rb") as fa: resp = requests.post( f"{API_BASE}/api/v1/render.php", headers=HEADERS, files=[ ("videos[]", ("video.mp4", fv, "video/mp4")), ("videos[]", ("music.mp3", fa, "audio/mpeg")), ], data={"mode": "add_audio"}, ) # Keep original audio + overlay MP3 — mode=mix_audio with open("video.mp4", "rb") as fv, open("music.mp3", "rb") as fa: resp = requests.post( f"{API_BASE}/api/v1/render.php", headers=HEADERS, files=[ ("videos[]", ("video.mp4", fv, "video/mp4")), ("videos[]", ("music.mp3", fa, "audio/mpeg")), ], data={"mode": "mix_audio", "options": json.dumps({"mp3_volume": 0.7})}, # mp3_volume : 0.0 = muted, 1.0 = original volume (default), 2.0 = amplified )

Tryb overlay_video — obraz w obrazie

with open("main.mp4", "rb") as fm, open("overlay.mp4", "rb") as fo: resp = requests.post( f"{API_BASE}/api/v1/render.php", headers=HEADERS, files=[ ("videos[]", ("main.mp4", fm, "video/mp4")), ("videos[]", ("overlay.mp4", fo, "video/mp4")), ], data={ "mode": "overlay_video", "options": json.dumps({ "position": "bottom-right", # top-left | top-right | bottom-left | bottom-right | center "scale": 0.25, # 0.05–1.0 — overlay width fraction "opacity": 1.0, # 0.0–1.0 — transparency "margin": 20, # 0–200 px — gap from frame edge "audio": "main", # main | overlay | mix # green screen: "chroma_key": True, "chroma_similarity": 0.15 }), }, )

Scalanie wideo

with open("clip1.mp4", "rb") as f1, open("clip2.mp4", "rb") as f2: resp = requests.post( f"{API_BASE}/api/v1/render.php", headers=HEADERS, files=[ ("videos[]", ("clip1.mp4", f1, "video/mp4")), ("videos[]", ("clip2.mp4", f2, "video/mp4")), ], data={"transition_type": "fade", "transition_duration": "0.5"}, )

Tryb text_to_mp3 — tekst na mowę

# No files — text + lang (+ optional voice / slow) as form fields resp = requests.post( f"{API_BASE}/api/v1/render.php", headers=HEADERS, data={ "mode": "text_to_mp3", "text": "Welcome to Rapid Video Maker.", "lang": "en", # one of the 20 site language codes "voice": "en-US-AvaNeural", # optional — falls back to the first voice of "lang" "slow": "false", # "true" = -25% speech rate }, )

Polling + pobieranie (wspólne dla wszystkich trybów)

resp.raise_for_status() job_id = resp.json()["job_id"] print(f"Job created: {job_id}") for _ in range(120): # timeout 10 min (120 × 5s) r = requests.get( f"{API_BASE}/api/v1/jobs.php", headers=HEADERS, params={"job_id": job_id}, ) data = r.json() status = data["status"] if status == "queued": pos = data.get("queue_position", "?") eta = data.get("eta_minutes", "?") print(f"Queued — position {pos}, ETA ~{eta} min") elif status == "processing": print("Processing…") elif status == "ready": download_url = data["download_url"] break elif status == "error": sys.exit(f"Error: {data.get('error')}") time.sleep(5) else: sys.exit("Timeout: job not completed after 10 min") r = requests.get(download_url, stream=True) with open("output.mp4", "wb") as f: for chunk in r.iter_content(65536): f.write(chunk) print("Downloaded: output.mp4")

Dwa podejścia w n8n: polling (pętla statusu) lub webhook (serwer wywołuje n8n). Webhook jest zalecany — czystszy, zero zbędnego obciążenia.

Podejście A — Webhook (zalecane)

Tylko 3 węzły, bez pętli.

Węzeł 1 — Wyzwalacz Webhook
Dodaj węzeł Webhook jako wejście workflow (metoda POST). Zanotuj wygenerowany URL, np. https://twoj-n8n.com/webhook/rvm-callback.

Węzeł 2 — Utwórz zadanie (HTTP Request)

MetodaPOST
URLhttps://rapidvideomaker.com/api/v1/render.php
UwierzytelnianieHeader Auth — Authorization: Bearer rvm_…
Typ zawartości bodyForm-Data Multipart
Body paramsPole Binary videos[] dla każdego klipu + Pole Text callback_url = URL węzła webhook

Zachowaj webhook_secret z odpowiedzi w zmiennej workflow.

Węzeł 3 — Przetwórz wynik (w workflow aktywowanym przez webhook)
Gdy n8n otrzyma POST serwera, $json.status to ready lub error. Przy ready, $json.download_url zawiera bezpośredni URL pobierania.

Weryfikacja podpisu: porównaj {{ $headers['x-rvm-signature'] }} z sha256= + HMAC-SHA256 surowego body. Węzeł Code: crypto.createHmac('sha256', secret).update(body).digest('hex').

Podejście B — Polling (bez webhooków)

5 węzłów, pętla statusu co 10 sek.

Węzeł 1 — Utwórz zadanie — ta sama konfiguracja, bez callback_url.

Węzeł 2 — Czekaj — 10 sekund.

Węzeł 3 — Pobierz status (HTTP Request GET)

URLhttps://rapidvideomaker.com/api/v1/jobs.php
Parametry zapytaniajob_id = {{ $('Węzeł 1').item.json.job_id }}
UwierzytelnianieUwierzytelnianie nagłówkiem — ten sam token

Węzeł 4 — If: {{ $json.status }} === 'ready' → true: Węzeł 5 / false: wróć do Węzła 2.

Dodaj licznik iteracji w węźle Set, aby przerwać pętlę po 60 próbach (max. 10 min.).

Węzeł 5 — Pobierz: HTTP Request GET na {{ $json.download_url }}, format odpowiedzi File.

Krok 1 — Utwórz zadanie (wybierz tryb)

# fusion JOB=$(curl -s -X POST https://rapidvideomaker.com/api/v1/render.php \ -H "Authorization: Bearer rvm_your_token" \ -F "videos[]=@clip1.mp4" -F "videos[]=@clip2.mp4") # add_audio (replace audio) JOB=$(curl -s -X POST https://rapidvideomaker.com/api/v1/render.php \ -H "Authorization: Bearer rvm_your_token" \ -F "videos[]=@video.mp4" -F "videos[]=@music.mp3" \ -F "mode=add_audio") # mix_audio (overlay music at 70% volume) JOB=$(curl -s -X POST https://rapidvideomaker.com/api/v1/render.php \ -H "Authorization: Bearer rvm_your_token" \ -F "videos[]=@video.mp4" -F "videos[]=@music.mp3" \ -F "mode=mix_audio" -F 'options={"mp3_volume":0.7}') # image_to_video JOB=$(curl -s -X POST https://rapidvideomaker.com/api/v1/render.php \ -H "Authorization: Bearer rvm_your_token" \ -F "videos[]=@scene.jpg" -F "videos[]=@narration.mp3" \ -F "mode=image_to_video" \ -F 'options={"text":"Chapter 1","font_size":72,"text_position":"bottom","fade_duration":0.5,"width":1080,"height":1920}') JOB_ID=$(echo $JOB | grep -o '"job_id":"[^"]*"' | cut -d'"' -f4) echo "Job ID: $JOB_ID"

Krok 2 — Polling

while true; do STATUS=$(curl -s \ -H "Authorization: Bearer rvm_your_token" \ "https://rapidvideomaker.com/api/v1/jobs.php?job_id=$JOB_ID") STATE=$(echo $STATUS | grep -o '"status":"[^"]*"' | cut -d'"' -f4) echo "Status: $STATE" [ "$STATE" = "ready" ] && break [ "$STATE" = "error" ] && { echo "Error"; exit 1; } sleep 10 done

Krok 3 — Pobieranie

DOWNLOAD_URL=$(echo $STATUS | grep -o '"download_url":"[^"]*"' | cut -d'"' -f4) curl -o output.mp4 "$DOWNLOAD_URL"

Najlepsze praktyki

Pliki wynikowe są przechowywane przez 2 godziny po zakończeniu, potem automatycznie usuwane. Pobierz wideo, gdy tylko status stanie się ready.