Projet Subtitld

OuvrirEnregistrerZIPXMLProjet

Le fichier propre à Subtitld : un paquet ZIP qui commence par un document USF des sous-titres, de leurs traductions, de leurs locuteurs et de leurs doublages, avec un manifeste de tout le reste, une image de l'endroit où vous vous êtes arrêté et, si vous le demandez, la vidéo et son son. Un seul fichier à déplacer, sauvegarder ou transmettre, et chacune de ses parties se lit avec des outils standard.

En bref

Extension.usfx
Type de médiaapplication/x-usfx, une sorte d'application/zip. Sur les systèmes Apple, org.subtitld.usfx.
SpécificationCette page. Le paquet est le ZIP de PKWARE (APPNOTE.TXT) ; le document est USF 1.0 avec les éléments de Subtitld.
PaquetZIP, ses membres compressés en Deflate (RFC 1951) et vérifiés par CRC-32 ; Zip64 pour les fichiers au-delà de 2 Gio
Premier membresubtitles.usf : son nom est à l'octet 30 de chaque projet enregistré par Subtitld
Précision temporelleSous-titres : millisecondes. Doublages : les secondes exactes, avec autant de décimales qu'il le faut.
Encodage du texteUTF-8, dans le XML et dans les noms des membres
StyleCelui d'USF : italique, gras, souligné, barré, couleur et neuf emplacements
LocuteursUn nom, une couleur, une image et une voix chacun
LanguesL'original et chaque traduction, un bloc chacun, par code ISO 639-2 et nom
Médias inclusLes doublages et les images des locuteurs ; sur demande, la vidéo, son son, les voix et le fond séparés, et la forme d'onde de la timeline

Anatomie d'un fichier

Un .usfx est un ZIP. N'importe quel outil d'archives l'ouvre, renommé en .zip si l'outil y tient.

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. 1 · Document

    Le projet lui-même, en USF : chaque sous-titre, traduction, locuteur et doublage. Toujours présent, toujours en premier.

  2. 2 · Manifeste

    Ce qui a créé le fichier, où était la vidéo, comment le son était mixé, et un type de média pour chaque autre membre.

  3. 3 · Image

    Ce que les gestionnaires de fichiers montrent du projet : l'image où vous vous êtes arrêté, son sous-titre et la timeline à cet endroit.

  4. 4 · Ressources

    L'audio de chaque doublage et les visages des locuteurs ; la vidéo, son son et la forme d'onde seulement si vous le demandez.

Le document dit ce qui se passe ; les ressources sont ce qu'il joue. Un doublage dans subtitles.usf désigne son clip par son chemin dans le paquet, assets/dubs/77a03e27.wav, si bien que le paquet peut passer dans un autre dossier, sur un autre disque ou un autre ordinateur et rester entier.

Les membres

Chemin Contenu Compression Écrit
subtitles.usf Le document : sous-titres, traductions, locuteurs, voix, doublages Deflate Toujours, en premier
manifest.xml Le manifeste Deflate Toujours, en deuxième
thumbnail.png Une carte PNG du projet, 512 × 384 Stocké Quand il y a une image à faire
assets/speakers/<speaker>.png L'image d'un locuteur, 256 pixels de côté au plus Deflate Sauf si vous le désactivez
assets/dubs/<uid>.<ext> L'audio d'une prise de doublage, nommé d'après l'identifiant de la prise Deflate Toujours, pour chaque prise avec de l'audio
assets/dubs/<uid>__<n>__<file> Un morceau coupé ou étiré d'une prise, et la source intacte dont il a été étiré Deflate Quand une prise a été coupée ou étirée
assets/video/<file> La vidéo Deflate Sur demande
assets/waveform.npy Les crêtes de la forme d'onde de la timeline, un tableau NumPy Deflate Sur demande
assets/audio/original.flac Le son de la vidéo Deflate Sur demande
assets/audio/vocals.flac, background.flac Le son séparé en voix et en reste Deflate Sur demande

