Чтение метаданных из HTML5 с помощью Captionator
У меня возникли проблемы с получением рабочего примера, который считывает метаданные из файла WebVTT, который был указан элементом <track>
элемента <video>
на странице HTML5. Чтобы быть ясным, я не говорю о считывании метаданных из самого видеофайла (как это было бы с транспортным потоком MPEG, например). Я говорю об элементе <track>
, который используется для субтитров видео. Одним из атрибутов a <track>
является kind
, который может быть определен как любой из следующих значения:
- субтитры
- описания
- подписи
- навигация
- главы
- метаданные
Я пытаюсь использовать тип метаданных для доступа к тексту, хранящемуся в соответствующем файле WebVTT, которым я намерен управлять с помощью JavaScript. Я знаю, что это возможно, так как это упомянуто Сильвией Пфайффер , а также создателем Captionator , который является полифиллом JavaScript, который я использую, чтобы реализуйте функциональность интерпретации тегов <track>
. Однако я просто не могу заставить его работать.
Мой код основан на примере субтитровCaptionator документации. Я добавил кнопку для извлечения метаданных и отображения их при нажатии на кнопку. К сожалению, он продолжает отображать "undefined" вместо метаданных. Есть идеи, что я могу делать неправильно? Кроме того, кто-нибудь знает, где находится рабочий пример, на который я мог бы взглянуть? Я не могу его найти. везде.
Если вы хотите взглянуть на мой код, я включил его ниже:
<!DOCTYPE html>
<html>
<head>
<title>HTML5 Video Closed Captioning Example</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" media="screen" href="js/Captionator-v0.5-12/css/captions.css"/>
</head>
<body>
<h1>HTML5 Video Closed Captioning Example</h1>
<div>
<p id="metadataText">Metadata text should appear here</p>
<input type='button' onclick='changeText()' value='Click here to display the metadata text'/>
</div>
<video controls autobuffer id="videoTest" width="1010" height="464">
<source src="http://localhost:8080/Videos/testVideo.webm" type="video/webm" />
<source src="http://localhost:8080/Videos/testVideo.mp4" type="video/mp4" />
<!-- WebVTT Track Metadata Example -->
<track label="Metadata Track" kind="metadata" src="http://localhost:8080/Videos/Timed_Text_Tracks/testVideo_metadata.vtt" type="text/webvtt" srclang="en" />
</video>
<!-- Include Captionator -->
<script type="text/javascript" src="js/Captionator-v0.5-12/js/captionator.js"></script>
<!-- Example Usage -->
<script type="text/javascript" src="js/Captionator-v0.5-12/js/captionator-example-api.js"></script>
<script type="text/javascript">
window.addEventListener("load",function() {
captionator.captionify(null,null,{
debugMode: !!window.location.search.match(/debug/i),
sizeCuesByTextBoundingBox: !!window.location.search.match(/boundingBox/i),
enableHighResolution: !!window.location.search.match(/highres/i),
});
var videoObject = document.getElementsByTagName("video")[0];
videoObject.volume = 0;
document.body.appendChild(generateMediaControls(videoObject));
},false);
function changeText() {
document.getElementById('metadataText').innerHTML = testVar;
var cueText = document.getElementById("video").tracks[0].activeCues[0].getCueAsSource();
document.getElementById('metadataText').innerHTML = cueText;
}
</script>
</body>
</html>
Мой файл WebVTT выглядит так:
WEBVTT
0
00:00.000 --> 00:04.000
Testing 1 2 3 . . .
2 ответа:
Способ доступа к cue правильный - никаких проблем нет (хотя в Captionator 0.6 будет изменено свойство
.tracks
на свойство.textTracks
, чтобы быть более соответствующим спецификации. Если вы можете переносить случайные ошибки, я бы рекомендовал использовать 0.6 для большего соответствия стандартам - я написал ниже код для использования.textTracks
- замените.tracks
, Если вы хотите продолжать использовать стабильную ветвь.)Проблема связана с загрузкой текстовых дорожек самих себя. На данный момент Вы на самом деле не говорите Captionator загрузить трек. Поскольку это происходит асинхронно, и по запросу возникает неизбежная задержка, когда их содержимое недоступно, вам нужно будет написать свой код таким образом, чтобы он соответствовал времени загрузки и потенциальной ошибке загрузки.
Вы также не ждете загрузки самого Captionator-потенциально пользователь может бессознательно нажать кнопку, прежде чем это произойдет-запуск неприятного ошибка JavaScript. Это не будет такой проблемой при тестировании на локальном компьютере, но как только вы развернетесь в интернете, вы увидите всевозможные условия гонки и другие неприятности. Рассмотрите возможность отключения кнопки до тех пор, пока не загрузятся данные о странице и заголовке.
Я постарался сделать API Captionator как можно ближе к фактическому API JS, который очень скоро появится в браузерах - так что в будущем это будет таким же образом, как вы будете взаимодействовать с собственным браузером функциональность. Как только функциональность будет доступна изначально, Captionator откланяется, и ваш код должен (при условии, что они не изменят API снова!) просто работайте с собственным API.
Прежде всего, вам нужно на самом деле запросить, чтобы Captionator загрузил содержимое. Это делается с помощью настройки "режима отображения" дорожки на
SHOWING
или2
.var video = document.getElementByID("myVideo"); video.textTracks[0].mode = 2; // SHOWING
Кроме того, вы можете присвоить статус трека
HIDDEN
(1
) - который все еще вызывает a загружайте, и события cueChange будут по - прежнему срабатывать-но не будут рисовать сигналы на экране. В Captionator я вообще не рисую треки метаданных для экрана, но (багги) webkit API в разработке будет.video.textTracks[0].mode = 1; // HIDDEN
Тогда вам нужно слушать, когда сигналы загружены и доступны:
video.textTracks[0].onload = function() { /* Your Code Here... */ }
Или когда что-то идет не так:
video.textTracks[0].onerror = function() { /* Whoah, something went wrong... */ }
Как только содержимое загружено, вы можете получить доступ к массиву
TextTrack.cues
(Ну, технически aTextTrackCueList
.) До того, как произойдет загрузка, свойствоTextTrack.cues
будетnull
.var myCueText = video.textTracks[0].cues[0].text;
Имейте в виду, что Captionator анализирует текст cue каждого cue, , за исключением случаев, когда вид дорожки
metadata
- поэтому убедитесь, что вы назначили правильный вид дорожки. Вы можете в конечном итоге получить данные или теги, которые Captionator считает "недопустимыми". Вы также можете отключить этот флажок для регулярных сигналов, установив опциюprocessCueHTML
вfalse
.
Имея это в виду, вот как я перепишу ваш код:
<div> <p id="metadataText">Metadata text should appear here</p> <input type='button' onclick='changeText()' value='Click here to display the metadata text' id="changetext" disabled /> </div> <video controls autobuffer id="videoTest" width="512" height="288"> <!-- Your video sources etc... --> <!-- The metadata track --> <track label="Metadata Track" kind="metadata" src="metadata.vtt" type="text/webvtt" srclang="en" /> </video> <!-- Include Captionator --> <script type="text/javascript" src="captionator.js"></script> <script type="text/javascript"> document.addEventListener("readystatechange",function(event) { if (document.readyState === "complete") { captionator.captionify(); document.querySelectorAll("#changetext")[0].removeAttribute("disabled"); } },false); function changeText() { // Get the metadataText paragraph var textOutput = document.querySelectorAll("#metadataText")[0]; // Get the metadata text track var metadataTrack = document.querySelectorAll("video")[0].textTracks[0]; if (metadataTrack.readyState === captionator.TextTrack.LOADED) { // The cue is already ready to be displayed! textOutput.innerHTML = metadataTrack.cues[0].text; } else { // We check to see whether we haven't already assigned the mode. if (metadataTrack.mode !== captionator.TextTrack.SHOWING) { textOutput.innerHTML = "Caption loading..."; // The file isn't loaded yet. Load it in! metadataTrack.mode = captionator.TextTrack.SHOWING; // You can use captionator.TextTrack.HIDDEN too. metadataTrack.onload = function() { textOutput.innerHTML = metadataTrack.cues[0].text; } metadataTrack.onerror = function() { textOutput.innerHTML = "Error loading caption!"; } } } } </script>
Здесь мы отключаем кнопка, препятствующая пользователям на медленных соединениях (или просто кому-то с очень быстрыми рефлексами!) от нажатия на нее до того, как будут готовы Captionator или дорожка метаданных, и прослушивания события загрузки - в этот момент мы снова включаем кнопку и можем получить текст подсказки как обычно.
Возможно, вам потребуется загрузить файл метаданных VTT через Ajax и проанализировать его и отобразить самостоятельно.
Я посмотрел на Пример из статьи HTML5 Doctors о субтитрах видео. Они используют Playr , поэтому я проверил его исходный код, и они определенно запрашивают файл VTT асинхронно и анализируют содержимое после его загрузки.
Я смог загрузить содержимое файла VTT и сбросить его в указанный элемент с помощью следующего код:
function changeText() { var track = document.getElementById("videoTest").querySelector("track"); var req_track = new XMLHttpRequest(); req_track.open('GET', track.getAttribute("src")); req_track.onreadystatechange = function(){ if(req_track.readyState == 4 && (req_track.status == 200 || req_track.status == 0)){ if(req_track.responseText != ''){ document.getElementById("metadataText").innerHTML = req_track.responseText; } } } req_track.send(null); }
Я не знаком с Captionator, но похоже, что он имеет некоторые возможности для разбора файлов VTT в некоторую структуру данных, даже если он не обязательно поддерживает тип дорожки
metadata
. Может быть, вы можете использовать комбинацию этого кода и существующего VTT-парсера Captionator?