Compare commits

..

3 Commits

Author SHA1 Message Date
HxxxxxS 3916ba4bc3 Initial commit 2 years ago
HxxxxxS a58b1ccb77 .gitignore assets/ 2 years ago
HxxxxxS d33a7b9ba5 Add .gitignore 2 years ago
  1. 4
      .gitignore
  2. 25
      index.html
  3. 31
      index.js
  4. 17
      package.json
  5. 178
      script.js
  6. 12
      styles.css
  7. 1
      videoFiles.js

4
.gitignore vendored

@ -0,0 +1,4 @@
node_modules/
package-lock.json
assets/

25
index.html

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>VFX2</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="visualizer">
<div class="video-layer">
</div>
<div class="video-layer">
</div>
<canvas id="videoCanvas"></canvas>
<div class="glitch-layer">
<!-- Add occasional glitch effects here -->
</div>
</div>
<script src="script.js"></script>
</body>
</html>

31
index.js

@ -0,0 +1,31 @@
const express = require('express');
const app = express();
const path = require('path');
const port = 8000
const videoFiles = [
{ "src": "assets/Blender Physics Simulations-8TGNRJDZX_o_compressed.webm"},
{ "src": "assets/Death Grips - Birds-XX5wk-6Mn5s_compressed.webm"},
{ "src": "assets/Jon Hopkins - 'Open Eye Signal' (Official Music Video)-Q04ILDXe3QE_compressed.webm"},
{ "src": "assets/Best Scene From Hackers The Movie-IyWv6snuZLk_compressed.webm"},
{ "src": "assets/$UICIDEBOY$ - O PANA!-VSXg2swBmrY_compressed.webm"},
{ "src": "assets/3D Fractals (Render Test 1)-xQ6nJYanKCY_compressed.webm"},
{ "src": "assets/Beyond The Minds Eye-wKxH51vPtHk -4_compressed.webm"},
{ "src": "assets/A Scene From Troll 2-HyophYBP_w4_compressed.webm"}
// Add more video files as needed
];
app.use(express.static(path.join(__dirname)));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'index.html'));
});
app.get('/api/videos', (req, res) => {
res.json(videoFiles);
});
app.listen(port, () => {
console.log('Server started on port', port);
});

17
package.json

@ -0,0 +1,17 @@
{
"name": "vfx2",
"version": "1.0.0",
"description": "",
"main": "script.js",
"scripts": {
"dev": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.2",
"http-server": "^14.1.1"
}
}

178
script.js

