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>
网友评论0