Les noms dans assets/ sont faits de lettres, de chiffres, de -, _ et . ; tout le reste devient _, si bien que Tears of Steel.mkv est stocké sous Tears_of_Steel.mkv. Les lettres hors ASCII sont conservées, le nom écrit en UTF-8 et marqué comme tel (bit 11 de l'en-tête ZIP), comme le demande APPNOTE.

Pourquoi l'image est stockée et non compressée. Un PNG est déjà compressé ; Deflate ne ferait que coûter du temps. Stockés, ses octets sont dans le fichier exactement comme dans un PNG, et un générateur de vignettes les lit sans rien décompresser.

Les premiers octets

Chaque projet commence de la même façon : un en-tête de fichier local ZIP, puis le nom de son premier membre.

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. 1 · Signature

    PK\3\4, octets 0 à 3 : un membre ZIP commence ici.

  2. 2 · En-tête

    Version 2.0 nécessaire pour extraire ; aucun drapeau ; méthode 8, Deflate ; l'heure et la date, à la manière de MS-DOS (ici le 17 octobre 2026, 14:02:28) ; le CRC-32 ; les tailles compressée et décompressée (15 215 et 57 983 octets).

  3. 3 · Longueur du nom

    13, et aucun champ supplémentaire.

  4. 4 · Nom

    subtitles.usf, à partir de l'octet 30.

Le nom n'est jamais compressé, même quand le membre l'est. Cela en fait une signature : un ZIP dont le nom à l'octet 30 est subtitles.usf est un projet Subtitld. Le Tracker de Haiku distingue les projets des autres archives exactement par cette règle, 0.60 ("PK\003\004") [30] ("subtitles.usf" | "manifest.xml"), classée au-dessus de la règle du ZIP ordinaire. ODF et EPUB font de même avec un premier membre nommé mimetype.

Une vidéo peut dépasser la limite d'origine de ZIP, 4 Gio. À partir de 2 Gio, Subtitld écrit les champs supplémentaires et les enregistrements de fin de Zip64 (section 4.5 d'APPNOTE), comme il le fait au-delà de 65 535 membres ; Subtitld, son gestionnaire de vignettes Windows et tout unzip actuel les lisent.

Le manifeste

<?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>
Élément Contenu
<manifest version> La version du manifeste, 1.0
<format>, <generator> USFX, et ce qui a écrit le fichier : Subtitld
<source path basename> Le chemin complet de la vidéo au moment de l'enregistrement du projet, et son seul nom de fichier
<voicemix volume> La position du curseur Musique/Voix : 0 le fond seul, 0.5 le son tel quel, 1 les voix seules, les doublages s'effaçant avec le fond
<entry path type> Un pour chaque membre sauf le manifeste lui-même, chacun avec son type de média

Les types sont application/x-usf+xml, image/png, audio/wav, audio/flac, audio/mpeg, video/mp4, video/x-matroska, video/quicktime, video/webm, video/ogg, et application/octet-stream pour la forme d'onde et tout le reste.

Le chemin de la vidéo voyage avec le fichier. <source path> est l'endroit où se trouvait la vidéo sur l'ordinateur qui a enregistré le projet, dossiers et nom d'utilisateur compris. Gardez-le à l'esprit avant de partager un projet. Quand le chemin ne mène nulle part, Subtitld cherche la vidéo par son nom dans le dossier du projet.

Le document

subtitles.usf est un fichier Universal Subtitle Format, en UTF-8, tel que Subtitld l'écrit seul, avec ce dont un projet a besoin ajouté dans le style d'USF : des éléments et des attributs là où USF n'en a pas. Un lecteur USF qui ignore ce qu'il ne connaît pas lit ses sous-titres.

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

Ce que Subtitld ajoute à USF

Où Élément ou attribut Contenu
<metadata> <subtitldcc:origin share-id version> Le sous-titre de subtitld.cc dont vient le projet, pour que les modifications puissent être publiées comme sa version suivante. Dans son propre espace de noms, https://subtitld.cc/ns/usf/1, écrit seulement quand il y en a un.
<styles> <style name> Un pour chaque locuteur, à son nom. Pas de style Default, qui changerait le style de chaque sous-titre dans un lecteur.
<style> <fontstyle color> La couleur du locuteur, #RRGGBB
<style> <dubbing engine voice rate pitch fit_to_subtitle> La voix du locuteur : le moteur, la voix, le débit et la hauteur de −100 à 100, et si les doublages sont ajustés à la durée de leur sous-titre
<text> speaker, style Qui le dit, et son style
<text> alignment L'un des neuf emplacements d'USF, de TopLeft à BottomRight ; aucun pour le bas au centre
<subtitle> <dubbing> Une prise du doublage du sous-titre, un élément chacune
<dubbing> uid engine voice rate pitch L'identifiant de la prise, et la voix avec laquelle elle a été faite
<dubbing> path, raw_path Son audio dans le paquet, et la source dont une prise étirée a été faite
<dubbing> start, end Où elle joue sur la timeline, en secondes
<dubbing> <subclip type path raw_path start end offset rate> Les morceaux d'une prise coupée ou étirée

