js 实现浏览器端进行视频剪辑合并裁剪等功能

js 实现浏览器端进行视频剪辑合并裁剪等功能

js 实现浏览器端进行视频剪辑合并裁剪等功能

以前视频转换我们需要下载软件进行转换,有些还是收费的,或者在服务器端进行ffmpeg压缩转换,那么能不能再浏览器中直接进行视频编辑转换压缩呢,html5给了我们一个答案,能,现在ffmpeg推出了js版本ffmpeg.js ,可以在线进行视频压缩编辑处理,是不是很强大呢

今天我们来演示一下如何通过ffmpeg.js进行浏览器端视频编辑压缩处理,今天我们需要用到html5中的work特性来进行后台压缩

可以点击右上角在线编辑运行按钮预览效果,注意,由于ffmpeg.js很大,有22M,所以需要加载一段时间

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>videoconverter.js - 浏览器视频转换</title>
    <style type="text/css">
        #terminal {
            background: #fff;
            color: #000;
            font-family: "Lucida Console", "Lucida Sans Typewriter", Monaco, "Bitstream Vera Sans Mono", monospace;
            font-weight: lighter;
            border: solid 1px;
            padding: 10px;
            margin-top: 35px;
        }
        .terminal-top-bar {
            background: rgb(233, 233, 233);
            height: 14px;
            font-size: 12px;
            line-height: 14px;
            margin-top: -30px;
            margin-left: -11px;
            margin-right: -11px;
            padding: 3px;
            text-align: center;
            color: rgb(92, 92, 92);
            border: solid 1px;
            border-radius: 2px 2px 0 0;
        }
        .terminal-header {
            padding-top: 15px;
        }
        #input {
            width: 80%;
            padding: 4px;
        }
        #run {
            width: 15%
        }
        #output {
            white-space: pre-wrap;
            word-break: break-all;
        }
        #output.closed {
            max-height: 200px;
            overflow-y: scroll;
        }
        #files {
            text-align: center;
        }
        #files img {
            max-width: 80%;
        }
        .sample-commands {
            text-align: center;
        }
    </style>
