Proyecto de Subtitld
El archivo propio de Subtitld: un paquete ZIP que empieza por un documento USF con los subtítulos, sus traducciones, hablantes y doblajes, un manifiesto de todo lo demás que contiene, una imagen del punto donde lo dejaste y, si lo pides, el vídeo y su sonido. Un solo archivo para mover, guardar como copia o entregar, y cada parte se lee con herramientas estándar.
De un vistazo
| Extensión | .usfx |
|---|---|
| Tipo de medio | application/x-usfx, un tipo de application/zip. En sistemas de Apple, org.subtitld.usfx. |
| Especificación | Esta página. El paquete es el ZIP de PKWARE (APPNOTE.TXT); el documento es USF 1.0 con los elementos de Subtitld. |
| Paquete | ZIP, con sus miembros comprimidos con Deflate (RFC 1951) y comprobados con CRC-32; Zip64 para archivos de más de 2 GiB |
| Primer miembro | subtitles.usf: su nombre está en el byte 30 de todo proyecto que guarda Subtitld |
| Precisión temporal | Subtítulos: milisegundos. Doblajes: los segundos exactos, con tantos decimales como hagan falta. |
| Codificación del texto | UTF-8, en el XML y en los nombres de los miembros |
| Estilo | El de USF: cursiva, negrita, subrayado, tachado, color y nueve puntos |
| Hablantes | Un nombre, un color, una imagen y una voz cada uno |
| Idiomas | El original y cada traducción, un bloque cada uno, por código ISO 639-2 y nombre |
| Medios incluidos | Los doblajes y las imágenes de los hablantes; si lo pides, el vídeo, su sonido, las voces y el fondo separados, y la forma de onda de la línea de tiempo |
Anatomía de un archivo
Un .usfx es un ZIP. Cualquier herramienta de archivos lo abre, renombrado a .zip si la herramienta se empeña.
Tears of Steel.usfx subtitles.usf manifest.xml thumbnail.png assets/speakers/Celia.png assets/dubs/77a03e27.wav assets/video/Tears_of_Steel.mkv assets/waveform.npy assets/audio/vocals.flac
- 1 · Documento
El proyecto en sí, en USF: cada subtítulo, traducción, hablante y doblaje. Siempre presente, siempre el primero.
- 2 · Manifiesto
Qué creó el archivo, dónde estaba el vídeo, cómo se mezcló el sonido, y un tipo de medio para cada uno de los demás miembros.
- 3 · Imagen
Lo que los gestores de archivos muestran del proyecto: el fotograma donde lo dejaste, su subtítulo y la línea de tiempo en ese punto.
- 4 · Recursos
El audio de cada doblaje y las caras de los hablantes; el vídeo, su sonido y la forma de onda solo cuando los pides.
El documento dice lo que pasa; los recursos son lo que reproduce. Un doblaje en subtitles.usf nombra su clip por su ruta en el paquete, assets/dubs/77a03e27.wav, así que el paquete puede pasar a otra carpeta, otro disco u otro ordenador y seguir completo.
Los miembros
| Ruta | Qué contiene | Compresión | Se escribe |
|---|---|---|---|
subtitles.usf |
El documento: subtítulos, traducciones, hablantes, voces, doblajes | Deflate | Siempre, el primero |
manifest.xml |
El manifiesto | Deflate | Siempre, el segundo |
thumbnail.png |
Una tarjeta PNG del proyecto, de 512 × 384 | Sin comprimir | Cuando hay una imagen que hacer |
assets/speakers/<speaker>.png |
La imagen de un hablante, de 256 píxeles por lado como máximo | Deflate | Salvo que lo desactives |
assets/dubs/<uid>.<ext> |
El audio de una toma de doblaje, con el ID de la toma como nombre | Deflate | Siempre, para cada toma con audio |
assets/dubs/<uid>__<n>__<file> |
Un trozo dividido o estirado de una toma, y la fuente intacta de la que se estiró | Deflate | Cuando una toma se dividió o se estiró |
assets/video/<file> |
El vídeo | Deflate | Si lo pides |
assets/waveform.npy |
Los picos de la forma de onda de la línea de tiempo, un array de NumPy | Deflate | Si lo pides |
assets/audio/original.flac |
El sonido del vídeo | Deflate | Si lo pides |
assets/audio/vocals.flac, background.flac |
El sonido separado en voces y el resto | Deflate | Si lo pides |
Los nombres en assets/ se componen de letras, dígitos, -, _ y .; todo lo demás pasa a ser _, así que Tears of Steel.mkv se guarda como Tears_of_Steel.mkv. Las letras fuera de ASCII se conservan, con el nombre escrito en UTF-8 y marcado como tal (bit 11 de la cabecera ZIP), como pide APPNOTE.
Por qué la imagen se guarda sin comprimir. Un PNG ya está comprimido; Deflate solo costaría tiempo. Sin comprimir, sus bytes están en el archivo exactamente como en un PNG, así que un generador de miniaturas los lee sin descomprimir nada.
Los primeros bytes
Todo proyecto empieza igual: una cabecera de archivo local ZIP y luego el nombre de su primer miembro.
50 4B 03 04 14 00 00 00 08 00 4E 70 51 5D 64 CE 1E 0B 6F 3B 00 00 7F E2 00 00 0D 00 00 00 73 75 62 74 69 74 6C 65 73 2E 75 73 66
- 1 · Firma
PK\3\4, bytes 0 a 3: aquí empieza un miembro ZIP. - 2 · Cabecera
Versión 2.0 necesaria para extraer; sin indicadores; método 8, Deflate; la hora y la fecha al estilo de MS-DOS (aquí, 17 de octubre de 2026, 14:02:28); el CRC-32; los tamaños comprimido y sin comprimir (15.215 y 57.983 bytes).
- 3 · Longitud del nombre
13, y ningún campo extra.
- 4 · Nombre
subtitles.usf, desde el byte 30.
El nombre nunca se comprime, aunque el miembro sí lo esté. Eso lo convierte en una firma: un ZIP cuyo nombre en el byte 30 es subtitles.usf es un proyecto de Subtitld. El Tracker de Haiku distingue los proyectos de otros archivos comprimidos exactamente con esa regla, 0.60 ("PK\003\004") [30] ("subtitles.usf" | "manifest.xml"), situada por encima de la regla del ZIP corriente. ODF y EPUB hacen lo mismo con un primer miembro llamado mimetype.
Un vídeo puede superar el límite original de ZIP, 4 GiB. A partir de 2 GiB, Subtitld escribe los campos extra y los registros finales de Zip64 (sección 4.5 de APPNOTE), igual que a partir de 65.535 miembros; Subtitld, su gestor de miniaturas para Windows y cualquier unzip actual los leen.
El manifiesto
<?xml version="1.0" encoding="UTF-8"?>
<manifest version="1.0">
<format>USFX</format>
<generator>Subtitld</generator>
<source path="/home/ana/Videos/Tears of Steel.mkv"
basename="Tears of Steel.mkv"/>
<voicemix volume="0.5000"/>
<entry path="subtitles.usf" type="application/x-usf+xml"/>
<entry path="thumbnail.png" type="image/png"/>
<entry path="assets/speakers/Celia.png" type="image/png"/>
<entry path="assets/dubs/77a03e27.wav" type="audio/wav"/>
</manifest>
| Elemento | Qué contiene |
|---|---|
<manifest version> |
La versión del manifiesto, 1.0 |
<format>, <generator> |
USFX, y qué escribió el archivo: Subtitld |
<source path basename> |
La ruta completa del vídeo cuando se guardó el proyecto, y solo su nombre de archivo |
<voicemix volume> |
Dónde estaba el control Música/Voz: 0 solo el fondo, 0.5 el sonido tal cual, 1 solo las voces, con los doblajes desvaneciéndose junto al fondo |
<entry path type> |
Uno por cada miembro salvo el propio manifiesto, cada uno con su tipo de medio |
Los tipos son application/x-usf+xml, image/png, audio/wav, audio/flac, audio/mpeg, video/mp4, video/x-matroska, video/quicktime, video/webm, video/ogg, y application/octet-stream para la forma de onda y todo lo demás.
La ruta del vídeo viaja con el archivo. <source path> es dónde estaba el vídeo en el ordenador que guardó el proyecto, con carpetas y nombre de usuario incluidos. Tenlo en cuenta antes de compartir un proyecto. Cuando la ruta no lleva a ninguna parte, Subtitld busca el vídeo por su nombre en la carpeta del proyecto.
El documento
subtitles.usf es un archivo Universal Subtitle Format, en UTF-8, tal como Subtitld lo escribe por sí solo, con lo que un proyecto necesita añadido al estilo de USF: elementos y atributos donde USF no los tiene. Un lector de USF que se salta lo que no conoce lee sus subtítulos.
<USFSubtitles version="1.0"
xmlns:subtitldcc="https://subtitld.cc/ns/usf/1">
<metadata>
<title>Tears of Steel</title>
<author><name>Subtitld</name></author>
<language code="eng">English</language>
<subtitldcc:origin share-id="Xk3pQ9aZ2bT" version="3"/>
</metadata>
<styles>
<style name="Celia">
<fontstyle color="#e5484d"/>
<dubbing engine="edge-tts" voice="en-GB-SoniaNeural"
rate="0" pitch="0" fit_to_subtitle="true"/>
</style>
</styles>
<subtitles>
<language code="eng">English</language>
<subtitle start="00:00:23.000" stop="00:00:24.500">
<text speaker="Celia" style="Celia">You're a jerk, Thom.</text>
<dubbing uid="77a03e27" engine="edge-tts"
voice="en-GB-SoniaNeural" rate="0" pitch="0"
path="assets/dubs/77a03e27.wav"
start="23.0" end="24.5"/>
</subtitle>
</subtitles>
<subtitles>
<language code="por">Portuguese (Brazil)</language>
<subtitle start="00:00:23.000" stop="00:00:24.500">
<text speaker="Celia" style="Celia">Você é um idiota, Thom.</text>
</subtitle>
</subtitles>
</USFSubtitles>
Lo que Subtitld añade a USF
| Dónde | Elemento o atributo | Qué contiene |
|---|---|---|
<metadata> |
<subtitldcc:origin share-id version> |
El subtítulo de subtitld.cc del que viene el proyecto, para que los cambios se publiquen como su siguiente versión. En su propio espacio de nombres, https://subtitld.cc/ns/usf/1, y solo se escribe cuando lo hay. |
<styles> |
<style name> |
Uno por cada hablante, con su nombre. Ningún estilo Default, que cambiaría el estilo de todos los subtítulos en un reproductor. |
<style> |
<fontstyle color> |
El color del hablante, #RRGGBB |
<style> |
<dubbing engine voice rate pitch fit_to_subtitle> |
La voz del hablante: el motor, la voz, la velocidad y el tono de −100 a 100, y si los doblajes se ajustan a la duración de su subtítulo |
<text> |
speaker, style |
Quién lo dice, y su estilo |
<text> |
alignment |
Uno de los nueve puntos de USF, de TopLeft a BottomRight; ninguno para abajo en el centro |
<subtitle> |
<dubbing> |
Una toma del doblaje del subtítulo, un elemento por toma |
<dubbing> |
uid engine voice rate pitch |
El ID de la toma, y la voz con que se hizo |
<dubbing> |
path, raw_path |
Su audio en el paquete, y la fuente de la que se hizo una toma estirada |
<dubbing> |
start, end |
Dónde suena en la línea de tiempo, en segundos |
<dubbing> |
<subclip type path raw_path start end offset rate> |
Los trozos de una toma que se dividió o se estiró |
En un .usf corriente, las imágenes de los hablantes y el audio de los doblajes pueden viajar dentro del XML, en base64 en <avatar> y <data>. Un .usfx nunca lo hace: son miembros propios, una cuarta parte más pequeños que en base64, y se leen sin analizar el XML.
Tiempos
El start y el stop de un subtítulo son tiempos de USF, redondeados al milisegundo más cercano. Los tiempos de un doblaje son segundos simples escritos completos, 18.01579117916244: el decimal más corto que se vuelve a leer como el mismo número de 64 bits, así que un clip colocado arrastrándolo vuelve exactamente a donde estaba.
Las versiones antiguas de Subtitld escribían los tiempos un milisegundo antes de la cuenta, y un inicio en cero como 23:59:59.999. Subtitld lee ese valor como cero, y deja el milisegundo como está.
Tomas y subclips
Un subtítulo puede tener varias tomas. El primer <dubbing> es el que suena; los demás son alternativas, en silencio hasta que eliges una, que entonces pasa al principio.
Una toma que se dividió o se estiró guarda una lista de <subclip>, colocados como clips en un editor de audio:
| Atributo | Significado |
|---|---|
start, end |
La parte del archivo fuente que suena, en segundos desde el inicio del archivo |
offset |
Dónde empieza esa parte, en segundos desde el start de la toma |
rate |
La velocidad a la que se estiró: 20 es el 120 % |
path, raw_path |
El audio que suena, y el audio intacto del que se estiró |
Un subclip suena a partir del start de la toma más su offset, durante end menos start segundos. Los huecos son silencio; los solapamientos se mezclan. Las fuentes nunca se modifican, así que cada división y cada estiramiento se pueden deshacer, y un estiramiento siempre se rehace desde raw_path, nunca desde el estiramiento de un estiramiento.
Traducciones
Cada idioma tiene su propio bloque <subtitles>, identificado por su código ISO 639-2 y, en el elemento, por el nombre del idioma, que distingue el portugués de Brasil del de Portugal. Cada bloque contiene todos los subtítulos con los mismos tiempos; solo el primero contiene doblajes. Subtitld empareja una traducción con su subtítulo por el tiempo de inicio, o con aquel con el que más se solapa, así que los bloques escritos por otras herramientas no tienen por qué coincidir.
Abrir un proyecto
Los proyectos grandes se abren al instante: Subtitld lee primero lo que necesita el editor, y el resto mientras trabajas.
subtitles.usf, leído para los subtítulos, los hablantes y las vocesmanifest.xml, para el vídeo y la mezclaassets/speakers/, las caras, decodificadas fuera del hilo principal- Un vídeo incluido, extraído una sola vez
- Los doblajes primero, para que puedas reproducirlos
- Luego, la forma de onda
- El sonido separado, al final
Cada doblaje de la línea de tiempo aparece rayado hasta que llega su audio, y entonces suena.
Los miembros se extraen en las carpetas propias de Subtitld, nunca junto al proyecto: el documento, las caras y los doblajes, en una carpeta de caché con el MD5 de la ruta del proyecto como nombre. Lo que llega mientras trabajas se escribe en bloques de 1 MiB en un archivo temporal, que se renombra a su sitio cuando está completo, así que un fallo a medias no deja nada escrito a medias. La próxima vez que se abre el mismo proyecto, un archivo que ya está ahí solo se reutiliza si tiene exactamente el tamaño del miembro; si no, se extrae de nuevo.
El vídeo se busca en este orden:
- un vídeo dentro del paquete, en
assets/video/; - la ruta de
<source path>, si sigue ahí; - un archivo con el nombre de
<source basename>, en la carpeta del proyecto; - si no, Subtitld lo pide.
Un archivo que no es un ZIP, está cortado o no pasa una comprobación CRC no abre nada: Subtitld lo avisa y lo quita de la lista de recientes. Los proyectos anteriores también se abren: uno sin manifiesto, o con su USF con otro nombre en la raíz del ZIP.
Guardar un proyecto
Guardar nunca pone en riesgo el proyecto que ya tienes.
- Una instantánea. El proyecto se copia tal como está al guardar, para que puedas seguir editando mientras se escribe. Los guardados, los guardados automáticos y las copias de seguridad se turnan: solo uno escribe a la vez.
- Un archivo nuevo. El paquete se escribe en
<project>.usfx.tmp, junto al proyecto. - No falta nada. Un doblaje cuyo audio aún no está en la caché, porque sigue llegando o se borró, se copia del archivo que está a punto de sustituirse. Un proyecto guardado sin vídeo conserva la imagen que tenía.
- Comprobado. El archivo nuevo se vuelve a abrir y se verifica el CRC-32 de cada miembro.
- Sustituido. Solo entonces reemplaza al proyecto, con un único renombrado (
os.replace): el nombre del proyecto nunca contiene medio proyecto.
Si falla algún paso, el archivo temporal se borra, el proyecto en el disco es el que tenías, y tus cambios siguen abiertos en Subtitld. Mientras los doblajes de un proyecto siguen llegando, Guardar los espera.
Qué va dentro
Configuración global, luego USFX, elige qué más lleva un proyecto, para todos los proyectos que guardes:
- Imágenes de los hablantesLas caras de los hablantes. Activado.
- Caché de la forma de onda de la línea de tiempoLa forma de onda, para que un proyecto se abra en otro ordenador sin volver a calcularla. Desactivado.
- Pista de audio originalEl sonido del vídeo, en FLAC. Desactivado.
- Audio procesado (voces + fondo)El sonido separado en voces y el resto, en FLAC, para que la separación no tenga que ejecutarse de nuevo. Desactivado.
- Archivo de vídeo originalEl propio vídeo: un solo archivo con todo, tan grande como el vídeo y más. Desactivado.
Cada uno entra cuando Subtitld tiene algo que meter: el sonido separado, por ejemplo, solo cuando ya se ha hecho la separación. Los subtítulos, las traducciones, los hablantes, las voces y todos los doblajes van siempre dentro. Deflate le quita alrededor de una sexta parte al WAV de un doblaje; un vídeo y un FLAC apenas se reducen.
Guardado automático y copias de seguridad
- Guardar automáticamente el archivo del proyectoEscribe tu propio
.usfx, como hace Guardar, de la misma forma segura. Para un proyecto guardado como USFX. - Copias de seguridad automáticasUn
.usfxcompleto en la carpeta de copias de seguridad de Subtitld, aparte de tu propio archivo, con el nombre<project>_<YYYYMMDDHHMMSS>.usfx, cuando hay cambios que conservar. Por encima de Conservar como máximo, 20 salvo que elijas otra cifra, se borran las más antiguas.
En los gestores de archivos
La miniatura es una tarjeta con el aspecto de Subtitld: el fotograma del vídeo donde se dejó el proyecto, el subtítulo encima y, debajo, los doce segundos de línea de tiempo alrededor del cabezal, con la forma de onda y los subtítulos en los colores de sus hablantes. En 4:3 a 512 × 384, llena mejor la celda cuadrada de un gestor de archivos que un fotograma panorámico. Sin vídeo, el símbolo de Subtitld ocupa el lugar del fotograma.
| Sistema | El tipo | Qué aporta |
|---|---|---|
| Linux | application/x-usfx en shared-mime-info, un tipo de application/zip, reconocido por *.usfx |
Un icono propio; con el paquete de AUR, miniaturas de subtitld-thumbnailer, un generador de miniaturas de freedesktop.org |
| Windows | Un tipo de archivo en el instalador y en el paquete MSIX | Un icono; un proveedor de miniaturas del shell (UsfxThumbnail.dll, IThumbnailProvider) que lee por sí mismo el directorio central del ZIP, Zip64 incluido, y decodifica el PNG con WIC al tamaño que pide el Explorador |
| macOS | El tipo org.subtitld.usfx, conforme a public.zip-archive |
Un icono propio |
| Haiku | application/x-usfx, con la regla de detección de arriba |
Un icono, y un Tracker que distingue un proyecto de un ZIP |
Con un doble clic, un proyecto se abre en Subtitld en los cuatro. Ambos generadores de miniaturas leen solo thumbnail.png, rechazan una de más de 8 MiB y no aceptan nada que no empiece por la firma de PNG, 89 50 4E 47 0D 0A 1A 0A. El de Windows solo la acepta sin comprimir, como la escribe Subtitld. El de Linux usa solo la biblioteca estándar de Python, ya que los gestores de archivos ejecutan los generadores de miniaturas aislados y muchos a la vez.
Leer un .usfx por tu cuenta
Nada en un proyecto es solo de Subtitld. Para mirar dentro:
unzip -l "Tears of Steel.usfx"
unzip -p "Tears of Steel.usfx" manifest.xml
Para leer sus subtítulos, en todos los idiomas, con la biblioteca estándar de Python:
import zipfile
import xml.etree.ElementTree as ET
def text_of(element):
"""A <text>'s words, <br/> as a line break."""
parts = [element.text or '']
for child in element:
parts.append('\n' if child.tag == 'br' else text_of(child))
parts.append(child.tail or '')
return ''.join(parts)
with zipfile.ZipFile('Tears of Steel.usfx') as usfx:
usf = ET.fromstring(usfx.read('subtitles.usf'))
for block in usf.iter('subtitles'):
language = block.find('language')
if language is not None:
print('#', language.get('code'), language.text)
for subtitle in block.iter('subtitle'):
text = subtitle.find('text')
print(subtitle.get('start'), subtitle.get('stop'),
text.get('speaker'), text_of(text))
Para un proyecto de otra persona, analiza con defusedxml en lugar de xml.etree, como con cualquier XML que no hayas escrito tú.
Crear uno
El proyecto más pequeño que abre Subtitld es un ZIP con un subtitles.usf. Sin manifiesto, Subtitld pide el vídeo. Para crear uno que también reconozcan los gestores de archivos, sigue lo que escribe Subtitld:
subtitles.usfprimero, luegomanifest.xml;- todos los miembros comprimidos con Deflate, salvo
thumbnail.png, sin comprimir; - los doblajes en
assets/dubs/, nombrados en el documento por su ruta en el paquete; - UTF-8 en todas partes.
Subtitld conserva lo que conoce. Al guardar se escriben los miembros de esta página, y un documento hecho con lo que Subtitld entendió del anterior. Un archivo que otra herramienta añada al paquete, o un elemento propio en el USF, desaparece en cuanto Subtitld guarda el proyecto. Guarda tus propios datos aparte.
Cómo se compara
USFX está construido como los paquetes de documentos de las suites ofimáticas y los libros electrónicos: un ZIP, un documento principal en XML, un inventario y los medios al lado.
ODF (.odt) |
EPUB | Office Open XML (.docx) |
USFX | |
|---|---|---|---|---|
| Norma | OASIS ODF 1.3, parte 2 | W3C EPUB 3.3, su OCF | ECMA-376 parte 2, OPC | Esta página |
| Cómo lo reconoce una herramienta | Un primer miembro mimetype, sin comprimir |
Un primer miembro mimetype, sin comprimir: application/epub+zip |
[Content_Types].xml |
El nombre de su primer miembro, subtitles.usf, en el byte 30 |
| Inventario | META-INF/manifest.xml, un tipo para cada archivo |
META-INF/container.xml, y luego el documento del paquete |
[Content_Types].xml y _rels/ |
manifest.xml, un tipo para cada miembro |
| Documento principal | content.xml |
El documento del paquete y su spine | word/document.xml |
subtitles.usf |
| Medios | Pictures/ |
En cualquier lugar del paquete | word/media/ |
assets/ |
| Vista previa | Thumbnails/thumbnail.png |
Una imagen de portada | Una parte de miniatura opcional | thumbnail.png, sin comprimir |
El documento principal es un formato abierto por derecho propio: saca el subtitles.usf de un .usfx y es un archivo USF, un formato con especificación pública desde 2002.
Curiosidades
El byte donde empieza el nombre del primer miembro de todo proyecto, y la forma en que Haiku distingue un proyecto de Subtitld de cualquier otro ZIP.
El tamaño de la imagen de un proyecto: 4:3, porque los gestores de archivos muestran los archivos en cuadrados.
La versión que dio a .usfx un icono propio en Linux, Windows, macOS y Haiku, y su imagen en el Explorador de Windows y en los gestores de archivos de Linux.
Formatos relacionados
-
.usfFormato universal de subtítulos
-
.jsonSubtítulos y transcripciones en JSON
-
.ttmlTimed Text Markup Language
Abre un vídeo en Subtitld, haz sus subtítulos y guarda: es un .usfx.