Чтение метаданных из 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 9

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 (Ну, технически a TextTrackCueList.) До того, как произойдет загрузка, свойство 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?