javascript - 如何从来自 json 的视频生成缩略图?

标签 javascript jquery html html5-canvas html5-video

我有一个简单的侧边栏,其中包含来自 JSON 的视频,每个视频都有一个编辑按钮,现在当您单击编辑按钮时,会打开一个包含视频的模式。

这是一个工作演示 live demo without 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";
        }
    });

这是生成缩略图的摆弄live demo not working generating thumbnails .

不幸的是,我收到以下错误。

> 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)

供引用: Thumbnails demo from the site point

我的代码有什么问题吗?

最佳答案

您的问题是 video 是一个 jQuery 元素,它没有 addEventHandler 方法。请改用 video.on('event', function)

或者,您可以使用 video[0].addEventHandler

获取 html 元素

代码中的其他问题来自于将 jQuery 元素与基本 html 元素混合。即videoHeightvideoWidth是base元素的属性,base元素需要传递给ctx.drawImage

关于javascript - 如何从来自 json 的视频生成缩略图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56719688/

相关文章:

html - 无法将 margin 应用于 div

javascript - 为什么我的卡在使用 bootstrap 时没有响应?

javascript - 动态 Accordion 菜单

jquery - 如何使用 jQuery 在 Stripes 按钮上添加图标

html - 属性不再被视为节点了吗?

php - 如何创建带预览的图像 uploader

javascript - 当可以通过 JS 或 CSS 完成某件事时,我应该选择哪种方式?

javascript - 如何全局安装节点模块?

javascript - jQuery 在更改值时设置字体大小奇怪的行为

javascript - 禁用和启用选中复选框的按钮