VideoTexture - video is rotated 90 degrees

Hi Everyone!

I am having an issue with presenting a video using THREE.js. The video appears rotated 90 degrees while when presenting it using video tag looks correct.

The video was taken in vertical mode using Samsung Galaxy s8.

The video has rotation property in it. When running ffprobe on the video I get:

Blockquote
Duration: 00:01:30.71, start: 0.000000, bitrate: 1194 kb/s
Stream #0:0(und): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p, 640x304, 933 kb/s, 30.02 fps, 30 tbr, 90k tbn, 180k tbc (default)
Metadata:
rotate : 90
Side data:
displaymatrix: rotation of -90.00 degrees
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 256 kb/s (default)
Blockquote

link to the video: vertical.mp4 - Google Drive

I created an example for running the video using VideoTexture

Blockquote

<html>
	<head>
		<meta charset="utf-8">
		<title>My first three.js app</title>
		<style>
			body { margin: 0; }
			canvas { display: block; width: 100%; height: 100%  }
		</style>
	</head>
	<body>
	<video src="http://127.0.0.1:8081/vertical.mp4" muted autoplay/>
		<script src="js/three.js"></script>
		<script>
      let vid = document.createElement("video");
vid.src = "http://127.0.0.1:8081/vertical.mp4";

vid.muted = true;
vid.autoplay = true;
vid.play();


var scene = new THREE.Scene();
var camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0.1, 10);

var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var material = new THREE.MeshBasicMaterial();
var texture = new THREE.VideoTexture( vid );
texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.LinearFilter;
texture.format = THREE.RGBFormat;
material.map = texture
var geometry = new THREE.PlaneBufferGeometry(2, 2);
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

camera.position.z = 1;

function animate() {
	requestAnimationFrame( animate );
	renderer.render( scene, camera );
}
animate();

vid.addEventListener(
  "canplaythrough",
  function (e) {
    console.log('playing');
  },
  false
);
		</script>
	</body>
</html>

Blockquote

Is there a way to present the video as it does using the video tag?

Thank you very much!

Well, you can try to rotate the plane mesh that presents your video like so:

mesh.rotation.z = - Math.PI * 0.5;

However, three.js can’t extract the video orientation automatically for you. I’m not sure if this is even possible with JavaScript :thinking:.

Thank you for the reply!

Shouldn’t the VideoTexture present the video as the HTML video tag does?

Well, I can only say that WebGL just uses the raw frame data. Additional meta information like transformation data are obviously not honored.

1 Like