RapidVideoMaker
Crea un account

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.

Ottieni il tuo token API gratuitamente
Crea un account per ottenere il tuo token API — 20 richieste incluse al giorno, utilizzabili dall'interfaccia o dall'API.
Crea un account gratuito Hai già un account? Accedi

Flusso di lavoro completo

Ogni integrazione segue la stessa sequenza di 4 passaggi:

1
Creare il job — POST /api/v1/render.php
Invia i file come multipart/form-data con il token Bearer. 1 JPG/PNG + 1 MP3 + mode=image_to_video → generazione video. 1 MP4 + 1 MP3 → modifica audio (mode=mix_audio per sovrapporre). Più MP4 → unione. Il server restituisce un job_id univoco.
2
Attendere il job — GET /api/v1/jobs.php?job_id=…
Interrogare periodicamente questo endpoint (ogni 5–10 sec.). Il job avanza da queuedprocessingready (o error). La risposta include la posizione in coda e il tempo stimato rimanente.
3
Recuperare l'URL di download
Quando lo stato è ready, la risposta contiene un campo download_url pronto all'uso.
4
Scaricare il file — GET /api/download.php?job_id=…
Scarica il file MP4 finale. Il file è disponibile per 2 ore dopo il completamento, poi eliminato automaticamente. Dopo la scadenza, l'API risponde 410 Gone per indicare che il job esisteva ma non è più recuperabile.

Autenticazione

Ogni richiesta deve includere il token API. Sono accettati due formati:

# Autenticazione — Ogni richiesta deve includere il token API. Sono accettati due formati: Authorization: Bearer rvm_your_token_here # Alternative X-API-Key: rvm_your_token_here

Il token è disponibile nel tuo spazio membroun token per account, creato automaticamente alla registrazione. Viene mostrato in chiaro solo una volta — conservalo in modo sicuro. In caso di smarrimento, puoi rigenerarlo dallo spazio membro.

Quota

Ogni account membro ha 20 richieste al giorno, condivise tra interfaccia web e API. I job falliti non consumano quota. Il contatore si azzera a mezzanotte UTC.

Le risposte POST includono quota_used e quota_remaining. Quando il limite è superato, il server risponde 429.

Interfaccia + API = stesso contatore. Un video creato dall'interfaccia web e una richiesta API consumano ciascuno 1 credito dalla stessa quota giornaliera.

Coda

Un job alla volta viene elaborato. Se vengono inviati più job contemporaneamente, vengono accodati in ordine di arrivo. Nell'attesa, la risposta di stato include:

Rate limit applicato: l'endpoint /api/v1/jobs.php accetta al massimo 12 chiamate al minuto per token (1 ogni 5 sec.). Oltre, il server risponde 429 con header Retry-After: 5. Raccomandazione: 10 secondi tra ogni chiamata.

Transizioni disponibili

Passa transition_type=none (predefinito) per unione diretta, o uno dei tipi seguenti per una dissolvenza tra clip:

none fade fadeblack dissolve wipeleft wiperight slideleft slideright zoomin circleclose

La durata (transition_duration) è compresa tra 0,2 e 2,0 secondi. Se un clip è troppo corto per la transizione, viene ignorata e l'unione procede senza.

Endpoint

POST /api/v1/render.php Crea un job di elaborazione video

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

UtilizzoModalità APIFile richiestiDescrizione
Unire video fusion 2–20 file MP4 I clip vengono assemblati in sequenza nell'ordine fornito. Transizioni opzionali tra clip.
Modificare audio add_audio o mix_audio 1 MP4 + 1 MP3 Sostituisce o arricchisce la traccia audio di un video. La traccia video non viene mai ricodificata (-c:v copy).

add_audio — l'audio originale è eliminato e sostituito dall'MP3.
mix_audio — l'audio originale è mantenuto e l'MP3 è sovrapposto (amix). options={"mp3_volume":…} per regolare il volume. Senza audio, si comporta come add_audio.
Creare un video image_to_video 1 JPG/PNG + 1 MP3 Genera un video da un'immagine statica e un file audio. Sovrapposizione testo, dissolvenze, risoluzione e FPS configurabili tramite il campo options.
Overlay video overlay_video 2 MP4 Sovrappone un secondo video al video principale. Posizione, dimensione, opacità e audio configurabili tramite il campo options.
Testo in MP3 text_to_mp3 (solo testo) Converte testo in parlato e restituisce un file MP3. Nessun upload necessario — invia mode=text_to_mp3, text e lang come campi form. Supporta tutte le 20 lingue del sito.
Validazione rigorosa: ogni modalità richiede un numero e un tipo esatto di file. add_audio e mix_audio accettano solo 1 MP4 + 1 MP3. image_to_video solo 1 JPG/PNG + 1 MP3. Qualsiasi altra combinazione viene rifiutata. I tipi MIME sono verificati per magic bytes.
Regola durata: nelle modalità audio e image_to_video, la durata del risultato è bloccata alla durata dell'MP3. La traccia video non viene mai ricodificata (-c:v copy).

