javascript播放带透明通道的mp4动画


    随着互联网的发展,动画效果也在一直更新,从刚开始的flsh动画,cocos骨骼动画,到YY开源的svga动画。最近1年来,带有透明通道的mp4动画被使用的极为广泛,对于app端。github上有开源的AlphaPlayer可以使用,但是对于web端,相关的资料很少。为了解决这个问题想了很多办法,提出了使用webm格式。但是最终还是要实现播放mp4格式。

    播放mp4格式的透明动画,需要什么呢。首先,对于web前端来说,webgl应该大家都很少介绍到,更不要说着色器了(shader)和OpenGL ES的语法了。放弃了好几次,最后看到一个帖子,可以用THREEJS来进行。先上一个图

    

 

   可以看到素材中左边部分使用RGB通道存储了原透明视频的Alpha值,右边部分使用RGB通道存储了原透明视频的RGB值,然后在端上通过OpenGL重新将每个像素点的Alpha值和RGB值进行组合,重新得到ARGB视频画面,实现透明视频的动画效果。

  在web端,具体实现。

  1.有个video播放器,播放mp4动画

  2.使用threejs和openel把画面重绘到一个容器里。

  

 1 var lastUpdate;
 2 var container; 3 var camera, scene, renderer; 4 var uniforms; 5 6 function init() { 7 8 container = document.getElementById('container'); 9 camera = new THREE.Camera(); 10 camera.position.z = 1; 11 scene = new THREE.Scene(); 12 13 var video = document.getElementById('video'); 14 video.src = "https://devimage.91banban.com/topcard.mp4"; 15  video.play(); 16 video.onended = () => { 17  video.play(); 18  } 19 videoTexture = new THREE.VideoTexture(video); 20 videoTexture.minFilter = THREE.LinearFilter; 21 videoTexture.magFilter = THREE.LinearFilter; 22 videoTexture.format = THREE.RGBAFormat; 23 24 // shader stuff 25 uniforms = { 26 time: { type: "f", value: 1.0 }, 27 texture: { type: "sampler2D", value: videoTexture } 28  }; 29 var material = new THREE.ShaderMaterial({ 30  uniforms: uniforms, 31  vertexShader: `varying vec2 vUv; 32 void main() { 33 vUv = uv; 34 gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); 35  }`, 36  fragmentShader: `#ifdef GL_ES 37 precision highp float; 38  #endif 39 40 uniform float time; 41  uniform sampler2D texture; 42  varying vec2 vUv; 43 44 void main( void ) { 45 gl_FragColor = vec4( 46 texture2D(texture, vec2(0.5+vUv.x/2., vUv.y)).rgb, 47 texture2D(texture, vec2(vUv.x/2., vUv.y)).r 48  ); 49  }`, 50 transparent: true 51  }); 52 lastUpdate = new Date().getTime(); 53 var geometry = new THREE.PlaneBufferGeometry(2, 2); 54 var mesh = new THREE.Mesh(geometry, material); 55 mesh.scale.setScalar(0.8); 56  scene.add(mesh); 57 renderer = new THREE.WebGLRenderer({ alpha: true }); 58 renderer.setPixelRatio(window.devicePixelRatio / 1); 59 60  container.appendChild(renderer.domElement); 61 62 document.getElementById('play-button').addEventListener('click', e => { video.play(); }); 63 renderer.setSize(1000, 1100); 64 this.animate(); 65 } 66 67 function animate() { 68 var currentTime = new Date().getTime() 69 var timeSinceLastUpdate = currentTime - lastUpdate; 70 lastUpdate = currentTime; 71  requestAnimationFrame(animate); 72  render(timeSinceLastUpdate); 73 74 } 75 function render(timeDelta) { 76 uniforms.time.value += (timeDelta ? timeDelta / 1000 : 0.05); 77  renderer.render(scene, camera); 78 } 79 80 init();

最终实现的效果图

 

 

    


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM