Three.js WebGLRenderered videos don't play on android phones
Asked Answered
B

1

1

The video texture example below does not seem to work on android LG nexus phone although all other non video examples work including the youtube example on three.js.

Does anyone else have this issue? I am trying to render video using THREE.WebGLRenderer so that I can ultimately use stereo effect with it to use it with VR (like google cardboard) kit. So far only CSS3DRenderer/Canvas rendered videos seem to work on the phone. But I can't use these renderers because stereo effect does not work with these renderers (i.e effect = new THREE.StereoEffect(renderer);)

http://mrdoob.github.io/three.js/examples/webgl_materials_video.html

Please let me know if there is to get videos render with stereo effect.

UPDATE---------------CODE ON HAND (Adapted from http://stemkoski.github.io/Three.js/Video.html)

            <!doctype html>
            <html lang="en">
            <head>
                <title>Video Texture (Three.js)</title>
                <meta charset="utf-8">
                <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
                <!-- <link rel=stylesheet href="css/base.css"/> -->
            </head>
            <body>

            <script src="js/three.min.js"></script>
            <script src="js/controls/OrbitControls.js"></script>
            <script src="js/effects/StereoEffect.js"></script>

            <div id="ThreeJS"></div>
            <script>
            var container, scene, camera, renderer, controls, stats, effect, element;
            var video, videoImage, videoImageContext, videoTexture;

            init();
            animate();

            // FUNCTIONS        
            function init() 
            {
                // SCENE
                scene = new THREE.Scene();
                // CAMERA
                var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
                var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
                camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
                scene.add(camera);
                camera.position.set(0,150,400);
                camera.lookAt(scene.position);  
                renderer = new THREE.WebGLRenderer( {antialias:true} );

                //effect = new THREE.StereoEffect(renderer);
                renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
                element= renderer.domElement;
                //effect.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
                container = document.getElementById( 'ThreeJS' );
                container.appendChild( element );
                // CONTROLS
                controls = new THREE.OrbitControls( camera, element );
                element.addEventListener('click', fullscreen, false);


                // LIGHT
                var light = new THREE.PointLight(0xffffff);
                light.position.set(0,250,0);
                scene.add(light);


                ///////////
                // VIDEO //
                ///////////

                // create the video element
                video = document.createElement( 'video' );
                //video.id = 'video';
                video.type = ' video/mp4; codecs="theora, vorbis" ';
                video.src = "video/sintel.ogv";
                video.load(); // must call after setting/changing source
                video.play();

                videoImage = document.createElement( 'canvas' );
                videoImage.width = 320;
                videoImage.height = 240;

                videoImageContext = videoImage.getContext( '2d' );
                // background color if no video present
                videoImageContext.fillStyle = '#000000';
                videoImageContext.fillRect( 0, 0, videoImage.width, videoImage.height );

                videoTexture = new THREE.Texture( videoImage );
                videoTexture.minFilter = THREE.LinearFilter;
                videoTexture.magFilter = THREE.LinearFilter;

                var movieMaterial = new THREE.MeshBasicMaterial( { map: videoTexture, overdraw: true, side:THREE.DoubleSide } );
                // the geometry on which the movie will be displayed;
                //      movie image will be scaled to fit these dimensions.
                var movieGeometry = new THREE.PlaneGeometry( 240, 100, 4, 4 );
                var movieScreen = new THREE.Mesh( movieGeometry, movieMaterial );
                movieScreen.position.set(0,50,00);
                scene.add(movieScreen);

                camera.position.set(0,150,300);
                camera.lookAt(movieScreen.position);

                window.addEventListener('resize', resize, false);
                  setTimeout(resize, 1);


            }

                function update() {
                  resize();

                  camera.updateProjectionMatrix();

                  controls.update();
                }

            function animate() 
            {
                requestAnimationFrame( animate );
                render();       
                //update();
            }

            function fullscreen() {

                video.play();
                console.log(video);
                  if (container.requestFullscreen) {
                    container.requestFullscreen();
                  } else if (container.msRequestFullscreen) {
                    container.msRequestFullscreen();
                  } else if (container.mozRequestFullScreen) {
                    container.mozRequestFullScreen();
                  } else if (container.webkitRequestFullscreen) {
                    container.webkitRequestFullscreen();
                  }
                }

                    function resize() {
                  var width = container.offsetWidth;
                  var height = container.offsetHeight;

                  //console.log(container, width,height);

                  camera.aspect = width / height;
                  camera.updateProjectionMatrix();

                  renderer.setSize(width, height);
                  //effect.setSize(width, height);
                }


            function render() 
            {   
                if ( video.readyState === video.HAVE_ENOUGH_DATA ) 
                {
                    videoImageContext.drawImage( video, 0, 0 );
                    if ( videoTexture ) 
                        videoTexture.needsUpdate = true;
                }

                renderer.render( scene, camera );
            }

            </script>

            </body>
            </html>
Beyer answered 29/9, 2014 at 21:49 Comment(1)
So I was able to get the video to play (sort of). I hear the audio but don't see the video. This was done by removing the type attribut as suggested in this blog post: broken-links.com/2010/07/08/… However, I see these errors thrown on the dev console when the audio part of the video plays. Uncaught SecurityError: Failed to execute 'texImage2D' on 'WebGLRenderingContext': Tainted canvases may not be loaded. three.min.js:507Beyer
E
1

On mobile devices videos don't play unless initiated from a user action. So if you execute the init method from a mousedown event listener it should work.

Espousal answered 30/9, 2014 at 3:53 Comment(6)
I have shown my code above. As you can see, I execute video.play() explicitly in click/touch event. I still don't see the video played.Beyer
if it helps, this is what I see in the log console. They are not reported as errors though. THREE.WebGLRenderer 68dev THREE.WebGLRenderer: Anisotropic texture filtering not supported. three.min.js:435 THREE.WebGLRenderer: S3TC compressed textures not supported.Beyer
I was able to play the audio part of the video. However I see these in the dev console: Uncaught SecurityError: Failed to execute 'texImage2D' on 'WebGLRenderingContext': Tainted canvases may not be loaded. three.min.js:507Beyer
I am going to close this question and open a new one. Since mrdoob's response answered the title of this question, it is sufficient in that respect. However there is a subsequent issue when the video plays and I am going to open a separate item to track that.Beyer
Posted #26127962Beyer
So, this is a bigger issue now apparently. See https://mcmap.net/q/11198/-one-three-js-example-of-video-on-iphone-6s-did-not-work-only-black-panelGullett

© 2022 - 2024 — McMap. All rights reserved.