Подождите, пока видео загрузится, чтобы сделать снимок как изображение - PullRequest
0 голосов
/ 08 ноября 2018

Я работаю над сценарием, который возьмет видео в формате mp4 и создаст снимок первого кадра. Цель этого заключается в том, что некоторые мобильные браузеры не воспроизводят mp4 при загрузке. Он покажет mp4 с кнопкой воспроизведения. Поэтому создание снимка будет хорошим запасным вариантом для мобильных устройств.

У меня уже есть базовый фрагмент кода, и он работает 70% времени. Однако, когда он не работает, я думаю, что у меня возникают проблемы со сценарием, пытающимся сделать снимок из кэшированное видео или оно пытается захватить до полной загрузки видео. У кого-нибудь есть предложения как сделать это на 100%? Я попытался отложить строки кода, чтобы подождать, пока все загрузится, но иногда это не работает .... Что немного помогло, так это добавление небольшого setTimeOut ...

( function( window, $ ) {

const document = window.document;

const ImgSnapshot = (el) => {
    //setup variables
    const $el    = $(el);
    const video = $el.find(".wave-animation__container").get(0);

    $(video).ready( () => {

        setTimeout(() => {

            function createCanvas(){


                //create a canvas obj
                let canvas = document.createElement("canvas");
                canvas.width = video.videoWidth;
                canvas.height = video.videoHeight;
                canvas.getContext('2d')
                    .drawImage(video, 0, 0, canvas.width, canvas.height);

                //wait until we have the canvas object captured
                return $.Deferred().resolve( canvas ).promise();
            }

            createCanvas().done( ( canvas ) => {
                   //create an image element to append
                   let img = document.createElement("img");
                   img.src = canvas.toDataURL();
                   img.classList.add('hide-for-medium', 'snapshot');

                   $el.append(img);

                   video.classList.add( 'show-for-medium' );
               });
           }, 150);



       });

   };


    $(document).ready(function(){
        $('.js-wave-animation').each(function(){
            new ImgSnapshot(this);
        });

    });

} )( window, jQuery );

1 Ответ

0 голосов
/ 25 декабря 2018

У меня другой подход к этой проблеме. Вместо использования deferred объектов для проверки загрузки видео, как насчет использования media events из video

<video width="400" controls id="myvideo">
    <source src="" type="video/mp4">
</video>
<script type="text/javascript">
    var jqvideo = $("#myvideo");
    var video = jqvideo[0];
    video.addEventListener("loadeddata", function() { 
        console.log("loaded");
        let canvas = document.createElement("canvas");
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
        let img = document.createElement("img");
        img.src = canvas.toDataURL();
        $("body").append(img);
    }, true);
    jqvideo.find("source").attr("src", "yourvideourl.mp4");
</script>
...