Тег track в HTML: что это и какие у него атрибуты

Тег track (от английского track, «дорожка») подключает к video или audio текстовую дорожку: субтитры, названия глав или реплики, привязанные ко времени. Это одиночный тег (в стандарте пустой элемент): закрывающего тега нет, всё задаётся атрибутами. Сам по себе он ничего не показывает: браузер берёт отдельный файл с репликами, а на экран выводит только субтитры и только поверх видео.

Дальше разобраны атрибуты, значения kind, формат файла WebVTT, несколько дорожек, работа из JavaScript, дорожка для звука, главы, стили реплик и причины, по которым дорожка не загружается. Сами теги описаны на страницах о теге video и о теге audio.

HTML
<video src="film.webm" controls>
  <track kind="subtitles" src="ru.vtt" srclang="ru"
         label="Русский" default>
</video>

Тег track в HTML: что это и почему он одиночный

Сначала о том, где записывается тег и почему у него нет закрывающей части.

Тег track допустим только внутри video или audio, после вложенных source, если они есть. Содержимого у него нет, поэтому закрывающий тег не нужен. Браузер загружает дорожку и с записанным </track>, но писать его не нужно: слэш в конце <track /> допускается и ничего не меняет.

Дорожка состоит из двух частей: тега в разметке и отдельного файла в формате WebVTT с расширением .vtt. В файле записаны реплики и время, когда каждая появляется. Тег только указывает на файл и описывает его: вид, язык, название. Способ вшить субтитры в само изображение не даёт ни выбрать язык, ни выключить текст, а дорожка track даёт и то и другое.

HTML
<video controls>
  <source src="film.webm" type="video/webm">
  <track kind="subtitles" src="ru.vtt" srclang="ru" default>
  <track kind="subtitles" src="en.vtt" srclang="en">
</video>

Пример: тег track внутри video и состояние дорожки

Результат

Это настоящее видео с одной дорожкой. Нажмите воспроизведение: реплики выводит браузер. Кнопки переключают режим дорожки, а строки под видео показывают её состояние.

Субтитры нужны тем, кто смотрит без звука или не знает язык ролика, а для демонстраций интерфейса без озвучки они часто единственный способ объяснить происходящее. Те же дорожки хранят названия глав и служебные данные для скриптов. Справочные описания есть на MDN, в стандарте HTML Living Standard, а формат файла описан на странице WebVTT API.

Атрибуты тега track: kind, src, srclang, label и default

Атрибутов пять, и только src нужен всегда, а остальные уточняют, что это за дорожка.

Булев атрибут default включён, если записан, и выключен, если его нет: значение не нужно. Остальные принимают значение: адрес, язык, название или слово из набора.

HTML
<track kind="captions" src="ru.vtt" srclang="ru"
       label="Русский" default>
АтрибутЧто делаетПример записи
kindВид дорожки: subtitles, captions, descriptions, chapters, metadata. Если атрибута нет, берётся subtitles<track kind="captions" src="ru.vtt">
srcАдрес файла .vtt, обязателен<track src="ru.vtt">
srclangЯзык дорожки кодом: ru, en, de. Стандарт требует его для subtitles<track src="ru.vtt" srclang="ru">
labelНазвание дорожки для меню плеера<track src="ru.vtt" label="Русский">
defaultВключает дорожку без выбора читателя. subtitles и captions считаются одним видом, и default допускается один на оба<track src="ru.vtt" default>

Пример: как браузер понимает атрибуты тега track

Результат

Кнопки собирают настоящие дорожки и показывают, что браузер понял. Без kind это subtitles, а неверное значение превращается в metadata. Без srclang дорожка работает, но язык пустой. Из двух default включается только первый, а default у разных видов работают оба.

Самая коварная запись: опечатка в kind. Значение subtitle без последней буквы браузер не отвергает, а превращает дорожку в metadata, и субтитры на экране не появятся. Без srclang дорожка работает, но язык у неё пустой, а стандарт для субтитров его требует, поэтому записывайте его всегда.

Атрибут kind у тега track: subtitles, captions, chapters и другие значения

Значение kind решает, что браузер сделает с репликами: покажет на экране, предложит в меню или отдаст только скрипту.

ЗначениеДля чегоПример записи
subtitlesПеревод или текст речи для тех, кто слышит звук, но не знает язык роликаkind="subtitles"
captionsПолная расшифровка для тех, кто не слышит звук: речь и важные звукиkind="captions"
descriptionsОписание происходящего на экране для тех, кто не видит картинку1kind="descriptions"
chaptersНазвания глав с временем начала для навигацииkind="chapters"
metadataСлужебные данные для скриптов, читателю не показываютсяkind="metadata"

