Проєкт Subtitld

ВідкритиЗберегтиZIPXMLПроєкт

Власний файл 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. 1 · Документ

    Сам проєкт у форматі USF: кожен субтитр, переклад, мовець і дубляж. Завжди присутній, завжди перший.

  2. 2 · Маніфест

    Що створило файл, де було відео, як змішано звук, і тип медіа для кожного іншого члена.

  3. 3 · Зображення

    Те, що файлові менеджери показують із проєкту: кадр, на якому ви зупинилися, його субтитр і шкалу часу в цьому місці.

  4. 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. 1 · Сигнатура

    PK\3\4, байти з 0 по 3: тут починається член ZIP.

  2. 2 · Заголовок

    Для розпакування потрібна версія 2.0; без прапорців; метод 8, Deflate; час і дата у стилі MS-DOS (тут 17 жовтня 2026, 14:02:28); CRC-32; стиснений і нестиснений розміри (15 215 і 57 983 байти).

  3. 3 · Довжина назви

    13, без додаткового поля.

  4. 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 МіБ у тимчасовий файл, який після завершення перейменовується на своє місце, тож збій посередині не залишає нічого записаного наполовину. Коли той самий проєкт відкривається наступного разу, наявний файл використовується повторно, лише якщо його розмір точно збігається з розміром члена; інакше він розпаковується знову.

Відео шукається в такому порядку:

  1. відео всередині пакета, в assets/video/;
  2. шлях у <source path>, якщо файл досі там;
  3. файл із назвою з <source basename> у теці проєкту;
  4. інакше Subtitld просить вказати його.

Файл, який не є ZIP, обрізаний або не проходить перевірку CRC, нічого не відкриває: Subtitld повідомляє про це і прибирає його зі списку нещодавніх. Відкриваються й давніші проєкти: без маніфесту або з USF під іншою назвою в корені ZIP.

Збереження проєкту

Зберегти ніколи не ставить під загрозу проєкт, який у вас є.

  1. Знімок. Проєкт копіюється таким, яким він є в момент збереження, тож ви можете редагувати далі, поки він записується. Збереження, автозбереження та резервні копії чергуються: одночасно пише лише одне.
  2. Новий файл. Пакет записується в <project>.usfx.tmp поруч із проєктом.
  3. Нічого не бракує. Дубляж, звуку якого ще немає в кеші, бо він досі надходить або його очищено, копіюється з файлу, який от-от буде замінено. Проєкт, збережений без відео, зберігає зображення, яке мав.
  4. Перевірено. Новий файл відкривається знову, і CRC-32 кожного члена перевіряється.
  5. Замінено. Лише тоді він замінює проєкт одним перейменуванням (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 року.

Цікаве

30

Байт, з якого починається назва першого члена кожного проєкту, і за яким Haiku відрізняє проєкт Subtitld від будь-якого іншого ZIP.

512 × 384

Розмір зображення проєкту: 4:3, бо файлові менеджери показують файли у квадратах.

26.10

Випуск, що дав .usfx власну піктограму в Linux, Windows, macOS і Haiku, а також зображення в Провіднику Windows і файлових менеджерах Linux.

Пов'язані формати

Почніть проєкт

Відкрийте відео в Subtitld, створіть до нього субтитри та збережіть: це і є .usfx.

Завантажити Subtitld