Dans un .usf ordinaire, les images des locuteurs et l'audio des doublages peuvent voyager dans le XML, en base64 dans <avatar> et <data>. Un .usfx ne le fait jamais : ce sont des membres à part entière, un quart plus petits qu'en base64, et lus sans analyser le XML.

Temps

Le start et le stop d'un sous-titre sont des temps USF, arrondis à la milliseconde la plus proche. Les temps d'un doublage sont de simples secondes écrites en entier, 18.01579117916244 : le décimal le plus court qui se relit comme le même nombre 64 bits, si bien qu'un clip placé en le faisant glisser revient exactement où il était.

Les anciennes versions de Subtitld écrivaient les temps une milliseconde trop tôt, et un début à zéro sous la forme 23:59:59.999. Subtitld lit cette valeur comme zéro, et laisse la milliseconde telle quelle.

Prises et sous-clips

Un sous-titre peut avoir plusieurs prises. Le premier <dubbing> est celui qui joue ; les autres sont des alternatives, muettes jusqu'à ce que vous en choisissiez une, qui passe alors en tête.

Une prise coupée ou étirée garde une liste de <subclip>, placés comme des clips dans un éditeur audio :

Attribut Signification
start, end La partie du fichier source qui joue, en secondes depuis le début du fichier
offset Où cette partie commence, en secondes depuis le start de la prise
rate La vitesse à laquelle elle a été étirée : 20 correspond à 120 %
path, raw_path L'audio qui joue, et l'audio intact dont il a été étiré

Un sous-clip joue à partir du start de la prise plus son offset, pendant end moins start secondes. Les vides sont du silence ; les chevauchements sont mixés. Les sources ne sont jamais modifiées, si bien que chaque coupe et chaque étirement peuvent être annulés, et un étirement est toujours refait à partir de raw_path, jamais à partir de l'étirement d'un étirement.

Traductions

Chaque langue a son propre bloc <subtitles>, désigné par son code ISO 639-2 et, dans l'élément, par le nom de la langue, qui distingue le portugais du Brésil de celui du Portugal. Chaque bloc contient chaque sous-titre aux mêmes temps ; seul le premier contient des doublages. Subtitld associe une traduction à son sous-titre par l'heure de début, ou à celui qu'elle chevauche le plus, si bien que les blocs écrits par d'autres outils n'ont pas besoin de s'aligner.

Ouvrir un projet

Les gros projets s'ouvrent tout de suite : Subtitld lit d'abord ce dont l'éditeur a besoin, et le reste pendant que vous travaillez.

Avant que l'éditeur s'affiche
  • subtitles.usf, lu pour les sous-titres, les locuteurs et les voix
  • manifest.xml, pour la vidéo et le mixage
  • assets/speakers/, les visages, décodés hors du fil principal
  • Une vidéo incluse, extraite une seule fois
Pendant que vous travaillez
  • Les doublages d'abord, pour que vous puissiez les écouter
  • La forme d'onde, ensuite
  • Le son séparé, en dernier

Chaque doublage sur la timeline est hachuré jusqu'à l'arrivée de son audio, puis il joue.

Les membres sont extraits dans les dossiers propres à Subtitld, jamais à côté du projet : le document, les visages et les doublages dans un dossier de cache nommé d'après le MD5 du chemin du projet. Ce qui arrive pendant que vous travaillez est écrit par blocs de 1 Mio dans un fichier temporaire, renommé à sa place une fois complet, si bien qu'un plantage en cours de route ne laisse rien d'à moitié écrit. La fois suivante où le même projet s'ouvre, un fichier déjà présent n'est réutilisé que s'il a exactement la taille du membre ; sinon il est extrait de nouveau.

