Чтение метаданных из <track>HTML5 <video>с использованием Captionator - PullRequest
9 голосов
/ 21 февраля 2012

У меня проблемы с получением рабочего примера, который читает метаданные из файла WebVTT, который был указан элементом <track> элемента <video> на странице HTML5.Чтобы было ясно, я не говорю о считывании метаданных из самого видеофайла (как, например, в случае с транспортным потоком MPEG).Я имею в виду элемент <track>, который используется для подписи видео.Одним из атрибутов <track> является kind, который может быть задан как любое из следующих значений:

  • Субтитры
  • Описания
  • Подписи
  • Навигация
  • Главы
  • Метаданные

Я пытаюсь использовать тип метаданные для доступа к тексту, хранящемуся в соответствующемФайл WebVTT, которым я намерен манипулировать с помощью JavaScript.Я знаю, что это возможно, так как это , упомянутое Сильвией Пфайфер , а также создателем Captionator , который является полифиллом JavaScript, который я использую для реализации функциональности интерпретации<track> тегов.Однако я просто не могу заставить его работать.

Мой код основан на примере заголовков документации Captionator .Я добавил кнопку для извлечения метаданных и отображения их при нажатии кнопки.К сожалению, он продолжает отображать «неопределенный» вместо метаданных.Есть идеи, что я могу делать неправильно?Кроме того, кто-нибудь знает, где рабочий пример, на который я мог бы взглянуть?Я нигде не могу его найти.

Если вы хотите посмотреть на мой код, я включил его ниже:

<!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 ]

11 голосов
/ 22 февраля 2012

Правильный способ доступа к метке - никаких проблем нет (хотя в Captionator 0.6 будет изменено свойство .tracks на свойство .textTracks, чтобы оно больше соответствовало спецификации. Если вы может нести случайную ошибку, я бы порекомендовал использовать 0,6 для более строгого соответствия стандартам - я написал следующий код для использования .textTracks - замените .tracks, если вы хотите продолжать использовать стабильную ветвь.)

Проблема связана с загрузкой самих текстовых дорожек. На данный момент вы на самом деле не говорите Captionator загрузить трек . Поскольку это происходит асинхронно, и по запросу существует неизбежная задержка, когда их содержимое недоступно, вам нужно будет написать свой код так, чтобы он соответствовал времени загрузки и потенциальной ошибке загрузки.

Вы также не ожидаете загрузки самого Captionator - потенциально пользователь может неосознанно нажать кнопку до того, как это произошло, что вызовет неприятную ошибку JavaScript. Это не будет такой проблемой при тестировании на вашем локальном компьютере, но как только вы развернетесь в Интернете, вы увидите все виды условий гонки и другие неприятности. Попробуйте отключить кнопку до тех пор, пока не будут загружены данные страницы и подписи.


Я пытался сделать API-интерфейс Captionator максимально приближенным к реальному JS-API, который очень скоро появится в браузерах - поэтому в будущем это будет таким же образом, как вы будете взаимодействовать с собственными функциональными возможностями браузера. Как только функциональность станет доступна изначально, Captionator прекратит работу, и ваш код должен (при условии, что они не изменят API снова!) Просто работать с собственным API.

Прежде всего, вам нужно запросить, чтобы Captionator загрузил контент. Это сделано, установив «режим отображения» трека на SHOWING или 2.

var video = document.getElementByID("myVideo");
video.textTracks[0].mode = 2; // SHOWING

В качестве альтернативы, вы можете присвоить статус дорожки HIDDEN (1) - что все еще вызывает загрузку, и события cueChange будут по-прежнему срабатывать - но не будут отображать подсказки на экране. В Captionator я вообще не рисую дорожки метаданных на экране, но (глючный) API WebKit в разработке.

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 (ну, технически TextTrackCueList.) До того, как загрузка произошла, свойство TextTrack.cues будет null.

var myCueText = video.textTracks[0].cues[0].text;

Имейте в виду, что Captionator анализирует текст реплики каждой реплики, , за исключением случаев, когда тип дорожки равен 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 или дорожка метаданных будут готовы, и прослушивать событие загрузки - в какой момент мы снова включаем кнопку и можем получить текст подсказки в обычном режиме.

1 голос
/ 21 февраля 2012

Вам может потребоваться загрузить файл 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?

...