1 Реплики такой дорожки загружаются, но на экран не выводятся. По стандарту такие реплики озвучивает синтезатор речи, а не рисует браузер.

Пример: что показывает тег track для разных значений kind

Результат

Видео остановлено на 1,5 секунде, дорожка включена в режиме showing. Реплика видна на экране только у subtitles и captions, хотя у остальных видов она тоже загружена и активна: счётчик активных реплик везде равен единице.

Разница между subtitles и captions в том, слышит читатель звук или не слышит. В русскоязычных справочниках встречается путаница: subtitles описывают как дорожку для глухих, а это назначение captions. Для видео без озвучки подходят captions, для зарубежного ролика с переводом subtitles. Главы и служебные данные разобраны в отдельных разделах ниже.

Файл WebVTT для тега track: как записать .vtt

Файл с репликами текстовый: первая строка WEBVTT, дальше блоки, разделённые пустой строкой.

Реплика (по-английски cue) состоит из необязательного идентификатора, времени начала и конца через --> и текста. В файле допустимы комментарии, настройки положения и теги внутри текста.

WebVTT
WEBVTT

NOTE Комментарий для автора, зритель его не увидит

1
00:00:01.000 --> 00:00:03.000
Первая реплика

2
00:00:04.000 --> 00:00:06.000 line:10% align:start
Вторая реплика с <b>выделением</b>
Часть файлаКак записываетсяПример
ЗаголовокПервая строка WEBVTT. Без неё браузер отвергает файл целикомWEBVTT
Времячч:мм:сс.ттт или короче, мм:сс.ттт. Перед миллисекундами точка, а не запятая00:01.000 --> 00:03.000
ИдентификаторСтрока перед временем, в скрипте доступна как cue.idintro
НастройкиПосле времени: line, position, size, alignline:10% align:start
Теги в текстеb, i, u, c.класс, v ИмяЭто <b>важно</b>
КомментарийБлок со словом NOTE в началеNOTE проверить время

Пример: редактор файла WebVTT для тега track

Результат

Текст в поле превращается в настоящий файл дорожки. Кнопка с запятой заменяет точки в записи времени, как в формате SRT: файл принимается, но ни одна реплика не показывается. Без строки WEBVTT браузер отвергает файл целиком.

Субтитры из других программ часто сохранены в формате SRT: в нём время пишут через запятую и нет строки WEBVTT. Перед подключением файл придётся привести к виду выше. Положение реплики задают настройками в файле, а не стилями: настройка line:10% поднимает реплику к верхнему краю кадра, а align:start прижимает её влево.

Несколько дорожек и атрибут default у тега track

У одного видео может быть много дорожек, по одной на язык, и браузер должен знать, какую включить сам.

Читатель выбирает дорожку в меню плеера, где она подписана значением label. Если ничего не выбирать, включится та, у которой записан default. Остальные дорожки браузер не загружает: у выключенной дорожки readyState равен 0, и обращения за её файлом нет. Файл загрузится, когда режим дорожки сменится на включённый.

РежимЧто значитПример записи
disabledДорожка выключена, файл не берётсяtrack.mode = "disabled"
hiddenФайл загружен, реплики доступны скрипту, на экран не выводятсяtrack.mode = "hidden"
showingФайл загружен, реплики субтитров и captions выводятся на экранtrack.mode = "showing"

Пример: несколько дорожек тега track и режим disabled

Результат

Русская дорожка включена атрибутом default, английская ещё не загружена, её readyState равен нулю. После выбора English файл второй дорожки загружается, а у русской режим становится disabled.

Если записать default у двух дорожек одного вида (subtitles и captions считаются одним видом), сработает первая, а вторая останется disabled и не загрузится. У дорожек разных видов, например subtitles и chapters, можно записать по одному default: включатся обе.

Тег track в JavaScript: textTracks, mode и cuechange

Дорожка доступна из скрипта как объект TextTrack: её можно читать, включать и даже создавать без файла.

