Как генерировать миниатюры из видео, которое приходит от JSON? - PullRequest
0 голосов
/ 23 июня 2019

У меня есть простая боковая панель, которая содержит видео из JSON, у каждого видео есть кнопка редактирования, теперь, когда вы нажимаете кнопку редактирования, открывается модал, содержащий видео.

Вот рабочая демонстрация живая демонстрациябез thumbanails

Теперь я хочу, чтобы, когда пользователь нажимает кнопку «Изменить», он отображал видео в том виде, в каком он есть сейчас, и автоматически генерирует миниатюры из видео.

Вот что я пробовал до сих пор:

HTML


<ul class="sidebar"></ul>

<div id="myModal" class="modal">
    <!-- Modal content -->
    <div class="modal-content">
        <h1 id="modalTitle"></h1>
        <span class="close">&times;</span>
        <div id="modalVideo"></div>
        <canvas id="canvas" width="750px" height="540px"></canvas>
        <div id="screenShots"></div>
    </div>
</div>

JS


$(function() {
    var movies = [{
        "title": "travel",
        "left": 201,
        "top": 209,
        "movieid": "10",
        "movie_url": "http://techslides.com/demos/sample-videos/small.mp4",
        "buttons": [{
            "left": 81,
            "top": 51,
            "start_time": 1,
            "end_time": 2,
            "buttonid": "10_1",
            "btn_url": "http://techslides.com/demos/sample-videos/small.mp4"
        }]
    },{
        "title": "ecommerce",
        "movieid": "20",
        "movie_url": "http://techslides.com/demos/sample-videos/small.mp4",
        "buttons": [{
            "left": 0,
            "top": 0,
            "start_time": 1,
            "end_time": 2,
            "width": '200',
            "height": '60',
            "buttonid": "20_1",
        }]
    }];

    function formatTitle(t) {
        var nt = t[0].toUpperCase();
        nt += t.slice(1);
        return nt;
    }

function makeListItem(v, p) {
    var li = $("<div id='" + v.movieid + "' class='sidebar_movie-block'>");
    var title = $("<h1>", {
        class: "title",
        for: "video_" + v.movieid
    }).html(formatTitle(v.title)).appendTo(li);
    var edit = $("<span>", {
        class: "block-edit fa fa-edit",
        for: "video_" + v.movieid,
    }).appendTo(li);
            var vObj = $("<video>", {
                    id: "video_" + v.movieid,
                    controls: "",
                    src: v.movie_url
            }).appendTo(li);
            li.appendTo(p);
    }
    function getVideoList() {
            $.each(movies, function(index, dataValue) {
                    makeListItem(dataValue, $(".sidebar"));
            });
    }
    getVideoList();
    var modal = $("#myModal");

    // When the user clicks the button, open the modal 
    $(".block-edit").on("click", function(obj) {
            var main = $(obj.target).parent();
            var video = $(main).find("video");
            var title = $(main).find(".title");

            $("#myModal").css("display", "flex");

            $("#modalVideo")[0].innerHTML = video[0].outerHTML
            $("#modalTitle").text($("h1[for='" + video[0].id + "']").text());
            video.addEventListener("loadedmetadata", initScreenshot);
            video.addEventListener("playing", startScreenshot);
            video.addEventListener("pause", stopScreenshot);
            video.addEventListener("ended", stopScreenshot);

            var canvas = document.getElementById("canvas");
            var ctx = canvas.getContext("2d");
            var ssContainer = document.getElementById("screenShots");
            var videoHeight, videoWidth;
            var drawTimer = null;

            function initScreenshot() {
                    videoHeight = video.videoHeight;
                    videoWidth = video.videoWidth;
            }

            function startScreenshot() {
                    if (drawTimer == null) {
                            drawTimer = setInterval(grabScreenshot, 1000);
                    }
            }
                function stopScreenshot() {
                            if (drawTimer) {
                                    clearInterval(drawTimer);
                                    drawTimer = null;
                            }
                    }

                    function grabScreenshot() {
                            if (Math.round($("video")[0].currentTime) % 5 != 0) return; //only draw if its a 5th second!!!
                            console.log("generating thumbnail");
                            ctx.drawImage(video, 0, 0, videoWidth, videoHeight);
                            var img = new Image();
                            img.src = canvas.toDataURL("image/png");
                            img.width = 120;
                            ssContainer.appendChild(img);
                            console.log('one');
                    }
            })

            // When the user clicks on <span> (x), close the modal
            $(".close").on("click", function() {
                    $("#myModal").css("display", "none");
            })

        // When user clicks anywhere outside of the modal, close it
        window.onclick = function(event) {
            if (event.target == modal) modal.style.display = "none";
        }
    });

Вот скрипка с генерацией миниатюр Демо-версия не работает при генерации миниатюр .

К сожалению, я получаю следующую ошибку.

> app.js:484 Uncaught TypeError: Cannot read property 'addEventListener' of null
    at HTMLSpanElement.<anonymous> (app.js:484)
    at HTMLSpanElement.dispatch (jquery.min.js:2)
    at HTMLSpanElement.v.handle (jquery.min.js:2)

Для справки примерно вот так: Демонстрация миниатюр с точки сайта

Что не так с моими кодами

1 Ответ

1 голос
/ 23 июня 2019

Ваша проблема в том, что video является элементом jQuery, у которого нет метода addEventHandler.Вместо этого используйте video.on('event', function).

В качестве альтернативы, вы можете получить элемент html, используя video[0].addEventHandler

Дополнительные проблемы в вашем коде возникают из-за смешивания элементов jQuery с базовыми элементами html.А именно, что videoHeight и videoWidth являются свойствами базового элемента, и базовый элемент необходимо передать в ctx.drawImage.

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