</head>
<body>

    <div class="container-fluid">
        <div class='content'>
            <div class='inner-content'>
                <div class="header clearfix">
                    <div class="pull-left">
                        <H1>在线js视频格式转换截图翻转编辑ffmpeg等操作
                        </H1>
                    </div>

                </div>

                <div class="clearfix">
                    <p>
                        待转换的视频
                    </p>
                    <video src="/bfwrepo/video/bigbuckbunny.webm" width="100%" autoplay="autoplay" controls="controls"></video>
                    <p>
                        待处理的图片
                    </p>
                    <img src="/bfwrepo/image/bigbuckbunny.jpg" width="100%" />

                    <!--<p>-->
                    <!--    选择视频<input type="file" accept="video/*" id="videoselect" />-->
                    <!--</p>-->

                    <div class="sample-commands">
                        <button class="plain-button sample" data-command="-help">帮助</button>

                        <button class="plain-button sample" data-command="-codecs">所有编码</button>

                        <button class="plain-button sample" data-command="-i input.jpeg -vf vflip output.jpeg"> 垂直翻转图片</button>

                        <button class="plain-button sample" data-command="-i input.jpeg -vf hflip output.jpeg"> 水平翻转图片</button>

                        <button class="plain-button sample" data-command="-i input.webm -vf showinfo -strict -2 output.mp4">在线视频转mp4格式</button>

                        <button class="plain-button sample" data-command="-t 5 -i input.webm -vf showinfo -strict -2 output.gif">在线视频转gif格式</button>

                        <button class="plain-button sample" data-command="-i input.webm -s 100x100 -f image2 -vf fps=fps=1,showinfo -an out%d.jpeg">视频截图</button>

                        <button class="plain-button sample" data-command="-i input.webm -vf"showinfo,drawbox=enable='between(n,0,60)' : x=10 : y=10 : w=50 : h=50 : color=red,drawbox=enable='gte(t,1)' : x=100 : y=100 : w=200 : h=200 : color=green" -strict -2 output.mp4">在视频上画个框</button>

                        <button class="plain-button sample" data-command="-t 3 -i input.webm -vf showinfo -strict -2 -c:v libx264 output.mp4">视频用H.264编码转换</button>

                        <button class="plain-button sample" data-command="-t 3 -i input.webm -vf showinfo -strict -2 -c:v libvpx-vp9 output.webm">视频用VP9编码转换</button>

                    </div>
                    <div id="terminal">
                        <div class="terminal-top-bar">
                            videoconverter.js
                        </div>
                        <div class="terminal-header">
                            <input id="input" value="-help" />
                            <button id="run" class="plain-button">执行ffmpeg命令</button>
                            <img id="image-loader" src="/bfwrepo/images/loading.gif" />
                        </div>
                        <pre id="output" style="height:100px;overflow:scroll;" >加载ffmpeg.js (很大,请稍后....)</pre>
                    </div>
                    <div id="files">

                    </div>
                </div>
            </div>
        </div>

    </div>

    <script>

        var worker;
        var sampleImageData;
        var sampleVideoData;
        var outputElement;
        var filesElement;
        var running = false;
        var isWorkerLoaded = false;
        var isSupported = (function() {
            return document.querySelector && window.URL && window.Worker;
        })();

        function isReady() {
            return !running && isWorkerLoaded && sampleImageData && sampleVideoData;
        }

        function startRunning() {
            document.querySelector("#image-loader").style.visibility = "visible";
            outputElement.className = "";
            filesElement.innerHTML = "";
            running = true;
        }
        function stopRunning() {
            document.querySelector("#image-loader").style.visibility = "hidden";
            running = false;
        }

        function retrieveSampleImage() {
            var oReq = new XMLHttpRequest();
            oReq.open("GET", "/bfwrepo/image/bigbuckbunny.jpg", true);
            oReq.responseType = "arraybuffer";

            oReq.onload = function (oEvent) {
                var arrayBuffer = oReq.response;
                if (arrayBuffer) {
                    sampleImageData = new Uint8Array(arrayBuffer);
                }
            };

            oReq.send(null);
        }

        function retrieveSampleVideo() {
            var oReq = new XMLHttpRequest();
            oReq.open("GET", "/bfwrepo/video/bigbuckbunny.webm", true);
            oReq.responseType = "arraybuffer";

            oReq.onload = function (oEvent) {
                var arrayBuffer = oReq.response;
                if (arrayBuffer) {
                    sampleVideoData = new Uint8Array(arrayBuffer);
                }
            };

            oReq.send(null);
        }

        function parseArguments(text) {
            text = text.replace(/\s+/g, ' ');
            var args = [];
            // Allow double quotes to not split args.
            text.split('"').forEach(function(t, i) {
                t = t.trim();
                if ((i % 2) === 1) {
                    args.push(t);
                } else {
                    args = args.concat(t.split(" "));
                }
            });
            return args;
        }


        function runCommand(text) {
            if (isReady()) {
                startRunning();
                var args = parseArguments(text);
                console.log(args);
                worker.postMessage({
                    type: "command",
                    arguments: args,
                    files: [{
                        "name": "input.jpeg",
                        "data": sampleImageData
                    },
                        {
                            "name": "input.webm",
                            "data": sampleVideoData
                        }]
                });
            }
        }

        function getDownloadLink(fileData, fileName) {
            if (fileName.match(/\.jpeg|\.gif|\.jpg|\.png/)) {
                var blob = new Blob([fileData]);
                var src = window.URL.createObjectURL(blob);
                var img = document.createElement('img');

                img.src = src;
                return img;
            } else {
                var a = document.createElement('a');
                a.download = fileName;
                var blob = new Blob([fileData]);
                var src = window.URL.createObjectURL(blob);
                a.href = src;
                a.textContent = '点击下载 ' + fileName + "!";
                return a;
            }
        }

        function initWorker() {
            worker = new Worker("/bfwrepo/js/worker-asm.js");
            worker.onmessage = function (event) {
                var message = event.data;
                if (message.type == "ready") {
                    isWorkerLoaded = true;
                    worker.postMessage({
                        type: "command",
                        arguments: ["-help"]
                    });
                } else if (message.type == "stdout") {
                    outputElement.textContent += message.data + "\n";
                } else if (message.type == "start") {
                    outputElement.textContent = "Worker has received command\n";
                } else if (message.type == "done") {
                    stopRunning();
                    var buffers = message.data;
                    if (buffers.length) {
                        outputElement.className = "closed";
                    }
                    buffers.forEach(function(file) {
                        filesElement.appendChild(getDownloadLink(file.data, file.name));
                    });
                }
            };
        }

        // document.querySelector("#videoselect").onchange = function() {
        //     // sampleVideoData = new Uint8Array(this.files[0]);
        //     var reader = new FileReader();
        //     //var fileByteArray = [];
        //     reader.readAsArrayBuffer(this.files[0]);
        //     reader.onloadend = function (evt) {
        //         if (evt.target.readyState == FileReader.DONE) {
        //             var arrayBuffer = evt.target.result,
        //             sampleVideoData = new Uint8Array(arrayBuffer);
        //             console.log(arrayBuffer);
        //             // for (var i = 0; i < array.length; i++) {
        //             //fileByteArray.push(array[i]);
        //             // }
        //         }
        //     }
        // };
        document.addEventListener("DOMContentLoaded", function() {

            initWorker();
            retrieveSampleVideo();
            retrieveSampleImage();

            var inputElement = document.querySelector("#input");
            outputElement = document.querySelector("#output");
            filesElement = document.querySelector("#files");

            inputElement.addEventListener("keydown", function(e) {
                if (e.keyCode === 13) {
                    runCommand(inputElement.value);
                }
            }, false);
            document.querySelector("#run").addEventListener("click", function() {
                runCommand(inputElement.value);
            });

            [].forEach.call(document.querySelectorAll(".sample"), function(link) {
                link.addEventListener("click", function(e) {
                    inputElement.value = this.getAttribute("data-command");
                    runCommand(inputElement.value);
                    e.preventDefault();
                });
            });

        });
    </script>
</body>
</html>


{{collectdata}}

网友评论0