La vidéo est cherchée dans cet ordre :

  1. une vidéo dans le paquet, dans assets/video/ ;
  2. le chemin dans <source path>, s'il existe encore ;
  3. un fichier nommé comme dans <source basename>, dans le dossier du projet ;
  4. sinon, Subtitld la demande.

Un fichier qui n'est pas un ZIP, qui est tronqué ou qui échoue à un contrôle CRC n'ouvre rien : Subtitld le signale et le retire de la liste des fichiers récents. Les projets plus anciens s'ouvrent aussi : un projet sans manifeste, ou dont l'USF porte un autre nom à la racine du ZIP.

Enregistrer un projet

Enregistrer ne met jamais en danger le projet que vous avez.

  1. Un instantané. Le projet est copié tel qu'il est quand vous enregistrez, pour que vous puissiez continuer à modifier pendant qu'il est écrit. Enregistrements, enregistrements automatiques et sauvegardes se relaient : un seul écrit à la fois.
  2. Un nouveau fichier. Le paquet est écrit dans <project>.usfx.tmp à côté du projet.
  3. Rien ne manque. Un doublage dont l'audio n'est pas encore dans le cache, encore en cours d'arrivée ou effacé, est copié depuis le fichier sur le point d'être remplacé. Un projet enregistré sans vidéo garde l'image qu'il avait.
  4. Vérifié. Le nouveau fichier est rouvert et le CRC-32 de chaque membre vérifié.
  5. Échangé. Alors seulement il remplace le projet, en un seul renommage (os.replace) : le nom du projet ne contient jamais un demi-projet.

Si une étape échoue, le fichier temporaire est supprimé, le projet sur le disque est celui que vous aviez, et vos modifications sont toujours ouvertes dans Subtitld. Tant que les doublages d'un projet sont encore en cours d'arrivée, Enregistrer les attend.

Ce qui va dedans

Réglages généraux, puis USFX, choisit ce qu'un projet emporte en plus, pour chaque projet que vous enregistrez :

  • Portraits des locuteursLes visages des locuteurs. Activé.
  • Cache de la forme d'onde de la timelineLa forme d'onde, pour qu'un projet s'ouvre sur un autre ordinateur sans la recalculer. Désactivé.
  • Piste audio originaleLe son de la vidéo, en FLAC. Désactivé.
  • Audio traité (voix + fond)Le son séparé en voix et en reste, en FLAC, pour que la séparation n'ait pas à tourner de nouveau. Désactivé.
  • Fichier vidéo originalLa vidéo elle-même : un seul fichier avec tout, aussi gros que la vidéo et plus. Désactivé.

Chacun entre quand Subtitld en a un à y mettre : le son séparé, par exemple, seulement une fois la séparation faite. Les sous-titres, les traductions, les locuteurs, les voix et chaque doublage sont toujours dedans. Deflate retire environ un sixième du WAV d'un doublage ; une vidéo et du FLAC rétrécissent à peine.

Enregistrement automatique et sauvegardes

  • Enregistrer automatiquement le fichier du projetÉcrit votre .usfx lui-même, comme le fait Enregistrer, de la même manière sûre. Pour un projet enregistré en USFX.
  • Sauvegardes automatiquesUn .usfx complet dans le dossier de sauvegarde de Subtitld, à l'écart de votre propre fichier, nommé <project>_<YYYYMMDDHHMMSS>.usfx, quand il y a des modifications à garder. Au-delà de Conserver au maximum, 20 sauf choix contraire, les plus anciennes sont supprimées.

Dans les gestionnaires de fichiers

La vignette est une carte à l'allure de Subtitld : l'image de la vidéo où le projet a été laissé, le sous-titre dessus, et en dessous les douze secondes de timeline autour de la tête de lecture, la forme d'onde et les sous-titres aux couleurs de leurs locuteurs. En 4:3 à 512 × 384, elle remplit mieux la case carrée d'un gestionnaire de fichiers qu'une image large. Sans vidéo, l'emblème de Subtitld remplace l'image.

