Skip to content

Commit

Permalink
Add a built-in video recorder
Browse files Browse the repository at this point in the history
  • Loading branch information
xianfei committed Jun 27, 2022
1 parent 24a6183 commit 9d60a2e
Show file tree
Hide file tree
Showing 6 changed files with 6,424 additions and 34 deletions.
Binary file modified .DS_Store
Binary file not shown.
27 changes: 27 additions & 0 deletions mocaprender/render.html
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,33 @@
</div>
</div>

<div
id="recording"
style="
position: fixed;
bottom: 20px;
height: 40px;
width: 200px;
background-color: #a40601;
left: calc(50% - 100px);
border-radius: 20px;
text-align: center;
line-height: 40px;
display: none;
color: #fff;
"
>
正在录制,按R键停止
</div>

<canvas
id="background-canvas"
style="position: absolute; top: -99999999px; left: -9999999999px"
></canvas>

<script src="../utils/html2canvas.js"></script>
<script src="../utils/RecordRTC.js"></script>

<script src="../node_modules/kalidokit/dist/kalidokit.umd.js"></script>
<script src="./script.js" defer></script>
</body>
Expand Down
61 changes: 61 additions & 0 deletions mocaprender/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ statsContainer.appendChild(stats2.dom);
// Main Render Loop
const clock = new THREE.Clock();

var isRecordingStarted = false;

function animate() {
requestAnimationFrame(animate);

Expand All @@ -109,6 +111,11 @@ function animate() {
currentVrm.update(clock.getDelta());
}
renderer.render(scene, orbitCamera);

if(isRecordingStarted)html2canvas(elementToRecord).then(function (canvas) {
context.clearRect(0, 0, canvas2d.width, canvas2d.height);
context.drawImage(canvas, 0, 0, canvas2d.width, canvas2d.height);
});
}
animate();

Expand Down Expand Up @@ -774,6 +781,14 @@ document.addEventListener("keydown", (event) => {
case "ArrowDown":
positionOffset.y -= step;
break;
case "r":
if (isRecordingStarted) {
stopRecording();
document.getElementById("recording").style.display = "none";
} else {
startRecording();
document.getElementById("recording").style.display = "";
}
}
});

Expand All @@ -797,3 +812,49 @@ contentDom.ondrop = (e) => {
contentDom.style.backgroundPosition = "center";
contentDom.style.backgroundRepeat = "no-repeat";
};

var elementToRecord = contentDom;
var canvas2d = document.getElementById("background-canvas");
var context = canvas2d.getContext("2d");

canvas2d.width = elementToRecord.clientWidth;
canvas2d.height = elementToRecord.clientHeight;

var recorder = new RecordRTC(canvas2d, {
type: "canvas",
});

function startRecording() {
this.disabled = true;

isRecordingStarted = true;

recorder.startRecording();
}

function stopRecording() {
this.disabled = true;

recorder.stopRecording(function () {
isRecordingStarted = false;

var blob = recorder.getBlob();

const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "video.webm";

link.dispatchEvent(
new MouseEvent("click", {
bubbles: true,
cancelable: true,
view: window,
})
);

setTimeout(() => {
window.URL.revokeObjectURL(blob);
link.remove();
}, 100);
});
}
75 changes: 56 additions & 19 deletions render/render.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,15 @@
overflow: hidden;
position: fixed;
"
></div>
></div>

<div id="status" style="position: absolute; bottom: 140px">
<span style="position: absolute; left: 10px;font-size: 12px;">Render</span>
<span style="position: absolute; left: 100px;font-size: 12px;">Mocap</span>
<span style="position: absolute; left: 10px; font-size: 12px"
>Render</span
>
<span style="position: absolute; left: 100px; font-size: 12px"
>Mocap</span
>
</div>

<div
Expand Down Expand Up @@ -128,27 +132,60 @@
</div>

<div
style="
position: fixed;
left: calc(50vw - 100px);
bottom: 80px;
width: 200px;
height: 40px;
border-radius: 20px;
background-color: #fffe;
"
class="mdui-shadow-5"
id="loading"
>
<div
class="mdui-spinner mdui-spinner-colorful"
style="margin: 10px 15px; width: 20px; height: 20px"
></div>
<span
style="
line-height: 40px;
position: fixed;
left: calc(50vw - 100px);
bottom: 80px;
width: 200px;
height: 40px;
border-radius: 20px;
background-color: #fffe;
color: #555;
font-size: 14px;
margin-left: -3px;
"
class="mdui-shadow-5"
id="loading"
>初始化动作捕捉引擎…</span
>
<div
class="mdui-spinner mdui-spinner-colorful"
style="margin: 10px 15px; width: 20px; height: 20px"
></div>
<span style="line-height: 40px; position: fixed; color: #555;font-size: 14px;margin-left: -3px;"
>初始化动作捕捉引擎…</span
>
</div>
</div>

<div
id="recording"
style="
position: fixed;
bottom: 20px;
height: 40px;
width: 200px;
background-color: #a40601;
left: calc(50% - 100px);
border-radius: 20px;
text-align: center;
line-height: 40px;
display: none;
color: #fff;
"
>
正在录制,按R键停止
</div>

