Проєкт Subtitld
Власний файл Subtitld: ZIP-пакет, на початку якого стоїть USF-документ із субтитрами, їхніми перекладами, мовцями та дубляжами, далі маніфест усього іншого всередині, зображення місця, де ви зупинилися, і, якщо попросите, відео та його звук. Один файл, щоб перенести, зберегти резервну копію чи передати, і кожна його частина читається стандартними інструментами.
Коротко
| Розширення | .usfx |
|---|---|
| Тип медіа | application/x-usfx, різновид application/zip. У системах Apple — org.subtitld.usfx. |
| Специфікація | Ця сторінка. Пакет — ZIP від PKWARE (APPNOTE.TXT); документ — USF 1.0 з елементами Subtitld. |
| Пакет | ZIP, члени якого стиснуті Deflate (RFC 1951) і перевіряються CRC-32; Zip64 для файлів понад 2 ГіБ |
| Перший член | subtitles.usf: його назва стоїть із байта 30 у кожному проєкті, який зберігає Subtitld |
| Точність часу | Субтитри: мілісекунди. Дубляжі: точні секунди, із стількома десятковими знаками, скільки потрібно. |
| Кодування тексту | UTF-8, і в XML, і в назвах членів |
| Оформлення | Як у USF: курсив, жирний, підкреслення, закреслення, колір і дев’ять місць |
| Мовці | Кожен має ім’я, колір, зображення та голос |
| Мови | Оригінал і кожен переклад, по блоку на кожну, за кодом ISO 639-2 і назвою |
| Медіа всередині | Дубляжі та зображення мовців; на запит — відео, його звук, відокремлені голоси й фон і форма хвилі шкали часу |
Будова файлу
.usfx — це ZIP. Його відкриває будь-який архіватор; якщо інструмент наполягає, перейменуйте файл на .zip.
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 · Документ
Сам проєкт у форматі USF: кожен субтитр, переклад, мовець і дубляж. Завжди присутній, завжди перший.
- 2 · Маніфест
Що створило файл, де було відео, як змішано звук, і тип медіа для кожного іншого члена.
- 3 · Зображення
Те, що файлові менеджери показують із проєкту: кадр, на якому ви зупинилися, його субтитр і шкалу часу в цьому місці.
- 4 · Ресурси
Звук кожного дубляжу та обличчя мовців; відео, його звук і форма хвилі — лише на ваш запит.
Документ каже, що відбувається; ресурси — це те, що він відтворює. Дубляж у subtitles.usf називає свій кліп за шляхом у пакеті, assets/dubs/77a03e27.wav, тож пакет можна перенести в іншу теку, на інший диск чи комп’ютер, і він залишиться цілим.
Члени пакета
| Шлях | Що містить | Стиснення | Коли записується |
|---|---|---|---|
subtitles.usf |
Документ: субтитри, переклади, мовці, голоси, дубляжі | Deflate | Завжди, першим |
manifest.xml |
Маніфест | Deflate | Завжди, другим |
thumbnail.png |
PNG-картка проєкту 512 × 384 | Stored | Коли є з чого зробити зображення |
assets/speakers/<speaker>.png |
Зображення мовця, не більше 256 пікселів за стороною | Deflate | Якщо ви не вимкнете |
assets/dubs/<uid>.<ext> |
Звук дубля, названий за ідентифікатором дубля | Deflate | Завжди, для кожного дубля зі звуком |
assets/dubs/<uid>__<n>__<file> |
Розділений або розтягнутий фрагмент дубля і незмінене джерело, з якого його розтягнуто | Deflate | Коли дубль розділили чи розтягнули |
assets/video/<file> |
Відео | Deflate | На ваш запит |
assets/waveform.npy |
Піки форми хвилі шкали часу, масив NumPy | Deflate | На ваш запит |
assets/audio/original.flac |
Звук відео | Deflate | На ваш запит |
assets/audio/vocals.flac, background.flac |
Звук, розділений на голоси та решту | Deflate | На ваш запит |
Назви в assets/ складаються з літер, цифр, -, _ і .; усе інше стає _, тож Tears of Steel.mkv зберігається як Tears_of_Steel.mkv. Літери поза ASCII зберігаються: назва записується в UTF-8 і позначається відповідним прапорцем (біт 11 заголовка ZIP), як вимагає APPNOTE.
Чому зображення зберігається без стиснення. PNG уже стиснутий; Deflate лише забрав би час. Без стиснення його байти лежать у файлі точно як PNG, тож генератор мініатюр зчитує їх, нічого не розпаковуючи.
Перші байти
Кожен проєкт починається однаково: локальний заголовок файлу ZIP, далі назва першого члена.
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 · Сигнатура
PK\3\4, байти з 0 по 3: тут починається член ZIP. - 2 · Заголовок
Для розпакування потрібна версія 2.0; без прапорців; метод 8, Deflate; час і дата у стилі MS-DOS (тут 17 жовтня 2026, 14:02:28); CRC-32; стиснений і нестиснений розміри (15 215 і 57 983 байти).
- 3 · Довжина назви
13, без додаткового поля.
- 4 · Назва
subtitles.usf, від байта 30.
Назва ніколи не стискається, навіть коли член стиснутий. Це робить її сигнатурою: ZIP, у якого на байті 30 стоїть назва subtitles.usf, — це проєкт Subtitld. Tracker у Haiku відрізняє проєкти від інших архівів саме за цим правилом, 0.60 ("PK\003\004") [30] ("subtitles.usf" | "manifest.xml"), яке має вищий пріоритет за звичайне правило ZIP. ODF і EPUB роблять те саме з першим членом на ім’я mimetype.
Відео може бути більшим за початкову межу ZIP у 4 ГіБ. Починаючи з 2 ГіБ, Subtitld записує додаткові поля та кінцеві записи Zip64 (APPNOTE, розділ 4.5), так само як і понад 65 535 членів; Subtitld, його обробник мініатюр для Windows і будь-який сучасний unzip їх читають.
Маніфест
<?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>
| Елемент | Що містить |
|---|---|
<manifest version> |
Версія маніфесту, 1.0 |
<format>, <generator> |
USFX і те, що записало файл: Subtitld |
<source path basename> |
Повний шлях до відео на момент збереження проєкту і лише назва його файлу |
<voicemix volume> |
Положення повзунка Музика/Голос: 0 — лише фон, 0.5 — звук як є, 1 — лише голоси, а дубляжі затихають разом із фоном |
<entry path type> |
По одному для кожного члена, крім самого маніфесту, кожен зі своїм типом медіа |
Типи: application/x-usf+xml, image/png, audio/wav, audio/flac, audio/mpeg, video/mp4, video/x-matroska, video/quicktime, video/webm, video/ogg, а для форми хвилі та всього іншого — application/octet-stream.
Шлях до відео подорожує разом із файлом. <source path> — це місце, де відео лежало на комп’ютері, який зберіг проєкт, разом із теками та ім’ям користувача. Пам’ятайте про це, перш ніж ділитися проєктом. Якщо шлях нікуди не веде, Subtitld шукає відео за назвою в теці проєкту.
Документ
subtitles.usf — це файл Universal Subtitle Format в UTF-8, такий, яким його записує сам Subtitld, із доданим тим, що потрібне проєкту, у стилі самого USF: елементи й атрибути там, де в USF їх немає. Читач USF, який пропускає незнайоме, прочитає його субтитри.
<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>
Що Subtitld додає до USF
| Де | Елемент або атрибут | Що містить |
|---|---|---|
<metadata> |
<subtitldcc:origin share-id version> |
Субтитри на subtitld.cc, з яких походить проєкт, щоб зміни можна було опублікувати як їхню наступну версію. У власному просторі імен, https://subtitld.cc/ns/usf/1, записується лише тоді, коли такі є. |
<styles> |
<style name> |
По одному для кожного мовця, названий його ім’ям. Стилю Default немає, бо він змінив би вигляд кожного субтитру в плеєрі. |
<style> |
<fontstyle color> |
Колір мовця, #RRGGBB |
<style> |
<dubbing engine voice rate pitch fit_to_subtitle> |
Голос мовця: рушій, голос, швидкість і висота від −100 до 100, а також чи підганяються дубляжі під тривалість субтитру |
<text> |
speaker, style |
Хто це каже, і його стиль |
<text> |
alignment |
Одне з дев’яти місць USF, від TopLeft до BottomRight; для низу по центру — жодного |
<subtitle> |
<dubbing> |
Дубль дубляжу субтитру, по елементу на кожен |
<dubbing> |
uid engine voice rate pitch |
Ідентифікатор дубля і голос, яким його зроблено |
<dubbing> |
path, raw_path |
Його звук у пакеті та джерело, з якого зроблено розтягнутий дубль |
<dubbing> |
start, end |
Де він звучить на шкалі часу, у секундах |
<dubbing> |
<subclip type path raw_path start end offset rate> |
Фрагменти дубля, який розділили чи розтягнули |
У звичайному .usf зображення мовців і звук дубляжів можуть бути всередині XML, у base64 в <avatar> і <data>. .usfx ніколи так не робить: це окремі члени, на чверть менші, ніж у base64, і читаються без розбору XML.
Час
start і stop субтитру — це час USF, округлений до найближчої мілісекунди. Час дубляжу — це прості секунди, записані повністю, 18.01579117916244: найкоротший десятковий запис, який читається назад як те саме 64-бітне число, тож кліп, розміщений перетягуванням, повертається точно туди, де був.
Старіші версії Subtitld записували час на мілісекунду раніше, а початок у нулі — як 23:59:59.999. Subtitld читає це значення як нуль, а мілісекунду залишає як є.
Дублі та підкліпи
Субтитр може мати кілька дублів. Перший <dubbing> — той, що звучить; інші — альтернативи, які мовчать, доки ви не оберете одну з них, і тоді вона переходить на перше місце.
Дубль, який розділили чи розтягнули, зберігає список <subclip>, розміщених як кліпи в аудіоредакторі:
| Атрибут | Значення |
|---|---|
start, end |
Частина вихідного файлу, що звучить, у секундах від початку файлу |
offset |
Де ця частина починається, у секундах від start дубля |
rate |
Швидкість, до якої її розтягнуто: 20 — це 120 % |
path, raw_path |
Звук, що звучить, і незмінений звук, з якого його розтягнуто |
Підкліп звучить від start дубля плюс його offset упродовж end мінус start секунд. Проміжки — тиша; накладання змішуються. Джерела ніколи не змінюються, тож кожне розділення та розтягнення можна скасувати, а розтягнення завжди переробляється з raw_path, ніколи з розтягнення розтягнення.
Переклади
Кожна мова має власний блок <subtitles>, названий кодом ISO 639-2, а в елементі — назвою мови, яка відрізняє бразильську португальську від португальської Португалії. Кожен блок містить кожен субтитр у тому самому часі; лише перший містить дубляжі. Subtitld зіставляє переклад із субтитром за часом початку або за тим, з яким він найбільше перетинається, тож блоки, записані іншими інструментами, не мусять збігатися.
Відкриття проєкту
Великі проєкти відкриваються одразу: Subtitld спершу читає те, що потрібне редактору, а решту — поки ви працюєте.
subtitles.usf, прочитаний заради субтитрів, мовців і голосівmanifest.xml, заради відео та міксуassets/speakers/, обличчя, декодовані поза головним потоком- Вкладене відео, розпаковане один раз
- Спершу дубляжі, щоб ви могли їх відтворювати
- Потім форма хвилі
- Наостанок відокремлений звук
Кожен дубляж на шкалі часу заштрихований, доки не надійде його звук, а тоді звучить.
Члени розпаковуються у власні теки Subtitld, ніколи не поруч із проєктом: документ, обличчя й дубляжі — у теку кешу, названу за MD5 шляху проєкту. Те, що надходить, поки ви працюєте, передається частинами по 1 МіБ у тимчасовий файл, який після завершення перейменовується на своє місце, тож збій посередині не залишає нічого записаного наполовину. Коли той самий проєкт відкривається наступного разу, наявний файл використовується повторно, лише якщо його розмір точно збігається з розміром члена; інакше він розпаковується знову.
Відео шукається в такому порядку:
- відео всередині пакета, в
assets/video/; - шлях у
<source path>, якщо файл досі там; - файл із назвою з
<source basename>у теці проєкту; - інакше Subtitld просить вказати його.
Файл, який не є ZIP, обрізаний або не проходить перевірку CRC, нічого не відкриває: Subtitld повідомляє про це і прибирає його зі списку нещодавніх. Відкриваються й давніші проєкти: без маніфесту або з USF під іншою назвою в корені ZIP.
Збереження проєкту
Зберегти ніколи не ставить під загрозу проєкт, який у вас є.
- Знімок. Проєкт копіюється таким, яким він є в момент збереження, тож ви можете редагувати далі, поки він записується. Збереження, автозбереження та резервні копії чергуються: одночасно пише лише одне.
- Новий файл. Пакет записується в
<project>.usfx.tmpпоруч із проєктом. - Нічого не бракує. Дубляж, звуку якого ще немає в кеші, бо він досі надходить або його очищено, копіюється з файлу, який от-от буде замінено. Проєкт, збережений без відео, зберігає зображення, яке мав.
- Перевірено. Новий файл відкривається знову, і CRC-32 кожного члена перевіряється.
- Замінено. Лише тоді він замінює проєкт одним перейменуванням (
os.replace): під назвою проєкту ніколи не лежить половина проєкту.
Якщо будь-який крок не вдається, тимчасовий файл видаляється, на диску лишається той проєкт, що у вас був, а ваші зміни досі відкриті в Subtitld. Поки дубляжі проєкту ще надходять, Зберегти на них чекає.
Що потрапляє всередину
Загальні налаштування, далі USFX, визначає, що ще несе проєкт, для кожного проєкту, який ви зберігаєте:
- Портрети мовцівОбличчя мовців. Увімкнено.
- Кеш форми хвилі шкали часуФорма хвилі, щоб проєкт відкрився на іншому комп’ютері без її повторного обчислення. Вимкнено.
- Оригінальна звукова доріжкаЗвук відео, у FLAC. Вимкнено.
- Оброблене аудіо (вокал + фон)Звук, розділений на голоси та решту, у FLAC, щоб розділення не довелося запускати знову. Вимкнено.
- Оригінальний відеофайлСаме відео: один файл з усім, завбільшки як відео і ще трохи. Вимкнено.
Кожен пункт потрапляє всередину, коли Subtitld має що покласти: відокремлений звук, наприклад, лише після того, як розділення відбулося. Субтитри, переклади, мовці, голоси та кожен дубляж завжди всередині. Deflate зменшує WAV дубляжу приблизно на шосту частину; відео та FLAC майже не стискаються.
Автозбереження та резервні копії
- Автоматично зберігати файл проєктуЗаписує сам ваш
.usfx, як Зберегти, тим самим безпечним способом. Для проєкту, збереженого як USFX. - Автоматичні резервні копіїПовний
.usfxу теці резервних копій Subtitld, окремо від вашого файлу, з назвою<project>_<YYYYMMDDHHMMSS>.usfx, коли є зміни, які варто зберегти. Понад Зберігати не більше, тобто 20, якщо ви не оберете інше, найстаріші видаляються.
У файлових менеджерах
Мініатюра — це картка в стилі Subtitld: кадр відео, де проєкт залишили, субтитр на ньому, а під ним дванадцять секунд шкали часу довкола курсора відтворення, форма хвилі та субтитри в кольорах їхніх мовців. 4:3 при 512 × 384, тож вона заповнює квадратну клітинку файлового менеджера краще за широкий кадр. Без відео замість кадру стоїть знак Subtitld.
| Система | Тип | Що дає |
|---|---|---|
| Linux | application/x-usfx у shared-mime-info, різновид application/zip, за маскою *.usfx |
Власна піктограма; з пакетом AUR — мініатюри від subtitld-thumbnailer, генератора мініатюр freedesktop.org |
| Windows | Тип файлу в інсталяторі та пакеті MSIX | Піктограма; постачальник мініатюр оболонки (UsfxThumbnail.dll, IThumbnailProvider), який сам читає центральний каталог ZIP, зокрема Zip64, і декодує PNG через WIC у розмірі, який просить Провідник |
| macOS | Тип org.subtitld.usfx, сумісний із public.zip-archive |
Власна піктограма |
| Haiku | application/x-usfx з наведеним вище правилом розпізнавання |
Піктограма, і Tracker відрізняє проєкт від ZIP |
Подвійним клацанням проєкт відкривається в Subtitld у всіх чотирьох. Обидва генератори мініатюр читають лише thumbnail.png, відхиляють файл понад 8 МіБ і не беруть нічого, що не починається сигнатурою PNG, 89 50 4E 47 0D 0A 1A 0A. Windows-генератор бере його лише нестиснутим, як його записує Subtitld. Linux-генератор використовує тільки стандартну бібліотеку Python, бо файлові менеджери запускають генератори мініатюр в ізольованому середовищі й багато одночасно.
Читання .usfx власноруч
Ніщо в проєкті не належить лише Subtitld. Щоб зазирнути всередину:
unzip -l "Tears of Steel.usfx"
unzip -p "Tears of Steel.usfx" manifest.xml
Щоб прочитати субтитри всіма мовами стандартною бібліотекою 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))
Проєкт від когось іншого розбирайте за допомогою defusedxml замість xml.etree, як і будь-який XML, який писали не ви.
Як створити власний
Найменший проєкт, який відкриває Subtitld, — це ZIP із файлом subtitles.usf. Без маніфесту Subtitld просить вказати відео. Щоб створити такий, який розпізнають і файлові менеджери, наслідуйте те, що записує Subtitld:
- спершу
subtitles.usf, потімmanifest.xml; - кожен член стиснутий Deflate, крім
thumbnail.png, який зберігається без стиснення; - дубляжі в
assets/dubs/, названі в документі за шляхом у пакеті; - UTF-8 усюди.
Subtitld зберігає те, що знає. Збереження записує члени, описані на цій сторінці, і документ, складений із того, що Subtitld зрозумів зі старого. Файл, доданий до пакета іншим інструментом, або власний елемент у USF зникає, щойно Subtitld збереже проєкт. Тримайте власні дані поруч.
Порівняння
USFX побудований так само, як пакети документів офісних пакетів і електронних книжок: ZIP, основний документ в XML, опис вмісту та медіа поруч.
ODF (.odt) |
EPUB | Office Open XML (.docx) |
USFX | |
|---|---|---|---|---|
| Стандарт | OASIS ODF 1.3, частина 2 | W3C EPUB 3.3, його OCF | ECMA-376, частина 2, OPC | Ця сторінка |
| Як його розпізнає інструмент | Перший член mimetype, без стиснення |
Перший член mimetype, без стиснення: application/epub+zip |
[Content_Types].xml |
Назва першого члена, subtitles.usf, на байті 30 |
| Опис вмісту | META-INF/manifest.xml, тип для кожного файлу |
META-INF/container.xml, далі документ пакета |
[Content_Types].xml і _rels/ |
manifest.xml, тип для кожного члена |
| Основний документ | content.xml |
Документ пакета та його spine | word/document.xml |
subtitles.usf |
| Медіа | Pictures/ |
Будь-де в пакеті | word/media/ |
assets/ |
| Попередній перегляд | Thumbnails/thumbnail.png |
Зображення обкладинки | Необов’язкова частина з мініатюрою | thumbnail.png, без стиснення |
Основний документ — самостійний відкритий формат: витягніть subtitles.usf із .usfx, і це файл USF, формату з публічною специфікацією від 2002 року.
Цікаве
Байт, з якого починається назва першого члена кожного проєкту, і за яким Haiku відрізняє проєкт Subtitld від будь-якого іншого ZIP.
Розмір зображення проєкту: 4:3, бо файлові менеджери показують файли у квадратах.
Випуск, що дав .usfx власну піктограму в Linux, Windows, macOS і Haiku, а також зображення в Провіднику Windows і файлових менеджерах Linux.
Пов'язані формати
Відкрийте відео в Subtitld, створіть до нього субтитри та збережіть: це і є .usfx.