Subtitld-project
Het eigen bestand van Subtitld: een ZIP-pakket met vooraan een USF-document met de ondertitels, hun vertalingen, sprekers en nasynchronisaties, een manifest van al het andere erin, een afbeelding van waar je was gebleven en, als je erom vraagt, de video en het geluid ervan. Eén bestand om te verplaatsen, te back-uppen of door te geven, en elk deel ervan leesbaar met standaardgereedschap.
In één oogopslag
| Extensie | .usfx |
|---|---|
| Mediatype | application/x-usfx, een soort application/zip. Op Apple-systemen org.subtitld.usfx. |
| Specificatie | Deze pagina. Het pakket is de ZIP van PKWARE (APPNOTE.TXT); het document is USF 1.0 met de elementen van Subtitld. |
| Pakket | ZIP, de onderdelen gecomprimeerd met Deflate (RFC 1951) en gecontroleerd met CRC-32; Zip64 voor bestanden boven 2 GiB |
| Eerste onderdeel | subtitles.usf: de naam staat op byte 30 van elk project dat Subtitld opslaat |
| Tijdsprecisie | Ondertitels: milliseconden. Nasynchronisaties: de exacte seconden, met zoveel decimalen als nodig. |
| Tekstcodering | UTF-8, in de XML en in de namen van onderdelen |
| Opmaak | Die van USF: cursief, vet, onderstreept, doorgehaald, kleur en negen plaatsen |
| Sprekers | Elk een naam, een kleur, een afbeelding en een stem |
| Talen | Het origineel en elke vertaling, elk een blok, met ISO 639-2-code en naam |
| Media erin | Nasynchronisaties en afbeeldingen van sprekers; de video, het geluid, de gescheiden stemmen en achtergrond, en de golfvorm van de tijdlijn als je erom vraagt |
Opbouw van een bestand
Een .usfx is een ZIP. Elk archiefprogramma opent hem, hernoemd naar .zip als het programma daarop staat.
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 · Document
Het project zelf, in USF: elke ondertitel, vertaling, spreker en nasynchronisatie. Altijd aanwezig, altijd als eerste.
- 2 · Manifest
Wat het bestand maakte, waar de video stond, hoe het geluid gemengd was, en een mediatype voor elk ander onderdeel.
- 3 · Afbeelding
Wat bestandsbeheerders van het project tonen: het beeld waar je was gebleven, de ondertitel ervan en de tijdlijn op dat punt.
- 4 · Assets
Het geluid van elke nasynchronisatie en de gezichten van de sprekers; de video, het geluid en de golfvorm alleen als je erom vraagt.
Het document zegt wat er gebeurt; de assets zijn wat het afspeelt. Een nasynchronisatie in subtitles.usf noemt haar clip bij haar pad in het pakket, assets/dubs/77a03e27.wav, zodat het pakket naar een andere map, schijf of computer kan en toch compleet blijft.
De onderdelen
| Pad | Wat het bevat | Compressie | Geschreven |
|---|---|---|---|
subtitles.usf |
Het document: ondertitels, vertalingen, sprekers, stemmen, nasynchronisaties | Deflate | Altijd, als eerste |
manifest.xml |
Het manifest | Deflate | Altijd, als tweede |
thumbnail.png |
Een PNG-kaart van 512 × 384 van het project | Opgeslagen | Als er een afbeelding te maken is |
assets/speakers/<speaker>.png |
De afbeelding van een spreker, hooguit 256 pixels per zijde | Deflate | Tenzij je het uitzet |
assets/dubs/<uid>.<ext> |
Het geluid van een take, genoemd naar de ID van de take | Deflate | Altijd, voor elke take met geluid |
assets/dubs/<uid>__<n>__<file> |
Een gesplitst of uitgerekt stuk van een take, en de onaangeroerde bron waaruit het is uitgerekt | Deflate | Als een take gesplitst of uitgerekt is |
assets/video/<file> |
De video | Deflate | Als je erom vraagt |
assets/waveform.npy |
De pieken van de golfvorm van de tijdlijn, een NumPy-array | Deflate | Als je erom vraagt |
assets/audio/original.flac |
Het geluid van de video | Deflate | Als je erom vraagt |
assets/audio/vocals.flac, background.flac |
Het geluid gescheiden in stemmen en de rest | Deflate | Als je erom vraagt |
Namen in assets/ bestaan uit letters, cijfers, -, _ en .; al het andere wordt _, dus Tears of Steel.mkv wordt opgeslagen als Tears_of_Steel.mkv. Letters buiten ASCII blijven behouden, de naam geschreven in UTF-8 en als zodanig gemarkeerd (bit 11 van de ZIP-kop), zoals APPNOTE vraagt.
Waarom de afbeelding wordt opgeslagen, niet gecomprimeerd. Een PNG is al gecomprimeerd; Deflate zou alleen tijd kosten. Opgeslagen staan de bytes precies als PNG in het bestand, zodat een thumbnailer ze uitleest zonder iets uit te pakken.
De eerste bytes
Elk project begint op dezelfde manier: een lokale ZIP-bestandskop, dan de naam van het eerste onderdeel.
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 · Handtekening
PK\3\4, bytes 0 tot 3: hier begint een ZIP-onderdeel. - 2 · Kop
Versie 2.0 nodig om uit te pakken; geen vlaggen; methode 8, Deflate; tijd en datum in MS-DOS-stijl (hier 17 oktober 2026, 14:02:28); de CRC-32; de gecomprimeerde en ongecomprimeerde grootte (15.215 en 57.983 bytes).
- 3 · Naamlengte
13, en geen extra veld.
- 4 · Naam
subtitles.usf, vanaf byte 30.
De naam wordt nooit gecomprimeerd, ook niet als het onderdeel dat wel is. Dat maakt hem tot een handtekening: een ZIP met subtitles.usf als naam op byte 30 is een Subtitld-project. Tracker van Haiku onderscheidt projecten van andere archieven met precies die regel, 0.60 ("PK\003\004") [30] ("subtitles.usf" | "manifest.xml"), hoger gerangschikt dan de gewone ZIP-regel. ODF en EPUB doen hetzelfde met een eerste onderdeel genaamd mimetype.
Een video kan groter zijn dan de oorspronkelijke ZIP-limiet van 4 GiB. Vanaf 2 GiB schrijft Subtitld de extra velden en eindrecords van Zip64 (APPNOTE sectie 4.5), net als boven 65.535 onderdelen; Subtitld, zijn Windows-thumbnailhandler en elke actuele unzip lezen ze.
Het manifest
<?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>
| Element | Wat het bevat |
|---|---|
<manifest version> |
De versie van het manifest, 1.0 |
<format>, <generator> |
USFX, en wat het bestand schreef: Subtitld |
<source path basename> |
Het volledige pad van de video toen het project werd opgeslagen, en alleen de bestandsnaam |
<voicemix volume> |
Waar de schuif Muziek/Stem stond: 0 alleen de achtergrond, 0.5 het geluid zoals het is, 1 alleen de stemmen, met de nasynchronisaties die samen met de achtergrond wegvallen |
<entry path type> |
Eén voor elk onderdeel behalve het manifest zelf, elk met zijn mediatype |
De types zijn application/x-usf+xml, image/png, audio/wav, audio/flac, audio/mpeg, video/mp4, video/x-matroska, video/quicktime, video/webm, video/ogg, en application/octet-stream voor de golfvorm en al het andere.
Het pad van de video reist mee met het bestand. <source path> is waar de video stond op de computer die het project opsloeg, mappen en gebruikersnaam inbegrepen. Houd daar rekening mee voordat je een project deelt. Als het pad nergens heen leidt, zoekt Subtitld de video op naam in de map van het project.
Het document
subtitles.usf is een Universal Subtitle Format-bestand, UTF-8, zoals Subtitld het op zichzelf schrijft, met wat een project nodig heeft toegevoegd in de eigen stijl van USF: elementen en attributen waar USF er geen heeft. Een USF-lezer die overslaat wat hij niet kent, leest de ondertitels.
<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>
Wat Subtitld aan USF toevoegt
| Waar | Element of attribuut | Wat het bevat |
|---|---|---|
<metadata> |
<subtitldcc:origin share-id version> |
De ondertitel op subtitld.cc waar het project vandaan kwam, zodat wijzigingen als volgende versie ervan gepubliceerd kunnen worden. In een eigen namespace, https://subtitld.cc/ns/usf/1, alleen geschreven als die er is. |
<styles> |
<style name> |
Eén voor elke spreker, naar hem of haar genoemd. Geen Default-stijl, die in een speler elke ondertitel zou herstijlen. |
<style> |
<fontstyle color> |
De kleur van de spreker, #RRGGBB |
<style> |
<dubbing engine voice rate pitch fit_to_subtitle> |
De stem van de spreker: de engine, de stem, snelheid en toonhoogte van −100 tot 100, en of nasynchronisaties aan de lengte van hun ondertitel worden aangepast |
<text> |
speaker, style |
Wie het zegt, en diens stijl |
<text> |
alignment |
Een van de negen plaatsen van USF, TopLeft tot BottomRight; geen voor onder in het midden |
<subtitle> |
<dubbing> |
Een take van de nasynchronisatie van de ondertitel, elk een element |
<dubbing> |
uid engine voice rate pitch |
De ID van de take, en de stem waarmee hij gemaakt is |
<dubbing> |
path, raw_path |
Het geluid ervan in het pakket, en de bron waaruit een uitgerekte take gemaakt is |
<dubbing> |
start, end |
Waar hij op de tijdlijn speelt, in seconden |
<dubbing> |
<subclip type path raw_path start end offset rate> |
De stukken van een take die gesplitst of uitgerekt is |
In een gewone .usf kunnen afbeeldingen van sprekers en het geluid van nasynchronisaties in de XML meereizen, als base64 in <avatar> en <data>. Een .usfx doet dat nooit: het zijn eigen onderdelen, een kwart kleiner dan in base64, en gelezen zonder de XML te parsen.
Tijden
De start en stop van een ondertitel zijn USF-tijden, afgerond op de dichtstbijzijnde milliseconde. De tijden van een nasynchronisatie zijn gewone seconden, voluit geschreven, 18.01579117916244: het kortste decimale getal dat terug wordt gelezen als hetzelfde 64-bits getal, zodat een clip die met slepen is geplaatst precies terugkomt waar hij was.
Oudere versies van Subtitld schreven tijden een milliseconde te vroeg, en een start op nul als 23:59:59.999. Subtitld leest die waarde als nul, en laat de milliseconde zoals ze is.
Takes en subclips
Een ondertitel kan meerdere takes hebben. De eerste <dubbing> is degene die speelt; de andere zijn alternatieven, stil tot je er een kiest, die dan naar voren schuift.
Een take die gesplitst of uitgerekt is, houdt een lijst <subclip>s bij, geplaatst zoals clips in een audio-editor:
| Attribuut | Betekenis |
|---|---|
start, end |
Het deel van het bronbestand dat speelt, in seconden vanaf het begin van het bestand |
offset |
Waar dat deel begint, in seconden vanaf de start van de take |
rate |
De snelheid waarop het is uitgerekt: 20 is 120 % |
path, raw_path |
Het geluid dat speelt, en het onaangeroerde geluid waaruit het is uitgerekt |
Een subclip speelt vanaf de start van de take plus zijn offset, gedurende end min start seconden. Gaten zijn stilte; overlappingen worden gemengd. De bronnen worden nooit veranderd, dus elke splitsing en uitrekking kan ongedaan worden gemaakt, en een uitrekking wordt altijd opnieuw gemaakt vanuit raw_path, nooit uit een uitrekking van een uitrekking.
Vertalingen
Elke taal heeft een eigen <subtitles>-blok, met haar ISO 639-2-code en, in het element, de naam van de taal, die Braziliaans Portugees van dat van Portugal onderscheidt. Elk blok bevat elke ondertitel op dezelfde tijden; alleen het eerste bevat nasynchronisaties. Subtitld koppelt een vertaling aan haar ondertitel op begintijd, of aan degene waarmee ze het meest overlapt, zodat blokken van andere programma's niet precies hoeven te kloppen.
Een project openen
Grote projecten gaan meteen open: Subtitld leest eerst wat de editor nodig heeft, en de rest terwijl je werkt.
subtitles.usf, gelezen voor de ondertitels, sprekers en stemmenmanifest.xml, voor de video en de mixassets/speakers/, de gezichten, gedecodeerd buiten de hoofdthread- Een meegeleverde video, één keer uitgepakt
- De nasynchronisaties, eerst, zodat je ze kunt afspelen
- Dan de golfvorm
- Het gescheiden geluid, als laatste
Elke nasynchronisatie op de tijdlijn is gearceerd tot het geluid binnen is, en speelt dan.
Onderdelen worden uitgepakt in de eigen mappen van Subtitld, nooit naast het project: het document, de gezichten en de nasynchronisaties in een cachemap genoemd naar de MD5 van het pad van het project. Wat binnenkomt terwijl je werkt, stroomt in blokken van 1 MiB naar een tijdelijk bestand, dat na voltooiing op zijn plaats wordt hernoemd, zodat een crash halverwege niets half geschreven achterlaat. De volgende keer dat hetzelfde project opengaat, wordt een bestand dat er al staat alleen hergebruikt als het precies zo groot is als het onderdeel; anders wordt het opnieuw uitgepakt.
De video wordt in deze volgorde gezocht:
- een video in het pakket, in
assets/video/; - het pad in
<source path>, als het er nog is; - een bestand met de naam uit
<source basename>, in de map van het project; - anders vraagt Subtitld erom.
Een bestand dat geen ZIP is, afgebroken is of een CRC-controle niet doorstaat, opent niets: Subtitld meldt het en haalt het van de lijst met recente bestanden. Oudere projecten gaan ook open: een zonder manifest, of met de USF onder een andere naam in de hoofdmap van de ZIP.
Een project opslaan
Opslaan brengt het project dat je hebt nooit in gevaar.
- Een momentopname. Het project wordt gekopieerd zoals het is wanneer je opslaat, zodat je kunt blijven bewerken terwijl het wordt geschreven. Opslaan, automatisch opslaan en back-ups wachten op hun beurt: er schrijft er één tegelijk.
- Een nieuw bestand. Het pakket wordt geschreven naar
<project>.usfx.tmpnaast het project. - Niets ontbreekt. Een nasynchronisatie waarvan het geluid nog niet in de cache staat, nog binnenstromend of gewist, wordt gekopieerd uit het bestand dat op het punt staat vervangen te worden. Een project dat zonder video wordt opgeslagen, houdt de afbeelding die het had.
- Gecontroleerd. Het nieuwe bestand wordt opnieuw geopend en de CRC-32 van elk onderdeel geverifieerd.
- Verwisseld. Pas dan vervangt het het project, in één hernoeming (
os.replace): de naam van het project bevat nooit een half project.
Als een stap mislukt, wordt het tijdelijke bestand verwijderd, is het project op schijf het project dat je had, en staan je wijzigingen nog open in Subtitld. Zolang de nasynchronisaties van een project nog binnenstromen, wacht Opslaan erop.
Wat erin gaat
Algemene instellingen, dan USFX, bepaalt wat een project verder meeneemt, voor elk project dat je opslaat:
- Portretafbeeldingen van sprekersDe gezichten van de sprekers. Aan.
- Golfvormcache van de tijdlijnDe golfvorm, zodat een project op een andere computer opengaat zonder hem opnieuw te berekenen. Uit.
- Oorspronkelijk audiospoorHet geluid van de video, als FLAC. Uit.
- Bewerkte audio (stem + achtergrond)Het geluid gescheiden in stemmen en de rest, als FLAC, zodat de scheiding niet opnieuw hoeft. Uit.
- Oorspronkelijk videobestandDe video zelf: één bestand met alles, zo groot als de video en meer. Uit.
Elk gaat erin als Subtitld er een heeft om erin te stoppen: het gescheiden geluid bijvoorbeeld pas nadat de scheiding heeft gedraaid. De ondertitels, vertalingen, sprekers, stemmen en elke nasynchronisatie zitten er altijd in. Deflate haalt ongeveer een zesde van de WAV van een nasynchronisatie af; een video en FLAC krimpen nauwelijks.
Automatisch opslaan en back-ups
- Het projectbestand automatisch opslaanSchrijft je
.usfxzelf, zoals Opslaan doet, op dezelfde veilige manier. Voor een project dat als USFX is opgeslagen. - Automatische back-upsEen volledige
.usfxin de back-upmap van Subtitld, los van je eigen bestand, genaamd<project>_<YYYYMMDDHHMMSS>.usfx, als er wijzigingen te bewaren zijn. Boven Maximaal bewaren, 20 tenzij je anders kiest, worden de oudste verwijderd.
In bestandsbeheerders
De miniatuur is een kaart in de stijl van Subtitld: het beeld van de video waar het project was gebleven, de ondertitel erop, en eronder de twaalf seconden tijdlijn rond de afspeelkop, de golfvorm en de ondertitels in de kleuren van hun sprekers. 4:3 op 512 × 384, zodat hij het vierkante vak van een bestandsbeheerder beter vult dan een breed beeld. Zonder video staat het logo van Subtitld in plaats van het beeld.
| Systeem | Het type | Wat het oplevert |
|---|---|---|
| Linux | application/x-usfx in shared-mime-info, een soort application/zip, herkend aan *.usfx |
Een eigen pictogram; met het AUR-pakket miniaturen van subtitld-thumbnailer, een freedesktop.org-thumbnailer |
| Windows | Een bestandstype in het installatieprogramma en het MSIX-pakket | Een pictogram; een shell-thumbnailprovider (UsfxThumbnail.dll, IThumbnailProvider) die de centrale directory van de ZIP zelf leest, Zip64 inbegrepen, en de PNG met WIC decodeert op de grootte die Verkenner vraagt |
| macOS | Het type org.subtitld.usfx, conform public.zip-archive |
Een eigen pictogram |
| Haiku | application/x-usfx, met de sniffer-regel hierboven |
Een pictogram, en Tracker die een project van een ZIP onderscheidt |
Dubbelgeklikt opent een project op alle vier in Subtitld. Beide thumbnailers lezen alleen thumbnail.png, weigeren er een boven 8 MiB, en nemen niets aan dat niet begint met de handtekening van PNG, 89 50 4E 47 0D 0A 1A 0A. Die van Windows neemt hem alleen opgeslagen aan, zoals Subtitld hem schrijft. Die van Linux gebruikt alleen de standaardbibliotheek van Python, omdat bestandsbeheerders thumbnailers in een sandbox en met vele tegelijk draaien.
Zelf een .usfx lezen
Niets in een project is alleen van Subtitld. Om erin te kijken:
unzip -l "Tears of Steel.usfx"
unzip -p "Tears of Steel.usfx" manifest.xml
Om de ondertitels te lezen, in elke taal, met de standaardbibliotheek van 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 null:
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))
Parse een project van iemand anders met defusedxml in plaats van xml.etree, zoals bij elke XML die je niet zelf schreef.
Er zelf een maken
Het kleinste project dat Subtitld opent, is een ZIP met een subtitles.usf. Zonder manifest vraagt Subtitld om de video. Om er een te maken die ook bestandsbeheerders herkennen, volg je wat Subtitld schrijft:
subtitles.usfeerst, danmanifest.xml;- elk onderdeel gecomprimeerd met Deflate, behalve
thumbnail.png, opgeslagen; - nasynchronisaties onder
assets/dubs/, in het document genoemd bij hun pad in het pakket; - overal UTF-8.
Subtitld bewaart wat het kent. Bij opslaan worden de onderdelen op deze pagina geschreven, en een document gemaakt uit wat Subtitld van het oude begreep. Een bestand dat een ander programma aan het pakket toevoegt, of een eigen element in de USF, is weg zodra Subtitld het project opslaat. Bewaar je eigen gegevens ernaast.
Hoe het zich verhoudt
USFX is opgebouwd zoals de documentpakketten van kantoorsuites en e-books: een ZIP, een hoofddocument in XML, een inventaris, de media ernaast.
ODF (.odt) |
EPUB | Office Open XML (.docx) |
USFX | |
|---|---|---|---|---|
| Standaard | OASIS ODF 1.3, deel 2 | W3C EPUB 3.3, de OCF ervan | ECMA-376 deel 2, OPC | Deze pagina |
| Hoe een programma het herkent | Een eerste onderdeel mimetype, opgeslagen |
Een eerste onderdeel mimetype, opgeslagen: application/epub+zip |
[Content_Types].xml |
De naam van het eerste onderdeel, subtitles.usf, op byte 30 |
| Inventaris | META-INF/manifest.xml, een type voor elk bestand |
META-INF/container.xml, dan het pakketdocument |
[Content_Types].xml en _rels/ |
manifest.xml, een type voor elk onderdeel |
| Hoofddocument | content.xml |
Het pakketdocument en de spine ervan | word/document.xml |
subtitles.usf |
| Media | Pictures/ |
Overal in het pakket | word/media/ |
assets/ |
| Voorbeeld | Thumbnails/thumbnail.png |
Een omslagafbeelding | Een optioneel miniatuuronderdeel | thumbnail.png, opgeslagen |
Het hoofddocument is op zichzelf een open formaat: haal de subtitles.usf uit een .usfx en het is een USF-bestand, een formaat met een openbare specificatie sinds 2002.
Wetenswaardigheden
De byte waar de naam van het eerste onderdeel van elk project begint, en hoe Haiku een Subtitld-project van elke andere ZIP onderscheidt.
De grootte van de afbeelding van een project: 4:3, omdat bestandsbeheerders bestanden in vierkanten tonen.
De release die .usfx een eigen pictogram gaf op Linux, Windows, macOS en Haiku, en een afbeelding in Windows Verkenner en Linux-bestandsbeheerders.
Verwante formaten
-
.usfUniversal Subtitle Format
-
.jsonJSON subtitles and transcripts
-
.ttmlTimed Text Markup Language
Open een video in Subtitld, maak de ondertitels en sla op: dat is een .usfx.