美文网首页Vue
Vue接入监控视频技术总结

Vue接入监控视频技术总结

作者: HoPGoldy | 来源:发表于2019-03-03 17:35 被阅读2250次

    最近一直在搞监控视频接入方面的事情,积累了不少的经验,这里总结一下。提前说一句,本文提到的视频接入均是以RTSP为基础转码而来的,至于用海康大华等插件播放的咱们就闭口不提了可以看这个文章,在vue中接入ocx控件播放监控视频

    现在监控视频在前端的播放主要有如下三种方式:

    • RTSP视频流播放
    • RTMP视频流播放
    • HLS视频流播放

    RTSP

    咱们一种一种的说,首先是RTSP这种其实和海康插件是一样的,需要VLC插件的支持,所以也是要用老版本的浏览器才可以使用。其实刚接触的时候查到了一个js包vxg-video可以前端在线播放RTSP,但是接入的效果差强人意,虽然能播放但是延迟太高,遂放弃,感兴趣的可以自己了解一下。

    RTMP

    然后是RTMP视频流,这里放一个链接,感兴趣的可以自己了解它和RTSP有什么区别。

    RTSP协议、RTMP协议、HTTP协议的区别

    简单来说呢,就是RTMP是Adobe维护的,没开源,而RTSP和HTTP一样都是开源的。所以呢,要在前端播放RTMP视频就必须得使用flash插件,看主流浏览器对flash的态度,只能说且用且珍惜吧。

    现在在前端播放RTMP主要有三种方案,videojsjwplayerckplayer。先说接入效果吧,ckplayervideojs成功了,jwplayer虽然失败了,但是在这里也谈一下吧,记录下失败的地点,等日后有实力了再试试能不能成功。

    流行的不得了的videojs

    当初要做RTMP播放的时候我第一个想到的就是videojs,毕竟这个太流行了,也有大神给vue封装了videojs,名字叫做vue-video-player,这两者我都尝试了,很尴尬的是,引入原生videojs成功了,但是使用vue-video-player却失败了,可能是后者的作者大大很久没维护的原因了吧,下面先贴一下videojs播放的源码

    <template>
        <video id="my-player"
               class="video-js
                    vjs-default-skin
                    vjs-big-play-centered"
               preload="auto"
               width="500"
               height="400"
               data-setup='{ "html5" : { "nativeTextTracks" : false }}'>
        </video>
    </template>
    
    <script>
      /*  下载的包
         "video.js": "^5.6.0",
         "videojs-flash": "^2.2.0"
         "videojs-swf": "^5.4.2",
      */
        import videojs from 'video.js'
        import 'video.js/dist/video-js.css'
        import 'vue-video-player/src/custom-theme.css'
        import 'videojs-flash'
        import SWF_URL from 'videojs-swf/dist/video-js.swf'
        videojs.options.flash.swf = SWF_URL // 设置flash路径,Video.js会在不支持html5的浏览中使用flash播放视频文件
    
        export default {
            name: 'videojsTest',
            mounted(){
                this.player1 = videojs('my-player', this.VideoOptions, function onPlayerReady() {
                    videojs.log('播放器已经准备好了!')
                    this.on('play', function() {
                        console.log('开始/恢复播放')
                    })
                    this.on('pause', function() {
                        console.log('暂停播放')
                    })
                    this.on('ended', function() {
                        console.log('结束播放')
                    })
                })
                setTimeout(() => {
                    this.player1.player()
                }, 1000)
            },
            data () {
                return {
                    VideoOptions: {
                        autoplay: true, // 是否自动播放
                        muted: false, // 是否静音
                        controls: false,
                        fluid: true, // 宽高自适应
                        techOrder: ["flash"],
                        sources: [{
                            src: 'rtmp://192.168.100.205:10935/hls/stream_1',
                            type: 'rtmp'
                        }]
                    },
                }
            }
        }
    </script>
    

    在引入的时候要注意 video.js 的版本,6.0以上的版本有可能会出现问题,如果不行的话建议切换 5.6.0 版本。

    在引入的时候遇到了一个问题,这个看一下报错就清楚了,vue找不到swf文件的loader引起的,我使用vue-cli3搭建的项目,所以在vue.js.config里做了配置,如果你用的是webpack的话,在webpack.base.js里添加下就可以了,当然写法不一样,这里我都贴上了。

    swf文件解析失败

    vue.config.js

    module.exports = {
      // 选项...
      chainWebpack: config => {
        config.module
          .rule('swf')
          .test(/\.swf$/)
          .use('url-loader')
            .loader('url-loader')
            .tap(options => {
              return {
                limit: 10000
              }
            })
      }
    }
    

    webpack.base.js

    module: {
        rules: [
          {
            test: /\.swf$/,
            loader: 'url-loader',
            options: {
              limit: 1024,
              name: 'file/[path][name].[hash7].[ext]'
            }
          }
        ]
      }
    

    vue-video-player

    然后是使用vue-video-player集成的代码,大佬集成的很好,写起来很舒服:

    <template lang="pug">
        video-player(:options="playerOptions")
    </template>
    
    <script>
    import { videoPlayer } from 'vue-video-player'
    import 'video.js/dist/video-js.css'
    import 'videojs-flash'
    
    export default {
        data() {
            return {
                playerOptions: {
                    height: '360',
                    width: '500',
                    sources: [{
                        type: 'rtmp/mp4',
                        src: 'rtmp://192.168.100.205:10935/hls/stream_1'
                    }],
                    techOrder: ['flash'],
                    autoplay: true,
                    controls: true,
                },
            }
        },
        components: { videoPlayer },
        methods: { },
    }
    </script>
    

    但是测试的时候出问题了,很难受,一直在报The "flash" tech is undefined错误,试过很多方法,什么用cnpm代替npm下载啊、给videojs-flash添加file loader啊,无论怎么尝试都不行。如果有大佬知道请一定要教教我。

    vue-video-player集成失败

    CkPlayer

    然后就是Ckplayer的接入,这个算是比较简单的,因为ckplayer是静态的第三方依赖。所以我们要把他放在public(vue-cli3)或者static(vue-cli2)文件夹下,然后在index.html里引入,注意,这里要使用绝对路径引入,因为相对路径会被解析为非静态资源。

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
    
        <script src="ck/ckplayer.js"></script>
    
        <title>vue-project</title>
      </head>
      <body>
        <noscript>
          <strong>网站未响应,请稍后再试。</strong>
        </noscript>
        <div id="app"></div>
      </body>
    </html>
    

    引入之后就可以直接在组件里调用了:

    <style scoped lang="stylus">
        .video 
            height 400px
            width 800px
    </style>
    
    <template lang="pug">
        .video ckplayer将会挂载到该div上
    </template>
    
    <script>
    export default {
        data() { return { }},
        mounted() {
            var videoObject = {
                container: '.video', //容器的ID或className
                variable: 'player', //播放函数名称
                live: true,
                flashplayer: true,//如果强制使用flashplayer则设置成true
                video: 'rtmp://192.168.100.205:1935/oflaDemo/hkvideo'//视频地址
            }
            // 定义一个对象
            var player = new ckplayer(videoObject)
        }
    }
    </script>
    

    测试之后发现视频黑屏、控制台无报错、播放时间正常进行的问题

    无报错但视频黑屏

    经过搜索后解决了该问题,要先到ckplayer的源文件目录下打开ckplayer.js文件,然后修改bufferTime0playCorrecttrue,如下:

    function ckplayerConfig() {
        return {
            flashvars: {},//用来补充flashvars里的对象
            languagePath: '',//语言包文件地址
            stylePath: '',//风格包文件地址
            config: {
                ...
                bufferTime: 0,//缓存区的长度,单位:毫秒,不要小于10
                ...
                playCorrect: true,//是否需要错误修正,这是针对rtmp的
                ...
            }
        }
    }
    

    然后就可以播放了,但是还有个小问题,就是点击播放之后视频依旧黑屏,要再次暂停后点继续才可以正常播放。这个问题暂时没找到原因,ckplayer播放easyNVR转出来的 rtmp 源就可以,播放ffmpeg转出的 rtmp 就有这个问题,而videojs播放哪种源都是没问题的。videojs牛批!

    JwPlayer

    jwplayer和ckplayer一样都属于静态的第三方依赖,但是迷一般的,现在网上关于接入jwplayer的文章几乎为零,在遇到错误之后找不到解决方法,随放弃。下面贴一下代码和报错,求有缘人解决:

    <template lang="pug">
        .player
    </template>
    
    <script>
    export default {
        data() { return { }},
        mounted() {
            jwplayer('player').setup({
                'flashplayer': 'player.swf',
                'file': 'hkvideo',
                'streamer': 'rtmp://39.96.37.119/oflaDemo',
                'controlbar': 'bottom',
                'width': '848',
                'height': '360'
            })
        }
    }
    </script>
    
    jwplayer 报错信息

    HLS

    HLS是苹果公司提出的一种视频流类型,所以苹果的设备对它有原生支持,不过其他的浏览器也可以通过js包的形式进行播放,和rtmp相比,hls最大的坏处就是延迟高,rtmp基本可以控制在1秒内播放,而hls基本都是5-6秒开外。而且RTMP是基于TCP协议,播放更加的稳定。

    参考资料 - 维基百科 HLS

    我这里接入HLS也是用的vue-video-player,下面贴一下源码,我把它封装成了一个公共组件,只接受一个hls的播放地址src,调用时把播放地址传递进来就可以播放了,因为没有打印什么log,所以播放成功的页面就不截图了

    <style scoped lang="stylus">
        .size
            width 900px
    </style>
    
    <template lang="pug">
        video-player.size.video-player.vjs-custom-skin(ref="videoPlayer"
            :playsinline="true"
            :options="playerOptions")
    </template>
    
    <script>
    import videojs from 'video.js'
    import 'video.js/dist/video-js.css'
    import 'vue-video-player/src/custom-theme.css'
    import 'videojs-contrib-hls'
    import { videoPlayer } from 'vue-video-player'
    
    export default {
        name: 'IVideoPlayer',
        data() { return {  }},
        props: {
            src: String
        },
        components: { videoPlayer },
        computed: {
            playerOptions() {
                return {
                    autoplay: true, 
                    muted: false, 
                    loop: false, 
                    preload: 'auto', 
                    language: 'zh-CN',
                    aspectRatio: '16:9',
                    fluid: true,
                    sources: [{
                        type: "application/x-mpegURL",
                        src: this.src
                    }],
                    width: document.documentElement.clientWidth,
                    notSupportedMessage: ' ',//'此视频暂无法播放,请稍后再试',
                }
            }
        }
    }
    </script>
    

    总结

    最后总结一下,虽然海康插件和RTSP的形式可以播放,但是受浏览器限制的影响,最后是肯定需要放弃的,而RTMP播放质量高效果好,可以说是当下最值得应用的监控视频接入技术了,当然了,需要flash也确实要考虑进来,这个接入方案在未来估计也会逐渐的降温,然后是hls方案,这个对移动端的适配挺好,安卓和苹果的浏览器都提供了原生支持,所以移动端开发应该优先考虑这个方案。

    相关文章

      网友评论

        本文标题:Vue接入监控视频技术总结

        本文链接:https://www.haomeiwen.com/subject/qcdpuqtx.html