前端canvas动画如何转成mp4视频的方法

2020-04-20 17:08:04易采站长站整理

用户通过上传合适尺寸的图片,选着渲染动画的效果和音乐,可以预览类似幻灯片的效果,最后点击确认生成视频,可以放到头条或者抖音播放。

生成视频可能的方案

纯前端的视频编码转换(例如WebM Encoder Whammy)

图片地址只能是相对地址
音乐不能收录
生成的视频需要下载再上传

将每帧图片传给后端实现,由后端调用FFmpeg进行视频转码

截图多的时候,base64字符串形式的图片太大,在前端不好传给后端
在前端截图还依赖用户电脑性能;

最后定的方案流程

canvas动画和截图在服务器端运行,后端根据标识获取截图
利用FFmpeg将图片合并成视频,并将视频存储在server端,并返回相应下载url
前端通过请求得到视频文件

前端canvas如何截图

每帧图片生成

图片生成可以通过canvas原生接口toDataURL实现,最终返回base64形式的图像数据


function generatePng() {
var canvas = document.createElement('canvas');
let icavas = '#canvas' //渲染动画的canvas id
if (wrapWidth == 2) {
icavas = '#verticalCanvas'
}
var canvasNode = document.querySelector(icavas)

canvas.width = canvasNode.width;
canvas.height = canvasNode.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(canvasNode, 0, 0);
var imgData = canvas.toDataURL("image/png");
return imgData;
}

canvas动画截图的方法

用setInterval定时执行图片生成的方法,当然也可以用requestAnimationFrame


setInterval(function() {
imgsTemp.push(generatePng())
}, 1000/60)

后端如何获取每帧图片

方案一:无头浏览器运行前端canvas动画js,然后js截图

最初设想:

截图用console.log打印出来,canvas截图是base64格式的,一个15秒的动画,截图有100多张,直接导致服务器运行崩溃(被否了);

试运行方案:

截图存储在js变量中,动画播放完成,在页面中加一个标识,然后后端去取这个变量,代码如下:


const pages = {
imageZoomOut: import ('./image_zoom_inout.js'), //缩放
imageArt: import ('./image_art.js'), //擦除
imageGrid: import ('./image_grid.js'), //网格
imageRotate: import ('./image_rotate.js'), //开合
imageFlash: import ('./image_flash.js'), //图文快闪
imageVerticalArt: import ('./image_vertical_art.js'), //竖版擦除
imageVerticalGrid: import ('./image_vertical_grid.js'), //竖版网格