Свойство или методЧто делаетПример записи
video.textTracksСписок всех дорожек элементаvideo.textTracks[0]
modeРежим дорожки: disabled, hidden, showingtrack.mode = "hidden"
cuesВсе реплики дорожки, пока файл не загружен, там null или пустоtrack.cues.length
activeCuesРеплики, которые идут сейчасtrack.activeCues[0].text
cuechangeСобытие: набор активных реплик изменилсяtrack.addEventListener("cuechange", f)
readyState тега0 — не загружается, 1 — идёт загрузка, 2 — загружена, 3 — ошибкаtrackTag.readyState
addTextTrack()Создаёт дорожку без файла и без тегаvideo.addTextTrack("metadata")
VTTCueРеплика для такой дорожки: начало, конец, текстnew VTTCue(1, 3, "текст")
JavaScript
const video = document.querySelector("video");
const track = video.textTracks[0];
track.mode = "hidden";

track.addEventListener("cuechange", () => {
  const cue = track.activeCues[0];
  caption.textContent = cue ? cue.text : "";
});

Пример: события cuechange у дорожки тега track

Результат

Видео идёт 8 секунд, а журнал показывает каждую смену активной реплики. Дорожка из тега track и дорожка из addTextTrack() ведут себя одинаково: режим у обеих hidden, на экран ничего не выводится.

Реплика активна с момента start до момента end, сам момент end уже не входит: в примере событие в 2,5 секунды показало ноль активных реплик. Видео в примере идёт . Режим hidden нужен, когда реплики хотят вывести самим: файл загружен, события приходят, а браузер ничего не рисует. Дорожка из addTextTrack() сразу получает режим hidden и не появляется в разметке: в video тегов track при этом нет. Текст реплики в свойстве text хранится вместе с тегами, например Вторая <b>реплика</b>, а разобранный вид даёт cue.getCueAsHTML().

Тег track в audio: текст для звука без картинки

У audio нет области показа, поэтому браузер ничего не выведет, и текст показывает сам скрипт.

Дорожка к audio загружается и работает так же, как у видео: у audio с default загружаются все реплики, а cuechange приходит в те же моменты. На экране при этом ничего не появляется: блок остаётся прежнего размера. Поэтому для звука выбирают kind="metadata": вместе с default режим hidden включается сам, а текст выводится на страницу скриптом.

HTML
<audio src="podcast.mp3" controls>
  <track kind="metadata" src="podcast.vtt" default>
</audio>

Пример: тег track в audio и расшифровка, которая следует за звуком

Результат

Звук идёт в настоящем audio, а строка под ним подсвечивается по событию cuechange. Нажмите на строку, чтобы перемотать звук к ней. Размер блока audio не изменился: сама дорожка ничего не выводит.

Строка расшифровки, например Сначала разберём, где он записывается, хранится в файле .vtt и не входит в разметку страницы, поэтому полную расшифровку для чтения лучше записать и обычным текстом, например внутри details. Подробнее о самом теге читайте на странице о теге audio.

Тег track kind chapters: главы видео и навигация

Дорожка глав содержит названия с временем начала, и из неё скрипт строит оглавление видео.

Для kind="chapters" файл загружается, но на экран ничего не выводится, как и у остальных видов, кроме subtitles и captions. Список глав строят сами из реплик: название берут из cue.text, время из cue.startTime. Идентификатор реплики, например intro, хорошо подходит для якоря.

WebVTT
WEBVTT

intro
00:00:00.000 --> 00:00:02.000
Вступление

main
00:00:02.000 --> 00:00:05.000
Главное
JavaScript
const cues = video.textTracks[0].cues;

for (const cue of cues) {
  const item = document.createElement("li");
  item.textContent = cue.text;
  item.onclick = () => (video.currentTime = cue.startTime);
  list.append(item);
}

Пример: главы из дорожки тега track kind chapters

Результат

Список построен из реплик файла с главами. Нажатие на главу перематывает видео, а текущая глава подсвечивается по ходу ролика.

Список строят после события load у тега track, иначе cues окажется пустым или null. Тот же приём работает для kind="metadata": в текст реплики записывают любые данные, например подсказку или номер слайда, а скрипт читает их в нужный момент. У metadata с default режим hidden включается сам.

Тег track в CSS: стили реплик через ::cue

Реплики рисует браузер, поэтому тег track стилизуют не напрямую, а псевдоэлементом ::cue у video.

Правило video::cue меняет все реплики, ::cue(b) — только текст внутри тега b, а ::cue(.hot) — только то, что записано как <c.hot>. Положение реплики задаётся в файле, размер шрифта растёт вместе с шириной видео.

