Obviously I tried to check if ChatGPT knows that but it failed too.
I wanted VideoJS since it can be easily extended and load AV1 video files.
My intention is to synchronize the frame decoding with an event and that’s not something that you can do 1:1 with video textures (you can get the approximated time but no the exact frame)
The test was:
<!DOCTYPE html>
<html>
<head>
<title>Video Texture en BabylonJS con VideoJS</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/video.js/8.3.0/video-js.min.css" rel="stylesheet">
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
<script src="https://cdn.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
<script src="https://vjs.zencdn.net/7.21.1/video.min.js"></script>
<style>
#renderCanvas {
width: 100%;
height: 70vh;
touch-action: none;
}
.video-container {
width: 100%;
max-width: 640px;
margin: 20px auto;
}
#videoPlayer {
width: 100%;
}
</style>
</head>
<body>
<div class="video-container">
<video
id="videoPlayer"
class="video-js vjs-default-skin"
controls
preload="auto"
width="640"
height="360"
data-setup="{}"
>
<source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
</video>
</div>
<canvas id="renderCanvas"></canvas>
<script>
window.addEventListener('load', function() {
const player = videojs('videoPlayer');
if (typeof BABYLON !== 'undefined') {
// Esperar a que el video esté listo
player.ready(() => {
initBabylon(player);
});
} else {
console.error('BABYLON is not loaded correctly');
}
});
function initBabylon(player) {
const canvas = document.getElementById('renderCanvas');
const engine = new BABYLON.Engine(canvas, true);
const createScene = function() {
const scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color4(0.2, 0.2, 0.2, 1);
// Debug layer
scene.debugLayer.show();
// Camera setup
const camera = new BABYLON.ArcRotateCamera(
"camera",
Math.PI / 2,
Math.PI / 2,
10,
BABYLON.Vector3.Zero(),
scene
);
camera.attachControl(canvas, true);
// Lights
const hemisphericLight = new BABYLON.HemisphericLight(
"hemisphericLight",
new BABYLON.Vector3(0, 1, 0),
scene
);
hemisphericLight.intensity = 1;
// Create reference sphere (red)
const sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {
diameter: 1
}, scene);
sphere.position = new BABYLON.Vector3(2, 0, 0);
const sphereMaterial = new BABYLON.StandardMaterial("sphereMaterial", scene);
sphereMaterial.diffuseColor = new BABYLON.Color3(1, 0, 0);
sphere.material = sphereMaterial;
// Create box
const box = BABYLON.MeshBuilder.CreateBox("box", {
size: 2
}, scene);
box.position = new BABYLON.Vector3(-2, 0, 0);
// Create video material
const videoMaterial = new BABYLON.StandardMaterial("videoMaterial", scene);
// Configurar el material antes de asignar la textura
videoMaterial.roughness = 1;
videoMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
videoMaterial.emissiveColor = new BABYLON.Color3(0.2, 0.2, 0.2);
// Crear y asignar la textura del video
const videoElement = player.tech().el();
const videoTexture = new BABYLON.VideoTexture(
"videoTexture",
videoElement,
scene,
true,
false,
BABYLON.VideoTexture.TRILINEAR_SAMPLINGMODE,
{
autoPlay: false,
loop: true,
autoUpdateTexture: true
}
);
videoMaterial.diffuseTexture = videoTexture;
box.material = videoMaterial;
// Rotación
scene.registerBeforeRender(function() {
box.rotation.y += 0.005;
});
return scene;
}
const scene = createScene();
engine.runRenderLoop(function() {
scene.render();
});
window.addEventListener('resize', function() {
engine.resize();
});
// Actualizar la textura cuando el video se reproduzca
player.on('play', function() {
const videoMaterial = scene.getMaterialByName("videoMaterial");
if (videoMaterial && videoMaterial.diffuseTexture) {
videoMaterial.diffuseTexture.update();
}
});
}
</script>
</body>
</html>
I modified it a little but as you can see the cube disappears when you apply that video texture.
Any help is welcome!