Système Le type Ce qu'il apporte
Linux application/x-usfx dans shared-mime-info, une sorte d'application/zip, reconnu par *.usfx Une icône à lui ; avec le paquet AUR, des vignettes de subtitld-thumbnailer, un générateur de vignettes freedesktop.org
Windows Un type de fichier dans l'installateur et le paquet MSIX Une icône ; un fournisseur de vignettes du shell (UsfxThumbnail.dll, IThumbnailProvider) qui lit lui-même le répertoire central du ZIP, Zip64 compris, et décode le PNG avec WIC à la taille que demande l'Explorateur
macOS Le type org.subtitld.usfx, conforme à public.zip-archive Une icône à lui
Haiku application/x-usfx, avec la règle de détection ci-dessus Une icône, et un Tracker qui distingue un projet d'un ZIP

D'un double-clic, un projet s'ouvre dans Subtitld sur les quatre. Les deux générateurs de vignettes ne lisent que thumbnail.png, refusent une image de plus de 8 Mio, et n'acceptent rien qui ne commence par la signature du PNG, 89 50 4E 47 0D 0A 1A 0A. Celui de Windows ne la prend que stockée, comme Subtitld l'écrit. Celui de Linux n'utilise que la bibliothèque standard de Python, car les gestionnaires de fichiers lancent les générateurs de vignettes isolés et nombreux à la fois.

Lire un .usfx soi-même

Rien dans un projet n'appartient à Subtitld seul. Pour regarder dedans :

unzip -l "Tears of Steel.usfx"
unzip -p "Tears of Steel.usfx" manifest.xml

Pour lire ses sous-titres, dans chaque langue, avec la bibliothèque standard 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))

Pour un projet venu de quelqu'un d'autre, analysez avec defusedxml à la place de xml.etree, comme pour tout XML que vous n'avez pas écrit.

En faire un

Le plus petit projet que Subtitld ouvre est un ZIP contenant un subtitles.usf. Sans manifeste, Subtitld demande la vidéo. Pour en faire un que les gestionnaires de fichiers reconnaissent aussi, suivez ce qu'écrit Subtitld :

  • subtitles.usf en premier, puis manifest.xml ;
  • chaque membre compressé en Deflate, sauf thumbnail.png, stocké ;
  • les doublages sous assets/dubs/, désignés dans le document par leur chemin dans le paquet ;
  • de l'UTF-8 partout.

Subtitld garde ce qu'il connaît. Un enregistrement écrit les membres décrits sur cette page, et un document fait de ce que Subtitld a compris de l'ancien. Un fichier qu'un autre outil ajoute au paquet, ou un élément à lui dans l'USF, disparaît dès que Subtitld enregistre le projet. Gardez vos propres données à côté.

Comparaison

USFX est construit comme les paquets de documents des suites bureautiques et des livres numériques : un ZIP, un document principal en XML, un inventaire, les médias à côté.

ODF (.odt) EPUB Office Open XML (.docx) USFX
Norme OASIS ODF 1.3, partie 2 W3C EPUB 3.3, son OCF ECMA-376 partie 2, OPC Cette page
Comment un outil le reconnaît Un premier membre mimetype, stocké Un premier membre mimetype, stocké : application/epub+zip [Content_Types].xml Le nom de son premier membre, subtitles.usf, à l'octet 30
Inventaire META-INF/manifest.xml, un type pour chaque fichier META-INF/container.xml, puis le document de paquet [Content_Types].xml et _rels/ manifest.xml, un type pour chaque membre
Document principal content.xml Le document de paquet et son spine word/document.xml subtitles.usf
Médias Pictures/ N'importe où dans le paquet word/media/ assets/
Aperçu Thumbnails/thumbnail.png Une image de couverture Une partie vignette facultative thumbnail.png, stocké

Le document principal est un format ouvert à part entière : sortez le subtitles.usf d'un .usfx et c'est un fichier USF, un format à la spécification publique depuis 2002.

Anecdotes

30

L'octet où commence le nom du premier membre de chaque projet, et la façon dont Haiku distingue un projet Subtitld de n'importe quel autre ZIP.

512 × 384

La taille de l'image d'un projet : 4:3, parce que les gestionnaires de fichiers montrent les fichiers dans des carrés.

26.10

La version qui a donné au .usfx une icône à lui sous Linux, Windows, macOS et Haiku, et son image dans l'Explorateur Windows et les gestionnaires de fichiers Linux.

Formats associés

Commencer un projet

Ouvrez une vidéo dans Subtitld, faites ses sous-titres et enregistrez : c'est un .usfx.

Télécharger Subtitld