ПравилоЧто получаетсяПример записи
colorЦвет текста репликиcolor: #FFD166
backgroundЦвет плашки под текстом, transparent убирает еёbackground: #0B6E6E
font-size и font-familyРазмер и шрифтfont-size: 24px
opacityРеплика бледнееopacity: .5
::cue(b)Только текст в теге bcolor: #FF6B6B
::cue(.hot)Только <c.hot>color: #FF6B6B
::cue(v[voice])Реплики одного говорящего из <v Anna>color: #FF6B6B

Пример: стили тега track через ::cue

Результат

Видео остановлено на второй секунде, в реплике есть тег b и класс hot. Кнопки подключают правила ::cue к настоящей дорожке, под видео показано действующее правило.

Не все свойства ::cue принимает: стандарт ограничивает набор, поэтому отступы и рамку у реплики лучше не задавать. Если нужен полностью свой вид, дорожку включают в режиме hidden и выводят текст в отдельный блок страницы (об этом рассказано в разделе про JavaScript).

Почему тег track не работает: загрузка, CORS и MIME

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

ПричинаЧто видноЧто сделать
Файла по адресу нетreadyState тега равен 3, приходит error, реплик 0Открыть адрес в браузере и проверить путь
В файле нет строки WEBVTTТо же: 3 и ни одной репликиЗаписать WEBVTT первой строкой
Время записано через запятую, как в SRTФайл принят, но такие реплики пропали без ошибкиЗаменить запятую на точку
Файл на другом домене, у video нет crossoriginБраузер не обращается к серверу, в консоли ошибка Unsafe attempt…Записать на video атрибут crossorigin="anonymous"
Другой домен не разрешает доступНет заголовка Access-Control-Allow-Origin: запрос идёт, но браузер блокирует ответ по правилам CORSВключить заголовок на сервере с файлом
Страница открыта как файл с диска, file://Браузер не загружает дорожку, readyState равен 3Открывать страницу через локальный сервер
Дорожка не включенаРежим disabled, файл не запрашивалсяЗаписать default или track.mode = "showing"
Два default одного видаРаботает первая, вторая остаётся disabledОставить один default
Вид chapters, descriptions или metadataРеплики загружены, но на экран не выводятсяИспользовать subtitles или captions
Неверный Content-Type у файлабраузер может принять файлы и с типами text/plain, text/html, application/octet-stream или без типа, но другие браузеры могут отказатьОтдавать text/vtt

Состояние загрузки читают у самого тега: readyState равен 0, пока файл не нужен, 2 — когда он загружен, 3 — при ошибке.

JavaScript
const tag = document.querySelector("track");

tag.addEventListener("load", () => console.log("готово"));
tag.addEventListener("error", () => console.log(tag.readyState));

Консоль браузера открывается клавишей F12, а вкладка сети покажет, было ли обращение к файлу .vtt и какой ответ пришёл.

Частые ошибки с тегом track

Основные ошибки связаны с видом дорожки, форматом файла времени и ожиданием, что браузер сам всё включит.

ОшибкаЧто происходитКак исправить
</track>Закрывающий тег не нужен, браузер его игнорируетЗаписать только <track src="ru.vtt">
<div><track></div>Вне video и audio тег дорожку не создаётПеренести внутрь video или audio
kind="subtitle"Опечатка превращает дорожку в metadata, субтитров нетЗаписать subtitles
kind="subtitles"Нет srclang: дорожка работает, но язык пустой, а стандарт его требуетДобавить srclang="ru"
<track src="ru.vtt">Нет default: дорожка выключена, пока читатель не выберет её в менюДобавить default для основной дорожки
Файл .vtt без строки WEBVTTБраузер отвергает файл, реплик нетЗаписать заголовок первой строкой
00:00:01,000Запятая вместо точки: реплика пропадает без ошибкиЗаписать 00:00:01.000
kind="chapters"Ждут, что главы появятся на экране, а браузер их не выводитПостроить список глав скриптом
track.cues.lengthСразу после добавления тега cues равен null или пуст, чтение length даёт ошибкуЧитать после события load
Два default одного видаВключается только первая дорожкаОставить один
Файл на чужом домене без crossoriginБраузер блокирует загрузку, дорожка не появляетсяЗаписать crossorigin="anonymous" и включить CORS
Расшифровка для звука только в .vttТекст не входит в страницу, читатель его не увидитВывести реплики скриптом и продублировать текст на странице
Категория
Поделиться в социальных сетях

Отправить комментарий

0 Комментарии

Отправить комментарий (0)

#buttons=(Хорошо) #days=(20)

Мы используем файлы cookie для улучшения работы сайта. Подробнее
Хорошо
×