Parametri comuni (multipart/form-data)

CampoTipoObb.Descrizione
videos[]File[]File da elaborare. In base alla modalità: 2–20 MP4, o 1 MP4 + 1 MP3, o 1 immagine (JPG/PNG) + 1 MP3. Max 500 MB per file.
modestring*image_to_video | add_audio | mix_audio. Obbligatorio per queste tre modalità. Ignorato (rilevato automaticamente) se tutti i file sono MP4 (fusion). Se il campo mode è fornito, i file caricati devono corrispondere esattamente — altrimenti la richiesta viene rifiutata.
orderJSONSolo modalità fusion — array JSON di indici per l'ordine dei clip.
transition_typestringSolo modalità fusion. Predefinito: none. Vedi elenco transizioni disponibili.
transition_durationfloatSolo modalità fusion. Durata 0,2–2,0 sec. Predefinito: 0.5.
optionsJSONSolo modalità image_to_video — oggetto JSON dei parametri di rendering (vedi sotto).
callback_urlstringURL pubblico (http/https) chiamato al completamento del job. La risposta include un webhook_secret.

Parametri options — modalità image_to_video

Tutti opzionali. Valori non forniti → predefiniti del worker.

ChiaveTipoPredefinitoDescrizione
textstring""Testo mostrato come sovrapposizione. Vuoto = nessun testo. Max 500 caratteri.
font_sizeint60Dimensione font in pixel. Intervallo: 10–300. Raccomandati: 36, 48, 60, 72, 96.
text_colorstring"white"Colore testo (es. white, yellow, #ffffff, 0xffffff).
text_positionstring"center"Posizione testo: center, top, bottom.
boxbooltrueSfondo semi-trasparente dietro il testo.
box_colorstring"black@0.4"Colore + opacità in formato FFmpeg: colore@opacità. Opacità: 0,0–1,0 (es. black@0.4 = nero al 40%).
fade_durationfloat0.5Durata dissolvenza in entrata/uscita in secondi (0–2). 0 = nessuna dissolvenza.
widthint1080Larghezza video in pixel (64–3840, pari forzato). Standard: 1080/1920/720/1280.
heightint1920Altezza video in pixel (64–3840, pari forzato).
fpsint24Frame rate (1–60).
image_fitstring"contain"Modalità inquadratura: contain = immagine completa visibile, aree vuote con bg_color; cover = immagine zoomata, bordi in eccesso tagliati. bg_color ignorato in cover.
bg_colorstring"black"Colore sfondo se l'immagine non riempie la risoluzione — solo con image_fit=contain (es. black, white, #1a1a2e).
enable_image_motionboolfalseAbilita l'animazione foto. Se false, l'immagine rimane statica. Se true, l'effetto di image_motion_effect viene applicato via FFmpeg zoompan.
image_motion_effectstring"ken_burns"Effetto animazione. Valori: 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. Predefinito: ken_burns.
motion_intensityfloat1.0Intensità animazione foto (0,25–2,0). Moltiplica ampiezza zoom e velocità panoramica.
text_effectstring"none"Animazione testo. Valori: none, fade_in, slide_up, slide_down, slide_left, bounce.
text_effect_intensityfloat1.0Intensità animazione testo (0,25–2,0).
text_border_widthint0Spessore contorno nero in pixel (0 = disabilitato, 1–10). Migliora la leggibilità.
text_modestring"static"Modalità di rivelazione del testo. static (predefinito): testo completo visibile dal primo fotogramma. word_by_word: le parole appaiono una per una alla velocità di word_reveal_speed. Esclusivo con text_effect: se text_mode=word_by_word, text_effect viene ignorato.
word_reveal_speedfloat1.5Velocità di rivelazione in parole al secondo (0.3–5.0, predefinito 1.5). Usato solo con text_mode=word_by_word. Valore consigliato per sincronizzazione con OpenAI TTS: 2.0.
word_animstring"none"Animazione di apparizione di ogni parola. none (default): rivelazione istantanea. fade: ogni nuova parola appare con una dissolvenza di 0.2s e crossfade con il blocco precedente. Solo con text_mode=word_by_word.

Parametri options — modalità overlay_video

Tutti opzionali. L'ordine di caricamento è importante: il primo file è il video principale (sfondo), il secondo file è l'overlay (primo piano). Usa chroma_key per rimuovere uno sfondo verde dall'overlay.

ChiaveTipoPredefinitoDescrizione
positionstring"bottom-right"Angolo dove viene posizionato l'overlay: top-left, top-right, bottom-left, bottom-right, o center.
scalefloat0.30Dimensione dell'overlay come frazione della larghezza del video principale. 0.25 = 25% della larghezza. Intervallo: 0.05–1.0.
opacityfloat1.0Trasparenza dell'overlay. 1.0 = completamente opaco, 0.0 = invisibile.
marginint10Distanza in pixel tra l'overlay e il bordo. Ignorato se position=center. Intervallo: 0–200.
audiostring"main"Quale traccia audio mantenere. main: solo audio principale. overlay: solo audio dell'overlay. mix: entrambe le tracce mixate.
chroma_keyboolfalseImposta true per rimuovere lo sfondo verde puro (#00FF00) dall'overlay — utile per webcam o animazioni su sfondo verde.
chroma_similarityfloat0.20Tolleranza del chroma key. Bassa = corrispondenza stretta. Alta = rimozione più ampia. Consigliato: 0.10–0.20 per verde digitale, 0.25–0.45 per schermo fisico. Intervallo: 0.01–0.60.

Parametri options — Modifica audio (mix_audio)

Disponibile solo con mode=mix_audio. Ignorato per add_audio.

ChiaveTipoPredefinitoDescrizione
mp3_volumefloat1.0Volume dell'MP3 sovrapposto (0,0 = muto, 1,0 = originale, 2,0 = doppio). Valori sopra 1,0 possono saturare.

Risposta di successo (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..." }

Esempio curl — modalità 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)

Esempio curl — Modifica 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)

Esempio curl — modalità 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)

