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