Transcripts that know who’s talking
Interviews, podcasts, panels and meetings all have more than one voice. A transcript that runs everything together as one block of text makes you guess who said what, and captions that flash by without a cue are even harder to follow.
🤖 /speech/transcribe now labels who is speaking, and every output shows it: a text transcript that reads like a script, subtitles with standard voice tags, and social captions that give every speaker their own color.
A clip from NASA’s Houston We Have a Podcast, episode 441, made by one Assembly from the audio alone: the host in yellow, the Artemis II astronaut in cyan. Served from Transloadit Storage.
One command
npx -y @transloadit/node speech transcribe --speaker-labels -i interview.mp3 -o interview.txt
For the clip above, interview.txt reads:
Speaker 1: If you could just maybe we'll take a step into those 10 days in orbit and what it was like in Orion, um, and just zooming back, looking at the overall perspective of the flight, now a couple months separated from it, you know, how are you characterizing the entirety of the experience, um, over those 10 days?
Speaker 2: Well, there's a lot that you could, you could dig into there. The, you know, I think one thing that comes to mind is we are busy, uh, really busy and really working together to try to stay on the schedule.
Add --max-speakers 2 when you know how many people are talking, and --format to pick another
output.
Every format shows the speaker
textgives one paragraph per turn, as above.webvttwraps each cue in a standard voice span, such as<v Speaker 1>, so players and caption editors can name or style each speaker.srthas no voice tag, so it starts a cue withSpeaker 2:whenever the turn changes.jsonlabels every word and adds one segment per turn. Use it to build your own view.
A subtitle cue never spans two speakers. Speaker labels come from the aws and gcp providers; leave provider out and Transloadit picks one
that supports them.
A color per speaker
Captions burned in with 🤖 /video/subtitle can now give each
speaker their own color. Pass the speaker-labeled JSON from /speech/transcribe and a list of
speaker_colors: the active word lights up in its speaker’s color, and a caption never runs on into
the next speaker’s words.
The video at the top is one Assembly, made from nothing but the audio file. It imports a NASA photo, draws the waveform, lays both into a cover, turns the cover and the audio into a video, and burns in the captions:
{
"steps": {
"photo": {
"robot": "/http/import",
"url": "https://images-assets.nasa.gov/image/art002e009567/art002e009567~orig.jpg"
},
"waveform": {
"use": ":original",
"robot": "/audio/waveform",
"format": "image",
"width": 1600,
"height": 90,
"background_color": "00000000",
"outer_color": "ffffff73",
"center_color": "ffffff73",
"waveform_style": "bars",
"bar_width": 5,
"bar_gap": 5,
"bar_style": "rounded",
"style": "v1"
},
"cover": {
"use": {
"steps": [
{ "name": "photo", "as": "base" },
{ "name": "waveform", "as": "watermark" }
]
},
"robot": "/image/resize",
"width": 1920,
"height": 1080,
"resize_strategy": "crop",
"watermark_y_offset": 40,
"format": "jpg",
"text": [
{
"text": "HOUSTON WE HAVE A PODCAST · ARTEMIS II",
"font": "Poppins-SemiBold",
"size": 30,
"color": "#ffffff",
"align": "right",
"valign": "top",
"x_offset": 60,
"y_offset": 52
}
],
"watermark_position": "bottom"
},
"video": {
"use": {
"steps": [
{ "name": "cover", "as": "image" },
{ "name": ":original", "as": "audio" }
]
},
"robot": "/video/merge",
"preset": "empty",
"ffmpeg": { "f": "mp4" },
"ffmpeg_stack": "v7"
},
"transcribed": {
"use": ":original",
"robot": "/speech/transcribe",
"speaker_labels": true,
"format": "json"
},
"captioned": {
"use": {
"steps": [
{ "name": "video", "as": "video" },
{ "name": "transcribed", "as": "subtitles" }
]
},
"robot": "/video/subtitle",
"subtitles_type": "burned",
"preset": "empty",
"style": "social",
"ffmpeg_stack": "v7",
"result": true,
"speaker_colors": ["FFD60A", "4CC9F0"]
}
}
}
Save it as speaker-captions.json and run it on any audio file:
npx -y @transloadit/node assemblies create --steps speaker-captions.json -i podcast.mp3 -o out/
For a video with people on screen, skip the first four Steps and use :original as the video, as
in the social captions post.
Get started
Run the command above on a recording of your own, or paste the Steps into a new Template. The 🤖 /speech/transcribe and 🤖 /video/subtitle pages list every parameter.
Audio and photo courtesy of NASA: Houston We Have a Podcast, episode 441, “Reflections After Artemis II”, and the Artemis II photo “Orion POV: Destination and Home”. NASA does not endorse Transloadit.
