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), Edit audio (1 MP4 + 1 MP3), Create a video (1 JPG/PNG + 1 MP3), Overlay video (2 MP4 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 + 1 MP3 → edycja audio (mode=mix_audio do nakładania). Wiele MP4 → 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. 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 Klipy są składane sekwencyjnie w podanej kolejności. Opcjonalne przejścia między klipami.
Edytuj audio add_audio lub mix_audio 1 MP4 + 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 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 + 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, lub 1 MP4 + 1 MP3, lub 1 obraz (JPG/PNG) + 1 MP3. Max. 500 MB na plik.
modestring*image_to_video | add_audio | mix_audio. Wymagane dla tych trzech trybów. Ignorowane (automatycznie wykrywane) gdy wszystkie pliki to MP4 (fusion). Gdy pole mode jest podane, przesłane pliki muszą dokładnie pasować.
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.

Odpowiedź sukcesu (HTTP 200)

{ "success": true, "job_id": "a3f1c8d2e5b09471...", "mode": "fusion", // "fusion" | "add_audio" | "mix_audio" | "image_to_video" | "overlay_video" "file_count": 2, "transition": null, "quota_used": 1, "quota_remaining": 9, "status_url": "https://rapidvideomaker.com/api/v1/jobs.php?job_id=a3f1c8..." }

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"
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)

apidocs_th_paramTypDomyślnieapidocs_th_desc
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)

apidocs_th_paramTypapidocs_th_requiredapidocs_th_desc
job_idstringapidocs_requiredID zadania (hex 32 znaki) ukończonego wideo
publicationsarrayapidocs_requiredTablica obiektów publikacji (maks. 10)

Obiekt publikacji

apidocs_th_paramTypapidocs_th_requiredapidocs_th_desc
account_idintegerapidocs_requiredID 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: direct
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

apidocs_th_codeZnaczenie
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

Zwraca gotowy plik MP4 jako strumień (Content-Type: video/mp4). 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.

Opcjonalny parametr

ParametrOpis
filenameSugerowana nazwa pobieranego pliku (np. moje-wideo.mp4)

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"}, )

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.