@ -0,0 +1,178 @@
// Define a debug mode variable
let debugMode = true;
const canvas = document.getElementById("videoCanvas");
const ctx = canvas.getContext("2d");
const videos = [createVideoElement(), createVideoElement()];
let videosLoaded = 0;
let aspectRatio = 1;
window.addEventListener("DOMContentLoaded", () => {
let previousVideo
videos.forEach((video) => {
previousVideo = selectRandomVideo(previousVideo || video)
});
})
videos.forEach((video) => {
video.addEventListener("loadedmetadata", handleVideoLoaded);
video.addEventListener("ended", handleVideoEnded);
});
function createVideoElement() {
const video = document.createElement("video");
video.autoplay = true;
video.muted = true;
return video;
}
function handleVideoLoaded() {
videosLoaded++;
if (videosLoaded === videos.length) {
updateCanvasSize();
drawVideos();
}
}
function handleVideoEnded(event) {
const video = event.target;
selectRandomVideo(video);
}
// Function to extract filename from full path and unescape it
function extractFilename(src) {
// Split the path by '/'
const parts = src.split('/');
// Get the last part of the path (filename)
const filename = parts[parts.length - 1];
// Unescape the filename and replace '%20' with whitespace
return decodeURIComponent(filename.replace(/\%20/g, ' '));
}
// Function to draw debug text on the canvas
function drawDebugText() {
// Set font style and color
ctx.font = "16px Arial";
ctx.fillStyle = "white";
let corners = [[0,0],[1,1],[0,1],[1,0]];
let padding = 20;
videos.forEach((video,i) => {
//console.log("Drawing debug text for video",i,video);
let corner = corners[i];
let positionX = corner[0] === 0 ? padding : canvas.width - padding;
let positionY = corner[1] === 0 ? padding : canvas.height - padding;
// Adjust position for bottom right corner to stay within canvas bounds
if (corner[0] === 1 && positionY + 40 > canvas.height) {
positionY = canvas.height - 40;
}
// Set text alignment based on corner
ctx.textAlign = corner[0] === 0 ? "left" : "right";
ctx.textBaseline = corner[1] === 0 ? "top" : "bottom";
// Draw debug text for the video
ctx.fillText(getFilename(video.src), positionX, positionY);
ctx.fillText("Dimensions: " + video.videoWidth + "x" + video.videoHeight, positionX, positionY + 20);
ctx.fillText(formatTime(video.currentTime) + "/" + formatTime(video.duration), positionX, positionY + 40);
// Add more debug information as needed
});
}
// Function to extract filename from full path
function getFilename(src) {
const parts = src.split('/');
return decodeURIComponent(parts[parts.length - 1].replace(/\%20/g, ' '));
}
// Helper function to format time in HH:MM:SS format
function formatTime(seconds) {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const remainingSeconds = Math.floor(seconds % 60);
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
}
// Modify the drawVideos function to include debug text drawing
function drawVideos() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Resize the canvas to accommodate both videos side by side
canvas.width = Math.max(videos[0].videoWidth, videos[1].videoWidth);
canvas.height = Math.max(videos[0].videoHeight, videos[1].videoHeight);
// Calculate positions for each video
const video1X = (canvas.width - videos[0].videoWidth) / 2;
const video1Y = (canvas.height - videos[0].videoHeight) / 2;
const video2X = (canvas.width - videos[1].videoWidth) / 2;
const video2Y = (canvas.height - videos[1].videoHeight) / 2;
// Draw video 1
ctx.drawImage(videos[0], video1X, video1Y, videos[0].videoWidth, videos[0].videoHeight);
// Set composite operation to overlay
ctx.globalCompositeOperation = "overlay";
// Draw video 2
ctx.drawImage(videos[1], video2X, video2Y, videos[1].videoWidth, videos[1].videoHeight);
// Reset composite operation
ctx.globalCompositeOperation = "source-over";
// Draw debug text if debug mode is enabled
if (debugMode) {
drawDebugText();
}
// Request next frame
requestAnimationFrame(drawVideos);
}
function updateCanvasSize() {
aspectRatio = Math.max(
videos[0].videoWidth / videos[0].videoHeight,
videos[1].videoWidth / videos[1].videoHeight
);
canvas.width = window.innerWidth;
canvas.height = window.innerWidth / aspectRatio;
}
window.addEventListener("resize", updateCanvasSize);
updateCanvasSize()
function selectRandomVideo(videoElement) {
console.log("selectRandomVideo",videoElement)
fetch("/api/videos")
.then((response) => response.json())
.then((videoFiles) => {
const otherVideo = videos.find((video) => video !== videoElement);
let randomVideo;
do {
const randomIndex = Math.floor(Math.random() * videoFiles.length);
randomVideo = videoFiles[randomIndex];
} while (randomVideo === otherVideo);
videoElement.src = randomVideo.src;
videoElement.play();
return videoElement
});
}
document.addEventListener('keydown', function(event) {
// Check if the pressed key is the one you want to bind
if (event.key === 'Enter') { // Change 'Enter' to the desired key
debugMode = !debugMode
console.log("debugMode:",debugMode)
}
});

12
styles.css

@ -0,0 +1,12 @@
body, html {
background: black;
height: 100%;
margin: 0;
padding: 0;
}
#videoCanvas {
position: absolute;
width: 100%;
height: 100%;
}

1
videoFiles.js

@ -0,0 +1 @@
]
Loading…
Cancel
Save