Cómo obtener la marca de tiempo de cada palabra en una grabación
Llama a POST /transcribe con output_format en json y word_timestamps en true (ambos vienen así por defecto). Cada tramo de la respuesta incluye un array words con objetos {start, end, word} y los tiempos en segundos. Aquí veremos qué estructura tiene, qué modelos devuelven tiempos por palabra y qué puedes construir con ellos.
La solicitud
{
"audio_url": "https://example.com/interview.mp3",
"model": "oracle",
"language": "auto",
"word_timestamps": true,
"output_format": "json"
}
Lanza el trabajo con POST /transcribe y consulta GET /transcribe/{jobId} hasta que el estado sea COMPLETED. Indica siempre el parámetro model, porque si lo omites la API usará por defecto el modelo heredado core.
La respuesta
{
"jobId": "34c63d45-4cb5-473b-bc60-25c175e69c57",
"status": "COMPLETED",
"result": {
"language": "en",
"segments": [
{
"start": 1.0,
"end": 3.75,
"text": "Hello everyone and welcome to the show.",
"speaker": "Speaker 1",
"words": [
{ "start": 1.0, "end": 1.35, "word": "Hello" },
{ "start": 1.4, "end": 1.75, "word": "everyone" }
]
}
]
}
}
segments[]: incluyestartyenden segundos,text,speaker(si activaste la diarización) y la listawords[].words[]: contienestart,endyword, expresados en segundos con hasta tres decimales.- Ten en cuenta que una palabra corta puede durar apenas unas centésimas de segundo, o incluso tener el mismo valor en
startyend. Evita dividir por la duración de una palabra en tu código. - Si pasas
word_timestampscomofalse, o si el modelo elegido solo calcula tiempos por tramo, el arraywordsno aparecerá y solo tendrás elstarty elendde cada tramo.
Modelos que devuelven tiempos por palabra
| Modelo | Tiempos por palabra |
|---|---|
base, oracle, oracle_pro, oracle_max | Sí |
oracle_mini | Solo tiempos por tramo en transcripción normal; tiempos por palabra al activar algún modo de hablantes (diarización o separación de canales) |
core, edge (heredados) | Sí |
El formato de texto plano (txt) no incluye tiempos. Los subtítulos SRT que genera la API dependen de este mismo parámetro; tienes más detalles en la guía de SRT.
Localizar en qué momento se dice una frase
Busca dentro de la lista aplanada de palabras y te da el intervalo de tiempo correspondiente. Así un agente puede responder a «¿dónde menciona los precios?» indicando el instante exacto, o recortar esa frase en un clip.
find.py
# find.py — where is a phrase said? Returns (start, end) in seconds.
import re
def find_phrase(result, phrase):
words = [w for segment in result["segments"] for w in segment.get("words", [])]
clean = lambda text: re.sub(r"[^\w]", "", text.lower())
target = [clean(p) for p in phrase.split()]
tokens = [clean(w["word"]) for w in words]
for i in range(len(tokens) - len(target) + 1):
if tokens[i:i + len(target)] == target:
return words[i]["start"], words[i + len(target) - 1]["end"]
return None
# start, end = find_phrase(result, "welcome to the show")
# ffmpeg -ss <start> -to <end> -i talk.mp4 -c:v libx264 -c:a aac clip.mp4
Cómo extraer un clip a partir de un intervalo de tiempo:
ffmpeg -ss 41.2 -to 47.8 -i talk.mp4 -c:v libx264 -c:a aac clip.mp4
Acortar silencios y hacer cortes directos
Al tener el inicio y el final de cada palabra, sabes cuánto duran las pausas entre ellas. Puedes conservar los tramos hablados y recortar cualquier silencio que supere cierto límite:
silences.py
# silences.py — keep the speech, drop pauses longer than max_gap seconds
def speech_ranges(words, max_gap=0.7, pad=0.1):
ranges = []
for word in words:
if ranges and word["start"] - ranges[-1][1] <= max_gap:
ranges[-1][1] = word["end"]
else:
ranges.append([word["start"], word["end"]])
return [[max(0.0, s - pad), e + pad] for s, e in ranges]
# Pass the ranges to cut() from cut.py to build the tightened video.
Después, une los intervalos resultantes con la función cut() de la guía de edición de vídeo.
Otros usos para las marcas de tiempo
- Resaltado de lectura en un reproductor web: se marca la palabra cuyo intervalo incluye el valor de
currentTime. - Transcripciones interactivas: haz que al pulsar sobre cualquier palabra el reproductor salte a
?t=<start>. - Capítulos y momentos clave: pídele a un LLM que elija los números de tramo más relevantes y traduce esos índices a tiempos desde tu código.
- Buscador en archivos de audio: indexa las palabras junto con su segundo de inicio para que, al buscar un término, la grabación se abra en el punto exacto.
- Alineación y corpus lingüísticos: convierte los tiempos del JSON al formato de anotación que utilicen tus herramientas de análisis.
Cuánto cuesta
Incluir marcas de tiempo por palabra no tiene coste adicional. Se factura por segundo de audio según el modelo elegido: desde 0,48 US$ la hora con base, o 1,44 US$ la hora con oracle. Puedes ver todas las tarifas en /llms/pricing.md.
Preguntas y respuestas
¿Cómo obtengo marcas de tiempo por palabra con la API de transcripción?
Envía la petición con output_format: "json" y word_timestamps: true. Cada tramo de la respuesta incluirá una lista words[] con start, end (en segundos) y word.
¿Qué modelos admiten marcas de tiempo por palabra?
Los modelos base, oracle, oracle_pro y oracle_max las devuelven siempre. oracle_mini solo devuelve tiempos por tramo, a menos que actives un modo de hablantes. Si pides la salida en texto plano, no habrá marcas de tiempo.
¿Qué precisión tienen los tiempos por palabra?
KolWrite no publica cifras de precisión desglosadas por idioma para esta API. Los tiempos funcionan bien para sincronizar texto en pantalla y editar cortes entre palabras; te recomendamos probar con algunas de tus propias grabaciones y dejar un pequeño margen al cortar audio.
¿Puedo obtener marcas de tiempo a partir de un archivo de vídeo?
Sí, la API lee directamente la pista de audio del vídeo que subas. Si el archivo pesa más de 100 MiB, extrae primero el audio con ffmpeg antes de enviarlo.
¿Las marcas de tiempo vienen en segundos o en milisegundos?
En segundos, expresados como números con hasta tres decimales (por ejemplo, 41.236).