<canvas
id="background-canvas"
style="position: absolute; top: -99999999px; left: -9999999999px"
></canvas>

<script src="../utils/html2canvas.js"></script>
<script src="../utils/RecordRTC.js"></script>
<script src="../node_modules/kalidokit/dist/kalidokit.umd.js"></script>
<script src="./render.js" defer></script>
</body>
Expand Down
84 changes: 69 additions & 15 deletions render/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ document.body.setAttribute(
globalSettings.ui.themeColor
);


// import Helper Functions from Kalidokit
const remap = Kalidokit.Utils.remap;
const clamp = Kalidokit.Utils.clamp;
Expand All @@ -31,7 +30,6 @@ let currentVrm;

var mocapData = null;


// renderer
const renderer = new THREE.WebGLRenderer({
alpha: true,
Expand Down Expand Up @@ -97,7 +95,6 @@ var modelPath = modelObj.path;
// Main Render Loop
const clock = new THREE.Clock();


var fileType = modelPath
.substring(modelPath.lastIndexOf(".") + 1)
.toLowerCase();
Expand Down Expand Up @@ -203,7 +200,6 @@ loader.load(
(error) => console.error(error)
);


// Animate Rotation Helper function
const rigRotation = (
name,
Expand Down Expand Up @@ -404,15 +400,15 @@ const animateVRM = (vrm, results) => {
if (!vrm && !skeletonHelper) {
return;
}
if(!results) return;
if (!results) return;
// Take the results from `Holistic` and animate character based on its Face, Pose, and Hand Keypoints.
let riggedPose = results.riggedPose,
riggedLeftHand = results.riggedLeftHand,
riggedRightHand = results.riggedRightHand,
riggedFace = results.riggedFace;

// Animate Face
if (riggedFace ) {
if (riggedFace) {
rigRotation("Neck", riggedFace.head, 0.7);
if (fileType == "vrm") rigFace(structuredClone(riggedFace));
}
Expand Down Expand Up @@ -446,7 +442,7 @@ const animateVRM = (vrm, results) => {
}

// Animate Hands
if (riggedLeftHand && fileType == "vrm") {
if (riggedLeftHand && fileType == "vrm") {
rigRotation("LeftHand", {
// Combine pose rotation Z and hand rotation X Y
z: riggedPose.LeftHand.z,
Expand Down Expand Up @@ -523,9 +519,10 @@ const animateVRM = (vrm, results) => {
);
rigRotation("RightLittleDistal", riggedRightHand.RightLittleDistal);
}

};

var isRecordingStarted = false;

function animate() {
requestAnimationFrame(animate);

Expand All @@ -538,21 +535,25 @@ function animate() {
currentVrm.update(clock.getDelta());
}
renderer.render(scene, orbitCamera);

if(isRecordingStarted)html2canvas(elementToRecord).then(function (canvas) {
context.clearRect(0, 0, canvas2d.width, canvas2d.height);
context.drawImage(canvas, 0, 0, canvas2d.width, canvas2d.height);
});
}
animate();

var isStart = false;

window.onMocapData = (data)=>{
if(!isStart){
document.getElementById('loading').remove()
isStart = true
window.onMocapData = (data) => {
if (!isStart) {
document.getElementById("loading").remove();
isStart = true;
}
console.log("sendRenderDataForward")
stats2.update();
// Animate model
mocapData = data;
}
};

var app = new Vue({
el: "#controller",
Expand Down Expand Up @@ -600,10 +601,17 @@ document.addEventListener("keydown", (event) => {
case "ArrowDown":
positionOffset.y -= step;
break;
case "r":
if(isRecordingStarted){
stopRecording()
document.getElementById("recording").style.display = "none";
}else{
startRecording()
document.getElementById("recording").style.display = ""
}
}
});


if (localStorage.getItem("useCamera") !== "camera") {
document.querySelector("#model").style.transform = "scale(-1, 1)";
}
Expand All @@ -627,4 +635,50 @@ contentDom.ondrop = (e) => {
contentDom.style.backgroundSize = "cover";
contentDom.style.backgroundPosition = "center";
contentDom.style.backgroundRepeat = "no-repeat";
};

var elementToRecord = contentDom;
var canvas2d = document.getElementById("background-canvas");
var context = canvas2d.getContext("2d");

canvas2d.width = elementToRecord.clientWidth;
canvas2d.height = elementToRecord.clientHeight;

var recorder = new RecordRTC(canvas2d, {
type: "canvas"
});

function startRecording() {
this.disabled = true;

isRecordingStarted = true;

recorder.startRecording();
};

function stopRecording() {
this.disabled = true;

recorder.stopRecording(function () {
isRecordingStarted = false;

var blob = recorder.getBlob();

const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "video.webm";

link.dispatchEvent(
new MouseEvent("click", {
bubbles: true,
cancelable: true,
view: window,
})
);

setTimeout(() => {
window.URL.revokeObjectURL(blob);
link.remove();
}, 100);
});
};
Loading

0 comments on commit 9d60a2e

Please sign in to comment.