Esempio curl — Unire video

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> Stato del job

Stati possibili

StatoSignificatoCampi aggiuntivi
queued In coda, non ancora elaborato queue_position, queue_total, eta_minutes
processing Elaborazione FFmpeg in corso
ready Completato — file disponibile download_url, created_at, expires_at
error Elaborazione fallita error (message)

Risposte per stato

{ "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" }

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

Parametri comuni (multipart/form-data)

apidocs_th_paramTipoPredefinitoapidocs_th_desc
pageinteger1Page number (starts at 1)
limitinteger20Results per page (max 50, default 20)

Risposte per stato

{ "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 Pubblica un video su YouTube o TikTok

Pubblica un job completato (status=ready) su uno o più account social. Il token deve appartenere a un account membro (non un token admin).

Prerequisito: Gli account social (YouTube, TikTok) devono essere prima connessi tramite OAuth nella pagina Pubblicazioni dell'area membro. L'account_id di ogni account è mostrato lì.

Parametri comuni (multipart/form-data)

apidocs_th_paramTipoapidocs_th_requiredapidocs_th_desc
job_idstringapidocs_requiredID job (hex 32 caratteri) del video completato
publicationsarrayapidocs_requiredArray di oggetti di pubblicazione (max. 10)

Oggetto pubblicazione

apidocs_th_paramTipoapidocs_th_requiredapidocs_th_desc
account_idintegerapidocs_requiredID dell'account social connesso — visibile nella pagina Pubblicazioni dell'area membro
titlestringTitolo del video (max. 512 caratteri)
descriptionstringDescrizione del video (max. 5 000 caratteri)
tagsstringTag separati da virgola (max. 1 024 caratteri)
visibilitystringpublic | private | unlisted — Predefinito: public
tiktok_modestringdraft | direct — Solo TikTok — predefinito: direct
tiktok_privacystringmodalità directSolo TikTok — obbligatorio in modalità direct
allow_commentbooleanSolo TikTok — consenti commenti
allow_duetbooleanSolo TikTok — consenti duetti
allow_stitchbooleanSolo TikTok — consenti stitch
your_brandbooleanSolo TikTok — contenuto promozionale organico ("Il tuo brand").
branded_contentbooleanSolo TikTok — divulgazione contenuto di marca
tiktok_cover_msintegerSolo TikTok — timestamp del frame copertina in ms (0–60 000, predefinito 1 000)

Risposte per stato

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

Codici errore per pubblicazione

apidocs_th_codeSignificato
job_not_readyJob non ancora completato
mode_not_supportedI job text_to_mp3 non possono essere pubblicati
account_not_foundAccount non trovato o disconnesso
tiktok_privacy_requiredLivello di privacy richiesto in modalità direct
publication_failedIl provider ha restituito un errore durante l'upload

Esempio 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> Scaricare il file finale

Restituisce il file MP4 finale come stream (Content-Type: video/mp4). Non richiede token. Disponibile solo quando lo stato è ready.

Il file è conservato per 2 ore dopo il completamento, poi eliminato. Scaricalo appena lo stato diventa ready.

Parametro opzionale

ParametroDescrizione
filenameNome suggerito per il file scaricato (es. mio-video.mp4)

Esempio curl

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

Webhook

I webhook sono un'alternativa al polling: invece di controllare lo stato ogni X secondi, fornisci un URL e il server ti chiama automaticamente quando il job è completato.

Come funziona

  1. Passa callback_url nel POST a /api/v1/render.php
  2. La risposta contiene un webhook_secret — conservalo per verificare le firme
  3. Quando il job raggiunge ready o error, il server invia un POST JSON firmato al tuo URL
  4. Verifica la firma con HMAC-SHA256(webhook_secret, raw_body)
Vincoli: callback_url deve essere un URL pubblicamente accessibile. IP privati e di loopback sono bloccati. Timeout: 10 secondi.

Payload ricevuto

{ "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" }

Header inviati dal server

HeaderValore
Content-Typeapplication/json
X-RVM-Signaturesha256=<hmac_hex> — firma HMAC-SHA256 del body grezzo
X-RVM-Job-IdIl job_id rilevante

Verifica della firma

# 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()

Codici di errore

HTTPCodice JSONCausa
401unauthorizedToken mancante, non valido o revocato
400missing_filesNessun file ricevuto
400too_few_filesMeno di 2 file inviati
400too_many_filesPiù di 20 file inviati
400invalid_mimeFile non supportato — solo MP4, MP3 e JPG/PNG accettati (MIME verificato per magic bytes)
400wrong_file_countIl numero di file non corrisponde alla modalità scelta
400wrong_file_typesI tipi di file non corrispondono alla modalità scelta
400invalid_file_combinationLa combinazione di file non corrisponde ad alcuna modalità supportata
400invalid_optionsIl campo options non è JSON valido o non contiene un oggetto
400invalid_optionUn valore in options non è valido (colore, font, posizione…)
400file_too_largeUn file supera i 500 MB
400invalid_orderL'array order non è una permutazione valida
400invalid_job_idFormato job_id errato (deve essere esadecimale a 32 caratteri)
404job_not_foundJob non trovato — job_id sconosciuto o mai esistito
410job_expiredJob scaduto — esisteva ma la finestra di 2 ore è passata
429quota_exceeded20 job riusciti/giorno raggiunti (tutte le modalità)
429rate_limitedPiù di 12 chiamate/min su /api/v1/jobs.php — attendere Retry-After secondi
500server_errorErrore interno del server

Esempi di integrazione

Esempi per ogni modalità — installare requests con pip install requests.

Configurazione comune

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

Modalità image_to_video — immagine + audio → video

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

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

Modalità overlay_video — picture-in-picture

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

Unire video

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 + download (comune a tutte le modalità)

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

Due approcci in n8n: polling (loop di stato) o webhook (il server chiama n8n). Il webhook è raccomandato — più pulito, zero carico inutile.

Approccio A — Webhook (raccomandato)

Solo 3 nodi, nessun loop.

Nodo 1 — Trigger Webhook
Aggiungere un nodo Webhook come input del workflow (metodo POST). Annotare l'URL generato, es. https://tuo-n8n.com/webhook/rvm-callback.

Nodo 2 — Creare il job (HTTP Request)

MetodoPOST
URLhttps://rapidvideomaker.com/api/v1/render.php
AutenticazioneHeader Auth — Authorization: Bearer rvm_…
Tipo contenuto bodyForm-Data Multipart
Body paramsCampo Binary videos[] per ogni clip + Campo Text callback_url = URL del nodo webhook

Conservare il webhook_secret dalla risposta in una variabile del workflow.

Nodo 3 — Elaborare il risultato (nel workflow attivato dal webhook)
Quando n8n riceve il POST del server, $json.status è ready o error. Se ready, $json.download_url contiene l'URL diretto.

Verifica firma: confrontare {{ $headers['x-rvm-signature'] }} con sha256= + HMAC-SHA256 del body grezzo. Nodo Code: crypto.createHmac('sha256', secret).update(body).digest('hex').

Approccio B — Polling (senza webhook)

5 nodi, loop di stato ogni 10 sec.

Nodo 1 — Creare il job — stessa configurazione, senza callback_url.

Nodo 2 — Attendere — 10 secondi.

Nodo 3 — Stato polling (HTTP Request GET)

URLhttps://rapidvideomaker.com/api/v1/jobs.php
Parametri queryjob_id = {{ $('Nodo 1').item.json.job_id }}
AutenticazioneHeader Auth — stesso token

Nodo 4 — If: {{ $json.status }} === 'ready' → true: Nodo 5 / false: torna a Nodo 2.

Aggiungere un contatore in un nodo Set per interrompere il loop dopo 60 tentativi (max 10 min.).

Nodo 5 — Download: HTTP Request GET su {{ $json.download_url }}, formato risposta File.

Passaggio 1 — Creare il job (scegli una modalità)

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

Passaggio 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

Passaggio 3 — Download

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

Best practice

I file dei risultati sono conservati 2 ore dopo il completamento, poi eliminati automaticamente. Scarica il video non appena lo stato diventa ready.