Three.js safari 上的 webgl 视频纹理 CORS 问题

Three.js webgl video texture CORS issue on safari

在我的 vuejs nuxt 静态站点 hosted on netlify 中,我尝试使用 mp4 视频 hosted 在 Vimeo Pro 上作为 three.js 中的视频纹理具有以下(简化版)

// create video dom element
let video_ele = document.createElement('video')
video_ele.className = 'video_texture'
video_ele.setAttribute('playsinline', true)
video_ele.muted = true
video_ele.loop = true
video_ele.autoplay = true
video_ele.crossOrigin = 'anonymous'
video_ele.src = "https://vimeo-video-url-here.....mp4"
document.body.appendChild(video_ele)


// create video texture from video
let video_texture = new THREE.VideoTexture(video_ele)
video_texture.minFilter = THREE.LinearFilter
video_texture.magFilter = THREE.LinearFilter
video_texture.format = THREE.RGBFormat

// map video texture to material
material = new THREE.MeshStandardMaterial({
    color: 0xa8a8a8,
    map: video_texture
})

在 chrome、firefox 和 chrome 移动浏览器上其他一切正常。 但是在 mac os 和 ios 13 上的 Safari 13 中,我在控制台中抛出了这个错误

THREE.WebGLState:
SecurityError: The operation is insecure. 

我尝试用 url 的其他视频 os hos 替换 vimeo 视频,但我只在 safari 中遇到同样的错误。

我很确定这是一个 CORS 问题,因为当我将 vimeo 或外部 url 替换为静态视频时 hosted 在同一个 host (netlify) , 它工作正常。

我也试过给视频添加时间戳 url 只是为了确定这不是缓存问题,但还是不行

想知道如何使用像 vimeo 这样的外部 hosted 视频来完成这项工作?

经过进一步测试,在我看来,问题是由使用 vimeo 文件时发生的 302 重定向到他们的 CDN 引起的 url。

正如@gman 指出的那样,Soundclound 上也有类似的问题,我发现那里提供的解决方案也适用于我的情况。 How to get Safari 12 to process audio from soundcloud?

我通过发出异步获取请求来获取 CDN url 然后将其传递给 video.src 来解决它。现在可以在 Safari mac 和 ios (13) 中使用了!

  async function getMediaURLForTrack(texture_to_update, passed_url) {
    await fetch(passed_url, {
      method: 'HEAD'
    })
    .then((response) => {
      texture_to_update.src = response.url
    });
  }