前端全景视频播放器总结

更新日期:2019-09-12

实现

全景视频原理

原理:球模型贴图+鼠标(手势)事件
官方示例代码https://github.com/mrdoob/three.js/blob/master/examples/webgl_video_panorama_equirectangular.html
示例地址webgl_video_panorama_equirectangular
测试视频http://cache.utovr.com/9049b27016264739a2126dd073830492/L2_em34n10gj9tdzeks.mp4

动态获取视频链接

问题:将video标签的src赋一个空字符传作为初值,然后通过请求或其他方式获取到视频链接,再替换video标签的src,这样做视频不能正常播放。
方案:获取到视频链接后,再生成video,插入到页面中

function createdVideo(src) {
    var videoPlayer = $("#my-video").get(0)
    if (typeof (videoPlayer) != "undefined") {
        var myPlayer = videojs('my-video')
        myPlayer.dispose()
    }
    var id = 'my-video'
    var videoDom = ''
    videoDom = $('<video id="' + id + '" class="video-js" controls preload="auto" loop data-setup="{}" crossorigin="anonymous" webkit-playsinline="true" x-webkit-airplay="true" playsinline="true" x5-video-player-type="h5" x5-video-player-fullscreen="true"><source src="' + src + '"></video>')
    $('#wrapper').html(videoDom)
    return videojs(id, {}, function() {
        var myPlayer = videojs(id);
        
        videojs(id).ready(function () {
            var myPlayer = this;
            startRender(myPlayer)
        });
    })
}

渲染全景视频

问题:视频能都播放,但无法渲染
方案:可能的原因是视频动态获取,还没有加载就进行渲染,导致渲染失败。因此在加载成功后再进行渲染

function startRender() {
    var geometry = new THREE.SphereBufferGeometry(500, 60, 40)
    // invert the geometry on the x-axis so that all of the faces point inward
    geometry.scale(-1, 1, 1)

    var texture = new THREE.VideoTexture(document.querySelector('#my-video video'))
    texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping;
    texture.minFilter = THREE.LinearFilter;
    texture.needsUpdate = true;
    var material = new THREE.MeshBasicMaterial({ map: texture })

    mesh = new THREE.Mesh(geometry, material)

    scene.add(mesh)
}

自动播放

新版的chrome已经禁止了自动播放,autoplay属性无效。但是可以通过video标签的muted属性进行静音,保证自动播放。网上流传的静音播放然后再打开声音的方法是无效的。自动播放什么的就别想了

移动端播放

webkit-playsinline="true"
x-webkit-airplay="true"
playsinline="true"
x5-video-player-type="h5"
x5-video-player-fullscreen="true"

注意:在退出全屏时候会暂停视频,触发pause事件

播放m3u8格式视频

使用video.js还要加一个插件才能播放m3u8,video标签上还需要加一个type="application/x-mpegURL"属性

<script src="https://cdnjs.cloudflare.com/ajax/libs/video.js/7.3.0/video.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-contrib-hls/5.15.0/videojs-contrib-hls.min.js"></script>

<video
    src="xxx"
    class="video-js" 
    controls preload="auto" 
    autoplay
    loop
    data-setup="{}"
    crossorigin="anonymous"
    webkit-playsinline="true"
    x-webkit-airplay="true"
    playsinline="true"
    x5-video-player-type="h5"
    x5-video-player-fullscreen="true"
    type="application/x-mpegURL">
</video>

在IOS上出现的问题

网络原因

一开始播放不了以为是代码或是视频问题,其实网络问题也是一个重要的因素。

ios不支持视频格式

ios支持播放的视频编码其实很少,渲染出场景的前提是视频能够播放。

ios视频请求

ios无法播放视频,在网上看到这样一种解释:

ios在请求视频时,会先请求0-1个字节,写在请求头的range字段中:range:'bytes=0-1'。如果是想要传输视频,必须要解析range字段,然后按照range字段的要求返回对应的数据,同时response header至少要包含三个字段:Content-Type, Content-Range, Content-LengthContent-Type必需明确指定视频格式,有video/mp4, video/ogg, video/mov等等

这个需要后端处理,由于公司没有视频服务,只能作罢。
参考链接
https://www.zhihu.com/question/41818719
https://segmentfault.com/q/1010000012524886/a-1020000012526858

loadedmetadata事件:ios的微信浏览器上视频只有在点击播放时才会开始加载,在ios上可以通过loadedmetadata事件判断视频是否开始加载,再进行渲染。因此,当要获取视频时长(duration)时,ios的微信浏览器要开始播放才能获取得到。

this.on('loadedmetadata',function(){
    var u = navigator.userAgent
    var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
    if(isIOS){
        startRender(myPlayer)
    }
})

window.resize事件

问题:在ios上横屏播放时,获取到的window宽高是之前的宽高
方案:setTimeout延时获取,不知有没有更好的方法

function onWindowResize() {
    var width, height

    setTimeout(function() {
        width = window.innerWidth
        height = window.innerHeight

        camera.aspect = width / height
        camera.updateProjectionMatrix()
        renderer.setSize(width, height)
    }, 200)
}

注意:全屏时也需要重新设置renderer的大小,全屏时会触发resize事件,所以最好不用orientationchange事件判断横竖屏,否则全屏时可能会有问题。

总结

这次主要的问题还是视频在ios上无法播放。要锻炼的还是自己排查问题的能力。这次排查问题的主要思路:

  • 通过测试视频判断问题是出在播放器上还是视频上,或者是视频服务上
  • 视频在ios上是否能够直接播放
    • 网络问题
    • 是否因动态获取视频连接导致无法播放
    • ios是否支持视频格式
  • 视频能否成功渲染成全景场景
    • 是否在视频加载后才开始渲染
    • three.js各个参数设置是否正确
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容