<!DOCTYPE html>
<!-- saved from url=(0045) -->
<html lang="zh-Hans" class="wds">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta content="no-transform" http-equiv="Cache-Control">
<meta content="zh-CN" http-equiv="Content-Language">
<!-- // 如果需要用到ffmpeg合并视频,需要将COEP和COOP打开,来确保ShareArrayBuffer能够正常使用/ -->
<meta http-equiv="Cross-Origin-Embedder-Policy" content="require-corp">
</meta>
<meta http-equiv="Cross-Origin-Opener-Policy" content="same-origin">
</meta>
<meta content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
name="viewport">
<script src="https://unpkg.com/konva@7.0.3/konva.min.js"></script>
<!-- <script src="/dist/canvas2video.js"></script>
<script src="/dist/ffmpeg-core.js"></script>
<script src="/dist/ffmpeg.min.js"></script> -->
<!-- <script src="/dist/canvas2video.js"></script> -->
<!-- <script src="https://unpkg.com/@ffmpeg/ffmpeg@0.7.0/dist/ffmpeg.min.js"></script> -->
<!-- <script src="https://unpkg.com/canvas2video@1.1.0/dist/canvas2video.js"></script> -->
<!-- <script src="https://unpkg.com/browse/@ffmpeg/ffmpeg@0.11.6/dist/ffmpeg.min.js"></script> -->
<!-- <script src="./dist/whammy.js"></script> -->
<style>
body {
background: green;
}
</style>
</head>
<body>
<div id="container"></div>
<video width="1000" height="1000" controls="true" autoplay="true" id="video" style="display:none;"></video>
<button id="btn">点击录制</button>
<button id="btn1">点击录制1</button>
<div id="image-box" style="display: flex; flex-direction: column;">
</div>
<img id="image1" src="/党课开讲了.jpg" style="display:none;height: 100px;">
<img id="image2" src="/党课标语.jpg" style="display:none;height: 100px;">
<canvas id="canvas"></canvas>
<script>
const loadImage = (imgSrc) => {
return new Promise((resolve, reject) => {
const image = new window.Image();
image.src = imgSrc;
image.onload = () => {
resolve(image);
};
image.onerror = reject;
});
}
const data = {
startOffsetTime: 2870000,
startTime: 2870000,
endTime: 5250612,
eleStartTime: 2870000,
eleEndTime: 5250612,
text: '默认文本',
trackId: '65b2d90f-0b9a-5d25-0c22-a1ad92f5100e',
id: '04640d8b-0060-368a-5de0-6a15350d209a',
type: 4,
locationTop: 819,
locationLeft: 729,
width: 462,
height: 42,
fontSize: 42,
opacity: 1,
fontFamily: '龙珠体 Regular',
fontColor: '#000000',
shadowColor: '#000000',
shadowBlur: 5,
shadowOpacity: 1,
shadowAngle: 0,
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowEnabled: false,
stroke: '#000000',
strokeEnabled: false,
strokeWidth: 2,
backgroundEnabled: false,
zIndex: 0,
x: 0,
y: 300,
captionswitch: true
}
const {
fontSize,
trackId,
text,
id,
opacity,
fontFamily,
fontColor,
locationLeft,
locationTop,
zIndex,
x, //中心点之间的距离差值x
y, //中心点之间的距离差值x
shadowColor,
shadowBlur,
shadowOffsetX,
shadowOffsetY,
shadowOpacity,
shadowEnabled,
stroke,
strokeEnabled,
strokeWidth,
cornerRadius,
fillEnabled,
fillPatternImage,
} = data;
var stage = new Konva.Stage({
container: 'container', // id of container <div>
width: 1000,
height: 1000,
});
// then create layer
var layer = new Konva.Layer();
// create our shape
var node = new Konva.Text({
x: 400, // 水平居中
y: 500,
text: '',
fontSize: fontSize,
fontFamily: fontFamily,
fill: 'green',
opacity: opacity,
shadowColor: shadowColor,
shadowEnabled: shadowEnabled,
shadowBlur: shadowBlur,
shadowOpacity: shadowOpacity,
shadowOffsetX: shadowOffsetX,
shadowOffsetY: shadowOffsetY,
data: data,
stroke: stroke,
strokeEnabled: strokeEnabled,
strokeWidth: strokeWidth,
fillEnabled,
fillPatternImage,
lineHeight: 1.1,
});
loadImage('/党课开讲了.jpg').then(img => {
console.log(img);
node.fillPatternImage(img);
node.fill(null);
});
// add the shape to the layer
layer.add(node);
// add the layer to the stage
stage.add(layer);
// draw the image
layer.draw();
let mediaRecorder = null;
let charsToShow = null
let elapsedTime = 0;
let frames = []; // 用于存储每一帧的图像URL
// 打字机的动画
const dzjAnimation = () => {
if (charsToShow > text.length) {
mediaRecorder.stop();
return
}
let duration = 4000; // 持续时间(毫秒)
let fps = 25; // 每秒帧数
let frameInterval = 1000 / fps; // 每帧的间隔时间(毫秒)
let charInterval = duration / text.length; // 每个字符的间隔时间(基于帧数分配)
let displayText = '默认文本'; // 用于构建并显示的部分文本
// 假设有一个元素用于显示文本
// 使用requestAnimationFrame可能更合适,因为它与屏幕刷新率同步
elapsedTime += frameInterval; // 使用每帧的间隔时间
// 计算在当前已过去的时间内应该显示多少个字符
charsToShow = Math.floor(elapsedTime / charInterval);
// 更新显示的文本
displayText = text.substring(0, charsToShow);
node.text(displayText);
layer.batchDraw();
setTimeout(dzjAnimation, frameInterval); // 递归调用
}
// 录制canvas动画
document.getElementById('btn').addEventListener('click', () => {
const canvas = document.querySelector('canvas');
if (!mediaRecorder) {
stream = canvas.captureStream(25);
mediaRecorder = new MediaRecorder(stream, {
mimeType: 'video/webm',
});
const recordedChunks = [];
mediaRecorder.ondataavailable = event => {
console.log(event.data);
recordedChunks.push(event.data);
};
mediaRecorder.onstop = async () => {
const videoBlob = new Blob(recordedChunks, { type: 'video/webm' });
console.log(videoBlob);
document.getElementById('video').src =URL.createObjectURL(videoBlob);
document.getElementById('video').style.display = 'block';
};
mediaRecorder.start();
requestAnimationFrame(dzjAnimation); // 开始绘制动画
}
})
</script>
</body>
</html>
针对konva.js 编写的canvas,进行canvas动画录制问题,已找到解决方案,但是想要格式是mp4 类型的 现在我只能转成webm 类型的 想要mp4 无损,透明的视频,各位大神帮帮忙
于 2024-08-21 11:15:51 首次发布