## Basic tool info Model name: wiro/video-caption Model description: Burn captions into a video with TikTok-style timing. Transcribe spoken audio word-by-word or overlay fixed text, with full control over caption style. Model cover: https://cdn.wiro.ai/uploads/models/wiro-video-caption-cover.webp Model categories: - tool - quick-showcase - nogpu-pipeline - video-to-video - utils Run Task Endpoint (POST): https://api.wiro.ai/v1/Run/wiro/video-caption Get Task Detail Endpoint (POST): https://api.wiro.ai/v1/Task/Detail ## Model Inputs: - name: inputVideo label: Input Video help: Required: the video to caption. mp4, mov, mkv and m4v keep their own format; anything else comes back as mp4. type: combinefileinput default: - name: mode label: Mode help: Required. Default 'speech': the speech in the video is transcribed and captioned word by word, timed to the voice. 'fixed' burns the caption text you write below instead, and needs no audio at all. type: select default: speech options: - value: "speech" label: speech - value: "fixed" label: fixed - name: captionEffect label: Caption Effect help: Required. Choose how captions appear: 'Rolling Line' keeps the last three words on screen and drops the oldest as the next one arrives, 'Flash Each Word' shows words briefly, 'Sentence' displays the whole line at once - which in 'fixed' mode leaves it on screen from start to end. type: select default: wordbyword options: - value: "word" label: Rolling Line - value: "wordbyword" label: Flash Each Word - value: "sentence" label: Sentence - name: text label: Caption Text help: Required with 'fixed' mode: the line burned onto the video. Left empty, the run falls back to 'speech' and captions the video's own speech instead. Optional with 'speech', where it is used only if no speech can be made out at all. type: textarea default: - name: captionPosition label: Caption Position help: Optional. Default 'BOTTOM': where the caption sits on the video. type: select default: bottom options: - value: "bottom" label: BOTTOM - value: "top" label: TOP - value: "center" label: CENTER - name: captionFontFamily label: Caption Font Family help: Optional. Default 'Poppins Medium': the font the caption is drawn in. type: select default: Poppins-Medium options: - value: "Poppins-Thin" label: Poppins Thin - value: "Poppins-ThinItalic" label: Poppins Thin Italic - value: "Poppins-ExtraLight" label: Poppins Extra Light - value: "Poppins-ExtraLightItalic" label: Poppins Extra Light Italic - value: "Poppins-Light" label: Poppins Light - value: "Poppins-LightItalic" label: Poppins Light Italic - value: "Poppins-Regular" label: Poppins Regular - value: "Poppins-Italic" label: Poppins Italic - value: "Poppins-Medium" label: Poppins Medium - value: "Poppins-MediumItalic" label: Poppins Medium Italic - value: "Poppins-SemiBold" label: Poppins Semi Bold - value: "Poppins-SemiBoldItalic" label: Poppins Semi Bold Italic - value: "Poppins-Bold" label: Poppins Bold - value: "Poppins-BoldItalic" label: Poppins Bold Italic - value: "Poppins-ExtraBold" label: Poppins Extra Bold - value: "Poppins-ExtraBoldItalic" label: Poppins Extra Bold Italic - value: "Poppins-Black" label: Poppins Black - value: "Poppins-BlackItalic" label: Poppins Black Italic - name: captionFontSize label: Caption Font Size help: Optional: font size in pixels, 8 to 400. Leave empty to scale it from the video's own size, which keeps the same look at any resolution. type: text default: - name: captionFontColor label: Caption Font Color help: Optional. Default #FFFFFF: a hex color code for the caption text. Every word is drawn in this one color. type: text default: #FFFFFF - name: captionBoxColor label: Caption Box Color help: Optional. Default #000000: a hex color code for the box behind the caption. Only visible when the box opacity is above 0.0. type: text default: #000000 - name: captionBoxOpacity label: Caption Box Opacity help: Optional. Default 0.0: how solid the box behind the caption is, 0.0 to 1.0. At 0.0 there is no box at all and the text sits straight on the video. type: text default: 0.0 - name: captionMargin label: Caption Margin help: Optional: distance in pixels from the top or bottom edge, 0 to 1000. Leave empty to scale it from the video's own size. Ignored when the position is center. type: text default: - name: captionMaxWords label: Rolling Line Words help: Optional. Default 3: how many words stay on screen with the 'Rolling Line' effect, 1 to 20. The next word pushes the oldest one off. Only used by that effect. type: text default: 3 ## Model Parameter Inspires: - prompt: Synthesize the speech below as a live horse-racing commentator. AUDIO PROFILE: Ray Tulloch, veteran racecourse commentator SCENE: The final furlong at Doncaster. Forty thousand people on their feet, hooves thundering, the two leaders inseparable. DIRECTOR'S NOTES Style: Controlled chaos. Rising urgency that cracks at the peak. He is calling names faster than he can breathe. Pace: Very fast and accelerating. No gaps, no dead air. Compress the words together at the finish. Accent: Northern English, Doncaster. TRANSCRIPT: And they're into the final furlong, [very fast] Kestrel Lane and Marble Arch stride for stride, nothing between them, nothing at all — [shouting] Marble Arch comes again! Marble Arch on the far rail! Kestrel Lane will not lie down, they are locked together at the line and — [gasp] oh, that is too close to call. - voice: fenrir - prompt: Synthesize the speech below as a hard-boiled detective's voiceover. AUDIO PROFILE: Frank Doyle, private investigator, fifty-one, twenty years too tired SCENE: A one-room office above a laundromat at two in the morning. Rain on the window, a bottle at his elbow, one lamp still burning. DIRECTOR'S NOTES Style: Dry, worn down, faintly amused at his own bad luck. He is talking to himself, not to an audience. Pace: Slow and deliberate, with long pauses between sentences. Let each line land before starting the next. Accent: Mid-century American, working-class Chicago. TRANSCRIPT: She walked in at a quarter past midnight wearing a coat worth more than my car. [sighs] They always come at midnight. That's when the money gets nervous. She told me her husband was missing. [sarcastic] Sure he was. In my experience husbands don't go missing. They go somewhere. And somebody pays me to find out where. - voice: algenib - prompt: Synthesize the speech below as a spacecraft's onboard intelligence. AUDIO PROFILE: HELIOS, onboard intelligence of the deep-space freighter Ardent SCENE: Reactor containment is failing. The corridor is empty. HELIOS is addressing a crew that may already be gone. DIRECTOR'S NOTES Style: Clinical and unhurried. No panic and no warmth, but a thin thread of something almost like regret running underneath the numbers. Pace: Even and metered, with identical spacing between each clause, like a countdown. Accent: Neutral and unplaceable. TRANSCRIPT: [serious] Attention. Containment integrity is at nineteen percent and falling. Estimated time to breach: four minutes, ten seconds. All personnel should proceed immediately to the aft escape modules. I have attempted to reach the bridge nine hundred and forty times. There has been no response. I will continue trying. [whispers] Please acknowledge, if you can hear me. - voice: iapetus - prompt: Synthesize the speech below as a wildlife documentary narrator. AUDIO PROFILE: Margaret Ainsley, natural history narrator, forty years in the field SCENE: A hedgerow at dusk in the Yorkshire Dales, filmed from six inches away. Nothing dramatic is happening, and she finds that fascinating. DIRECTOR'S NOTES Style: Hushed reverence with genuine affection for the animal. Understated — she trusts the picture and never oversells it. Pace: Measured and patient, slowing further on the closing line. Accent: Northern English, Yorkshire. TRANSCRIPT: [curious] He has been awake for four minutes, and already the evening is going badly. Forty grams of hedgehog, one slug, and a rival twice his size who arrived first. He will not win this. He knows he will not win this. [amused] And yet he tries — because a hedgehog's ambition has never once been troubled by arithmetic. - voice: gacrux ## Integration Header Prepare ```bash # Sign up Wiro dashboard and create project export YOUR_API_KEY="{{useSelectedProjectAPIKey}}"; export YOUR_API_SECRET="XXXXXXXXX"; # unix time or any random integer value export NONCE=$(date +%s); # hmac-SHA256 (YOUR_API_SECRET+Nonce) with YOUR_API_KEY export SIGNATURE="$(echo -n "${YOUR_API_SECRET}${NONCE}" | openssl dgst -sha256 -hmac "${YOUR_API_KEY}")"; ``` ## Run Command - Make HTTP Post Request ```bash curl -X POST "https://api.wiro.ai/v1/Run/wiro/video-caption" -H "Content-Type: multipart/form-data" -H "x-api-key: ${YOUR_API_KEY}" -H "x-nonce: ${NONCE}" -H "x-signature: ${SIGNATURE}" -d '{ "inputVideo": "", "mode": "speech", "captionEffect": "wordbyword", "text": "", "captionPosition": "bottom", "captionFontFamily": "Poppins-Medium", "captionFontSize": "", "captionFontColor": "#FFFFFF", "captionBoxColor": "#000000", "captionBoxOpacity": "0.0", "captionMargin": "", "captionMaxWords": "3", "callbackUrl": "You can provide a callback URL; Wiro will send a POST request to it when the task is completed." }'; ``` ## Run Command - Response ```json { "errors": [], "taskid": "2221", "socketaccesstoken": "eDcCm5yyUfIvMFspTwww49OUfgXkQt", "result": true } ``` ## Get Task Detail - Make HTTP Post Request with Task ID ```bash curl -X POST "https://api.wiro.ai/v1/Task/Detail" -H "Content-Type: multipart/form-data" -H "x-api-key: ${YOUR_API_KEY}" -H "x-nonce: ${NONCE}" -H "x-signature: ${SIGNATURE}" -d '{ "taskid": "2221" }'; ``` ## Get Task Detail - Make HTTP Post Request with Socket Access Token ```bash curl -X POST "https://api.wiro.ai/v1/Task/Detail" -H "Content-Type: multipart/form-data" -H "x-api-key: ${YOUR_API_KEY}" -H "x-nonce: ${NONCE}" -H "x-signature: ${SIGNATURE}" -d '{ "tasktoken": "eDcCm5yyUfIvMFspTwww49OUfgXkQt" }'; ``` ## Get Task Detail - Response ```json { "total": "1", "errors": [], "tasklist": [ { "id": "2221", "uuid": "15bce51f-442f-4f44-a71d-13c6374a62bd", "socketaccesstoken": "eDcCm5yyUfIvMFspTwww49OUfgXkQt", "parameters": {}, "debugoutput": "", "debugerror": "", "starttime": "1734513809", "endtime": "1734513813", "elapsedseconds": "6.0000", "status": "task_postprocess_end", "createtime": "1734513807", "canceltime": "0", "assigntime": "1734513807", "accepttime": "1734513807", "preprocessstarttime": "1734513807", "preprocessendtime": "1734513807", "postprocessstarttime": "1734513813", "postprocessendtime": "1734513814", "outputs": [ { "id": "6bc392c93856dfce3a7d1b4261e15af3", "name": "0.png", "contenttype": "image/png", "parentid": "6c1833f39da71e6175bf292b18779baf", "uuid": "15bce51f-442f-4f44-a71d-13c6374a62bd", "size": "202472", "addedtime": "1734513812", "modifiedtime": "1734513812", "accesskey": "dFKlMApaSgMeHKsJyaDeKrefcHahUK", "url": "https://cdn1.wiro.ai/6a6af820-c5050aee-40bd7b83-a2e186c6-7f61f7da-3894e49c-fc0eeb66-9b500fe2/0.png" } ], "size": "202472" } ], "result": true } ``` ## Kill Task - Make HTTP Post Request with Task ID ```bash curl -X POST "https://api.wiro.ai/v1/Task/Kill" -H "Content-Type: multipart/form-data" -H "x-api-key: ${YOUR_API_KEY}" -H "x-nonce: ${NONCE}" -H "x-signature: ${SIGNATURE}" -d '{ "taskid": "534574" }'; ``` ## Kill Task - Make HTTP Post Request with Socket Access Token ```bash curl -X POST "https://api.wiro.ai/v1/Task/Kill" -H "Content-Type: multipart/form-data" -H "x-api-key: ${YOUR_API_KEY}" -H "x-nonce: ${NONCE}" -H "x-signature: ${SIGNATURE}" -d '{ "socketaccesstoken": "ZpYote30on42O4jjHXNiKmrWAZqbRE" }'; ``` ## Kill Task - Response ```json { "errors": [], "tasklist": [ { "id": "534574", "uuid": "15bce51f-442f-4f44-a71d-13c6374a62bd", "name": "", "socketaccesstoken": "ZpYote30on42O4jjHXNiKmrWAZqbRE", "parameters": { "inputImage": "https://api.wiro.ai/v1/File/mCmUXgZLG1FNjjjwmbtPFr2LVJA112/inputImage-6060136.png" }, "debugoutput": "", "debugerror": "", "starttime": "1734513809", "endtime": "1734513813", "elapsedseconds": "6.0000", "status": "task_cancel", "cps": "0.000585000000", "totalcost": "0.003510000000", "guestid": null, "projectid": "699", "modelid": "598", "description": "", "basemodelid": "0", "runtype": "model", "modelfolderid": "", "modelfileid": "", "callbackurl": "", "marketplaceid": null, "createtime": "1734513807", "canceltime": "0", "assigntime": "1734513807", "accepttime": "1734513807", "preprocessstarttime": "1734513807", "preprocessendtime": "1734513807", "postprocessstarttime": "1734513813", "postprocessendtime": "1734513814", "pexit": "0", "categories": "["tool","image-to-image","quick-showcase","compare-landscape"]", "outputs": [ { "id": "6bc392c93856dfce3a7d1b4261e15af3", "name": "0.png", "contenttype": "image/png", "parentid": "6c1833f39da71e6175bf292b18779baf", "uuid": "15bce51f-442f-4f44-a71d-13c6374a62bd", "size": "202472", "addedtime": "1734513812", "modifiedtime": "1734513812", "accesskey": "dFKlMApaSgMeHKsJyaDeKrefcHahUK", "foldercount": "0", "filecount": "0", "ispublic": 0, "expiretime": null, "url": "https://cdn1.wiro.ai/6a6af820-c5050aee-40bd7b83-a2e186c6-7f61f7da-3894e49c-fc0eeb66-9b500fe2/0.png" } ], "size": "202472" } ], "result": true } ``` ## Cancel Task - Make HTTP Post Request (For tasks on queue) ```bash curl -X POST "https://api.wiro.ai/v1/Task/Cancel" -H "Content-Type: multipart/form-data" -H "x-api-key: ${YOUR_API_KEY}" -H "x-nonce: ${NONCE}" -H "x-signature: ${SIGNATURE}" -d '{ "taskid": "634574" }'; ``` ## Cancel Task - Response ```json { "errors": [], "tasklist": [ { "id": "634574", "uuid": "15bce51f-442f-4f44-a71d-13c6374a62bd", "name": "", "socketaccesstoken": "ZpYote30on42O4jjHXNiKmrWAZqbRE", "parameters": { "inputImage": "https://api.wiro.ai/v1/File/mCmUXgZLG1FNjjjwmbtPFr2LVJA112/inputImage-6060136.png" }, "debugoutput": "", "debugerror": "", "starttime": "1734513809", "endtime": "1734513813", "elapsedseconds": "6.0000", "status": "task_cancel", "cps": "0.000585000000", "totalcost": "0.003510000000", "guestid": null, "projectid": "699", "modelid": "598", "description": "", "basemodelid": "0", "runtype": "model", "modelfolderid": "", "modelfileid": "", "callbackurl": "", "marketplaceid": null, "createtime": "1734513807", "canceltime": "0", "assigntime": "1734513807", "accepttime": "1734513807", "preprocessstarttime": "1734513807", "preprocessendtime": "1734513807", "postprocessstarttime": "1734513813", "postprocessendtime": "1734513814", "pexit": "0", "categories": "["tool","image-to-image","quick-showcase","compare-landscape"]", "outputs": [ { "id": "6bc392c93856dfce3a7d1b4261e15af3", "name": "0.png", "contenttype": "image/png", "parentid": "6c1833f39da71e6175bf292b18779baf", "uuid": "15bce51f-442f-4f44-a71d-13c6374a62bd", "size": "202472", "addedtime": "1734513812", "modifiedtime": "1734513812", "accesskey": "dFKlMApaSgMeHKsJyaDeKrefcHahUK", "foldercount": "0", "filecount": "0", "ispublic": 0, "expiretime": null, "url": "https://cdn1.wiro.ai/6a6af820-c5050aee-40bd7b83-a2e186c6-7f61f7da-3894e49c-fc0eeb66-9b500fe2/0.png" } ], "size": "202472" } ], "result": true } ``` ## Task Status Information This section defines the possible task status values returned by the API when polling for task completion. ### Completed Task Statuses (Polling can stop) These indicate that the task has reached a terminal state — either success or failure. Once any of these is received, polling should stop. - task_postprocess_end : Task completed successfully and post-processing is done. - task_cancel : Task was cancelled by the user or system. ### Running Task Statuses (Continue polling) These statuses indicate that the task is still in progress. Polling should continue if one of these is returned. - task_queue : Task is waiting in the queue. - task_accept : Task has been accepted for processing. - task_assign : Task is being assigned to a worker. - task_preprocess_start : Preprocessing is starting. - task_preprocess_end : Preprocessing is complete. - task_start : Task execution has started. - task_output : Output is being generated.