这里写自定义目录标题
如何使将3D模型插入到视频中去
需要使用 three和 file-saver 这两个库
实现原理是通过将video 标签设置为父元素 将container设为子元素 进行覆盖同时子元素的背景设置为透明
直接上代码
<template>
<div class="wrapper">
<button @click="add">点击下载视频</button>
<video ref="video" width="100%" height="100%" autoplay muted loop @canplay="onVideoCanPlay">
<source src="../public/稻妻女团.mp4" type="video/mp4" />
</video>
<div ref="container" class="container"></div>
</div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import * as THREE from "three";
import { saveAs } from "file-saver";
const container = ref(null);
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
let renderer = null;
let cube = null;
let modelCreated = false;
onMounted(() => {
const video = document.querySelector("video");
if (!video) return;
video.addEventListener("canplay", () => {
if (modelCreated) return; // 如果模型已经被创建,则不再执行后续操作
const videoWidth = video.videoWidth;
const videoHeight = video.videoHeight;
canvas.width = 200;
canvas.height = 200;
const scene = new THREE.Scene();
const width = 200;
const height = 200;
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(width, height);
const containerElement = container.value;
if (!containerElement) return;
containerElement.appendChild(renderer.domElement);
scene.background = null;
const geometry = new THREE.BoxGeometry(200, 200, 200);
const material = new THREE.MeshBasicMaterial({
color: 0x00ff00,
transparent: true,
opacity: 0.5
});
cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 400;
const animate = () => {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
// 在每一帧的最后渲染模型
renderer.render(scene, camera);
};
animate();
// 将视频和3D模型绘制到画布上(模型绘制在视频的左下角)
ctx.drawImage(video, 0, 0, 200, 200);
ctx.drawImage(renderer.domElement, 0, 0, 200, 200);
modelCreated = true; // 将模型创建标志设置为 true
});
});
const add = () => {
if (!modelCreated) return;
canvas.toBlob(blob => {
saveAs(blob, "video_with_model.mp4");
}, "video/mp4");
};
</script>
<style>
.wrapper {
position: relative;
width: 100%;
height: 100%;
}
.container {
position: absolute;
bottom: 0;
left: 0;
width: 200px;
height: 200px;
}
</style>