I need to render an mjpeg steam as a WebGL texture that automatically updates along with the stream.
Using Three.js, I found one approach: drawing the mjpeg stream into an html canvas and using the canvas as the webgl texture:
<canvas id="2d" width="512" height="512" style="display: none"></canvas>
<canvas id="3d" width="1000px" height="800px"></canvas>
_
import THREE from 'three'
const renderer = new THREE.WebGLRenderer({ canvas: document.getElementById('3d') })
let scene, camera
const canvas2d = document.getElementById('2d')
const ctx = canvas2d.getContext("2d")
const img = new Image()
img.crossOrigin = 'anonymous'
img.src = 'http://localhost:8080'
const map = new THREE.Texture(canvas2d)
const material = new THREE.MeshBasicMaterial({ map: map })
const init = () => {
scene = new THREE.Scene()
camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 10000)
camera.position.set(0, 0, 5)
scene.add(camera)
const geometry = new THREE.TorusGeometry(1, 0.5, 16, 16)
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)
}
const animate = () => {
requestAnimationFrame(animate)
// Update texture
ctx.drawImage(img, 0, 0, 500, 500)
map.needsUpdate = true
renderer.render(scene, camera)
}
init()
animate()
This works in Safari but I can't get this to work in Chrome due to what looks like this problem: Chrome MJPEG CORS "invalid response" when img.crossOrigin="Anonymous" I've tried adding all the proper headers and I've tried a bunch of cors workarounds, but Chrome always thinks that the 2d canvas has been tainted and will not use it as a texture.
Is there a better to draw an mjpeg stream into a webgl texture that would work on Chrome as well?
Is there a more direct way to do this all instead of going through an html canvas?