Security News
Weekly Downloads Now Available in npm Package Search Results
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
web-video-creator
Advanced tools
A framework for creating videos based on Node.js + Puppeteer + FFmpeg。
WebVideoCreator(简称WVC)是一个基于 Node.js + Puppeteer + FFmpeg 创建视频的框架,它执行确定性的渲染,准确的以目标帧率捕获任何可在HTML5播放动画(CSS3动画/SVG动画/Lottie动画/GIF动画/APNG动画/WEBP动画)以及任何基于时间轴使用RAF驱动的动画(anime.js是一个不错的选择 :D),当然您也可以调皮的使用setInterval或者setTimeout来控制动画,支持嵌入mp4和透明webm视频,还支持转场合成、音频合成与字体等功能。让我们快速开始。
WVC为您酷炫的动画页面创造了一个虚拟时间环境(也许可以想象成是一个《楚门的世界》),它的主要职责是将一个 不确定性渲染的环境 转化到 确定性渲染的环境。
在日常使用中,浏览器在执行动画渲染时并不是“实时同步”的,当系统负载较高时可能出现掉帧导致动画看上去不够平滑,并且为了提高性能浏览器通常会将部分解码/渲染任务交由其它线程处理,这导致动画间时间轴并不同步(video元素是一个典例:P)。这些对于视频渲染是不可靠的,视频的每一帧动画效果应该是确定性的。
对于执行渲染的代码来说它是无感的,一切照常发生,只是时间流速变得可控,RAF返回的currentTime、setTimeout/setInterval回调的调用时机、Date、performance.now等,都是根据当前已渲染的进度决定的。除了接管时钟,对于动态图像和内嵌视频这类通常不由开发者控制的媒体,采用了一些实验性的 WebCodecs API 进行了接管。
这一切的前提由Chrome提供的无头实验API支持:HeadlessExperimental.beginFrame
理论上所有的Web动画/图形库都能够在WVC环境正常运行,以下仅列出我已验证可用的库:
Anime.js / GSAP / D3.js / Three.js / Echart / Lottie-Web / PixiJS / Animate.css / Mo.js / Tween.js
需要注意的是,如果您手动使用RAF驱动动画,请确保从回调中接收timestamp参数设置动画的进度到该时间点,否则可能出现帧率不同步。
正在生产...
npm i web-video-creator
如遇到ffmpeg-static下载失败,请先设置环境变量:FFMPEG_BINARIES_URL=https://cdn.npmmirror.com/binaries/ffmpeg-static
目前WVC提供了两个简易的示例,分别演示单幕和多幕视频渲染合成。
调用示例代码来自:examples/single-video.js
import { examples, VIDEO_ENCODER } from "web-video-creator";
await examples.singleVideo({
// 需要渲染的页面地址
url: "http://localhost:8080/test.html",
// 视频宽度
width: 1280,
// 视频高度
height: 720,
// 视频帧率
fps: 30,
// 视频时长
duration: 10000,
// 根据您的硬件设备选择适合的编码器,这里采用的是Nvidia显卡的h264_nvenc编码器
// 编码器选择可参考VIDEO_ENCODER内提供的选项注释
videoEncoder: VIDEO_ENCODER.NVIDIA.H264,
// 视频输出路径
outputPath: "./test.mp4"
});
调用示例代码来自:examples/multi-video.js
import { examples, VIDEO_ENCODER, TRANSITION } from "web-video-creator";
await examples.multiVideo({
// 视频块列表
chunks: [
{
url: "http://localhost:8080/scene1.html",
duration: 10000,
// 与下一幕切换时使用圆形裁剪转场
transition: TRANSITION.CIRCLE_CROP
},
{
url: "http://localhost:8080/scene2.html",
duration: 10000
},
...
],
// 视频宽度
width: 1280,
// 视频高度
height: 720,
// 视频帧率
fps: 30,
// 根据您的硬件设备选择适合的编码器,这里采用的是Nvidia显卡的h264_nvenc编码器
// 编码器选择可参考VIDEO_ENCODER内提供的选项注释
videoEncoder: VIDEO_ENCODER.NVIDIA.H264,
// 视频输出路径
outputPath: "./test.mp4"
});
import WebVideoCreator, { VIDEO_ENCODER } from "web-video-creator";
const wvc = new WebVideoCreator();
// 配置WVC
wvc.config({
// 根据您的硬件设备选择适合的编码器,这里采用的是Nvidia显卡的h264_nvenc编码器
// 编码器选择可参考VIDEO_ENCODER内提供的选项注释
mp4Encoder: VIDEO_ENCODER.NVIDIA.H264
});
// 创建单幕视频
const video = wvc.createSingleVideo({
// 需要渲染的页面地址
url: "http://localhost:8080/test.html",
// 视频宽度
width: 1280,
// 视频高度
height: 720,
// 视频帧率
fps: 30,
// 视频时长
duration: 10000,
// 视频输出路径
outputPath: "./test.mp4",
// 是否在cli显示进度条
showProgress: true
});
// 监听合成完成事件
video.once("completed", result => {
console.log("Render Completed!!!", result);
});
// 启动合成
video.start();
只需在需要渲染的html中添加 <audio>
元素,您还可以设置循环,WVC会自动为视频合入循环音轨。
<audio src="bgm.mp3" loop/>
还可以设置一些其它属性控制音频的行为,这些属性并不总是需要成对出现,您可以根据自己的需求定制。
<!-- 控制音频在3秒后开始播放并在10秒处停止播放 -->
<audio src="bgm.mp3" startTime="3000" endTime="10000"/>
<!-- 截取音频第5秒到第15秒的片段并循环播放它 -->
<audio src="bgm.mp3" seekStart="5000" seekEnd="15000" loop/>
<!-- 控制音频300毫秒淡入且500毫秒淡出 -->
<audio src="bgm.mp3" fadeInDuration="300" fadeOutDuration="500"/>
在代码中添加和移除 <audio>
元素来实现音频出入场也是被允许的,WVC将检测到它们。
const audio = document.createElement("audio");
audio.src = "bgm.mp3";
// 音频在视频第3秒入场
setTimeout(() => document.body.appendChild(audio), 3000);
// 音频在视频第8秒出场
setTimeout(() => audio.remove(), 80000);
许多时候您可能并不希望侵入修改html内容,可以使用 addAudio
将音频添加到视频中。
const video = wvc.createSingleVideo({ ... });
// 添加单个音频
video.addAudio({
// url: "http://.../bgm.mp3"
path: "bgm.mp3",
startTime: 500,
loop: true
});
// 添加多个音频
video.addAudios([...]);
这样的操作同样适用于 MultiVideo 和 ChunkVideo 。
目前支持 mp4
和 webm
格式的视频,只需在需要渲染的html中添加 <video>
元素,您可以设置循环和静音,请务必为通过属性或样式设置元素宽高,因为在WVC中画布的大小是确定的,否则可能不可见。
<video src="background.mp4" loop muted style="width: 1280px; height: 720px"/>
如果希望插入透明通道的视频请见:透明通道视频,如果您对视频帧率同步或透明视频绘制感兴趣可以参考:技术实现。
和音频一样,它也支持设置一些属性控制视频的行为,这些属性并不总是需要成对出现,您可以根据自己的需求定制。
<!-- 控制视频在3秒后开始播放并在10秒处停止播放 -->
<video src="test.mp4" startTime="3000" endTime="10000" style="width: 640px; height: 480px"/>
<!-- 截取视频第5秒到第15秒的片段并循环播放它 -->
<video src="test.mp4" seekStart="5000" seekEnd="15000" loop style="width: 640px; height: 480px"/>
<!-- 控制视频的音频在300毫秒淡入且500毫秒淡出 -->
<video src="test.mp4" fadeInDuration="300" fadeOutDuration="500" style="width: 640px; height: 480px"/>
在代码中添加和移除 <video>
元素来实现视频出入场也是被允许的,WVC将检测到它们。
const video = document.createElement("video");
video.src = "test.mp4";
video.width = 640;
video.height = 480;
// 视频在第3秒入场
setTimeout(() => document.body.appendChild(video), 3000);
// 视频在第8秒出场
setTimeout(() => video.remove(), 8000);
透明视频非常适合用于将vtuber数字人合成到视频画面中,结合精美的动画可以获得非常好的观看体验。
透明通道视频格式需为 webm
,在内部它会被重新编码为两个mp4容器的视频,分别是原色底视频和蒙版视频后在浏览器canvas中使用进行 globalCompositeOperation
进行图像混合并绘制。
对于使用者是无感的,像下面代码演示中那样,只需需要渲染的html中添加 <video>
元素,并设置src为webm格式视频地址即可。
<video src="vtuber.webm" style="width: 480px; height: 640px"/>
webm编解码通常比较耗时,如果您可以直接获得原始mp4视频和蒙版mp4视频是更好的方案,只需增加设置maskSrc即可。
<video src="vtuber.mp4" maskSrc="vtuber_mask.mp4" style="width: 480px; height: 640px"/>
动态图像指的是 gif
/ apng
/ webp
格式的序列帧动画,他们可以在浏览器中自然播放,帧率通常是不可控的,但WVC代理了它们的绘制,img元素被替换为canvas并通过ImageDecoder解码绘制每一帧,让序列帧动画按照虚拟时间同步绘制。
以下这些动图都能够正常绘制,您也可以照常给他们设置样式。
<img src="test.gif"/>
<img src="test.apng"/>
<img src="test.webp"/>
WVC已经内置 lottie-web 动画库,如果您的页面有自己实现的lottie动效则可以忽略本内容,因为它们也能够正常工作。
只需要插入一个 <lottie>
元素并设置src即可。
<lottie src="example.json"/>
WVC能够检测样式表中的 @font-face
声明并等待字体加载完成再开始渲染。
<style>
@font-face {
font-family: "FontTest";
src: url("font.ttf") format("truetype");
}
</style>
<p style='font-family: "FontTest"'>Hello World</p>
或者,可以通过代码注册本地或远程的字体。
const video = wvc.createSingleVideo({ ... });
// 注册单个字体
video.registerFont({
// url: "http://.../font.ttf"
path: "font.ttf",
family: "FontTest",
format: "truetype"
});
// 注册多个字体
video.registerFonts([...]);
您需要确保字体能够正常加载,否则可能无法启动渲染。
WVC默认页面导航完成后立即启动渲染,如果希望在渲染之前进行一些工作,可以在选项中禁用自动启动渲染,禁用后请记得在您的页面中调用 captureCtx.start()
,否则将永远阻塞。
const video = wvc.createSingleVideo({
url: "http://localhost:8080/test.html",
width: 1280,
height: 720,
duration: 10000,
// 禁用自动启动渲染
autostartRender: false
});
页面代码中,在您觉得合适的时机调用启动。
<script>
// 5秒后启动渲染
setTimeout(() => captureCtx.start(), 5000);
</script>
如果您有多台设备可以为这些设备部署WVC,它提供了 MultiVideo
和 ChunkVideo
,您可以将动画页面分为很多个分段,如0-10秒、10-20秒...,将它们的参数分发到不同设备的WVC上,在这些设备上创建ChunkVideo实例并执行并行渲染为多个视频 ts
分段,将他们回传到核心节点上,并最终输入MultiVideo进行合并以及转场、音轨合成输出。这个分发以及回传流程WVC还未实现,但它并不难,您可以根据自己的场景进行封装并欢迎为WVC贡献PR!
大部分时候,建议使用高级别API,因为它足够的简单,但可能不够灵活。
性能通常受动画和媒体的复杂程度影响,您可以将长时间动画分为多个分段动画播放,比如为每个页面地址带一个seek参数,加载页面后seek到指定时间点开始播放,然后作为多幕视频进行渲染合成,可以显著的降低长视频的渲染耗时。
目前手上没有更好的测试设备,我将以我的个人主机的性能参数作为参考:
系统:Windows10(在Linux系统中性能表现更好)
CPU: AMD Ryzen 7 3700X(主频3.6-4.4GHz 8核16线程)
GPU: Nvidia GeForce GTX 1660 SUPER(6GB显存 支持NVENC)
RAM: 16GB(DDR4 2400MHz)
视频类型:SVG动画+GIF+Lottie动画播放
视频分辨率:1280x720
视频帧率:30
视频时长:300s(5分钟)
渲染耗时:61s(1分钟)
实时率:4.844
并行渲染数:16
正在编写中...
FAQs
A framework for creating videos based on Node.js + Puppeteer + FFmpeg.
The npm package web-video-creator receives a total of 6 weekly downloads. As such, web-video-creator popularity was classified as not popular.
We found that web-video-creator demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
Security News
A Stanford study reveals 9.5% of engineers contribute almost nothing, costing tech $90B annually, with remote work fueling the rise of "ghost engineers."
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.