Как создать видеокадр с точностью до кадра с HTML5 <video>? - PullRequest
5 голосов
/ 08 января 2011

Я пытаюсь создать видеопоследователь, способный воспроизводить список URL-адресов видео последовательно. Между видео не должно быть разрыва; воспроизведение должно быть максимально приближенным к кадру.

Попытка # 1 Я использовал довольно очевидный и простой подход, подобный тому, который упоминался в этой теме. HTML 5 видео или аудио плейлист

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

Попытка № 2 Я переписал сценарий, чтобы каждое видео в списке приводило к созданию отдельного элемента видео, но не к документу (с использованием createElement). Затем, когда закончилось каждое видео, я удалил предыдущий узел и добавил следующий элемент.

Код, выполняемый при загрузке страницы:

for (i in timelinePlay)
    if (timelinePlay[i] != null)        
    {
        var element = document.createElement('video');
        element.id = 'video1-' + (i);
        element.src = timelinePlay[i]['URL'];
        element.preload = 'load';
        video1Array[i] = element;
    }

Код для события «закончилась» видео:

videoElement.addEventListener("ended", function (event) {
    if (this.currentTime > 0)
    {
        if (player.hasChildNodes())
            while (player.childNodes.length > 0)
                player.removeChild(player.firstChild);

        player = document.getElementById('canvas-player');
        player.appendChild(video1Array[timelineCurrent]);

        nextVideo = document.getElementById('video1-' + timelineCurrent);

        nextVideo.play();

        timelineCurrent++;
    }
}, false);

(Обратите внимание, что эти примеры кода являются частичными и несколько упрощенными. Кроме того, я понимаю, что использование объектов в качестве ассоциативных массивов не является наилучшей практикой)

Результат этой модификации был НАМНОГО ближе, потому что видео были загружены к тому времени, когда они были необходимы для воспроизведения, но между видео все еще был короткий и непоследовательный разрыв.

Попытка № 3 Я заменил прослушиватель события «конец» на прослушиватель «время обновления», начиная со следующего:

nextVideo.addEventListener("timeupdate", function (event)
{
    if (this.currentTime > (this.duration - 0.1)  && this.currentTime > 1)
    {
        this.removeEventListener("timeupdate", function () { return; }, false);

('this.currentTime> 1' просто для гарантии того, что предыдущее видео действительно воспроизводится)

Я надеялся, что разрыв между видео был достаточно близок к тому, чтобы быть постоянным, что запуск следующего видео за произвольные 0,1 секунды до его окончания исправил бы разрыв в приемлемой степени. Результатом было то, что время было действительно лучше, но оно пропускало видео. Я связываю пропущенные видео с пропуском события timeupdate, но могу ошибаться.

Другие альтернативные варианты, которые я также рассмотрел: Сценарий SMIL (кажется, устарел, и в любом случае, вероятно, будет иметь те же проблемы синхронизации) ffmpeg в бэкэнде для объединения видео (мой хост не разрешает сценарии оболочки)

FYI Я сейчас разрабатываю для Safari 5.0.3

Ответы [ 3 ]

3 голосов
/ 08 ноября 2012

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

Вместо родного тега видео я использую jwplayer на нескольких видеоэлементах. При запуске все элементы начинают играть одну секунду, ставятся на паузу и возвращаются в ноль. Затем один за другим воспроизводится и становится видимым с помощью display: block.

<ul class="playlist">
    <li>
        <video class="playlist" id="vid01" poster="img/preview.jpg">
            <source src="vid/v01.mp4" type="video/mp4">
        </video>
    </li>
    <li>
        <video class="playlist" id="vid02" poster="img/preview.jpg">
            <source src="vid/v02.mp4" type="video/mp4">
        </video>
    </li>
    <li>
        <video class="playlist" id="vid03" poster="img/preview.jpg">
            <source src="vid/v03.mp4" type="video/mp4">
        </video>
    </li>
    <li>
        <video class="playlist" id="vid04" poster="img/preview.jpg">
            <source src="vid/v04.mp4" type="video/mp4">
        </video>
    </li>
</ul>

При добавлении на сцену «предварительно загрузить» видео одну или две секунды: (Отрывок)

var isPrebuffering = false,
    isSeeking = false;

$player = jwplayer(videoId).setup({
    width: '800px',
    height: '450px',
    autoplay: false,
    modes: [
        { type: 'html5' }
    ],
    events: {
        onReady: function(e) {
            prebuffer();
        },
// There is a quirk in jwplayer that makes it impossible to pause at the 
// new position directly after seeking. So we have to work around that.
        onTime: function(e) {
            if((e.position > 1.0 && isPrebuffering) || isSeeking) {
                finishPrebuffering();
            }
        }
    }
});

function prebuffer() {
    isPrebuffering = true;
    $player.setMute(true);
    $player.play();
};

function finishPrebuffering() {
    if(isPrebuffering) {
        isPrebuffering = false;
        isSeeking = true;
        $player.seek(0);
    }

    if($player.getPosition() === 0) {
        isSeeking = false;
        $player.pause();
        $player.setMute(false);
    }
};
0 голосов
/ 19 февраля 2013

Возможно, вы сможете сделать это с http://popcornjs.org/. Они обеспечивают JS-хуки на уровне кадра за кадром в видео с помощью тега html5 video. Есть много событий и т. Д.

0 голосов
/ 08 января 2011

Интерфейс mediaElement в HTML5 может иногда вызывать путаницу между предварительной загрузкой, загрузкой и буферизацией.Но пытались ли вы добавить в ваше видео событие, например, за 3 секунды до его окончания?Затем в ajax попробуйте загрузить следующее видео в новом div.По окончании события вашего видео вы можете переключить div, поэтому ваше следующее видео будет достаточно загружено для воспроизведения.И так далее для следующих видео.

http://www.w3.org/TR/html5/video.html#media-elements

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...