vue + video.js 加载多种视频流(HLS、FLV、RTMP、RTSP)

起因: 由于需要在一个项目内接入多种常用的视频流,所以接触到video.js,这里就做个记录。

框架: vue2 + video.js + videojs-contrib-hls + videojs-flvjs-es6 + videojs-flash + video-js.swf

vue安装就不讲了,直接从项目开始了。

第一步:安装依赖

bash 复制代码
// video.js
npm install video.js
// 安装hls,用于播放 HLS
npm install  videojs-contrib-hls
// 安装flv,用于播放 FLV
npm install videojs-flvjs-es6
npm install flv.js
// 安装flash 用于播放 RTMP
npm install videojs-flash
npm install videojs-swf

依赖版本:

javascript 复制代码
"flv.js": "^1.6.2",
"video.js": "^7.21.5",
"videojs-contrib-hls": "^5.15.0",
"videojs-flash": "^2.2.1",
"videojs-flvjs-es6": "^1.0.1",
"videojs-swf": "^5.4.2",

说明:比较重要,有很多坑

  1. 安装 videojs-swf 是因为 RTMP 必须用 flash 播放( RTMP 是由 Adobe 公司基于 Flash Player 播放器对应的音视频 FLV 封装格式提出的一种,基于TCP 的数据传输协议),video.js 里面使用 flash 是需要引入 swf 文件路径的,所以这里需要安装一下,方便引用,当然也可以自己下载后放在资源目录里面引用。
  2. 安装以上依赖的时候要注意,要用 npm 安装,在查资料的时候,发现有些文章说用 cnpm 安装会出现一些问题,不过我没遇到,不过为了避免还是慎重吧(毕竟像我这种学艺不精的,有些问题解决起来挺玄学的)。
  3. 针对 RTMP 的说明,截止目前(2023.08.30)Chrome浏览器(114版本)和 Microsoft Edge(116版本) 已经不支持 flash 了,反正我找了半天没找到设置的地方,最终还是在360浏览器上才勉强测试了 RTMP 的播放。
  4. 对于 videojs-flash 这个插件需要 video.js 版本的配合,如果版本不对,就会一直报错(The "flash" tech is undefined. Skipped browser support check for that tech.),解决方案是找到 videojs-flash 里面匹配的版本,然后更换 video.js 版本,就可以解决了,具体的方法,文章后面会详细介绍的。

第二步:引入依赖

javascript 复制代码
import videojs from 'video.js'
import 'video.js/dist/video-js.min.css'
import 'videojs-contrib-hls'
import 'videojs-flvjs-es6'
import 'videojs-flash'
import SWF_URL from 'videojs-swf/dist/video-js.swf'

第三步:创建播放器(播放视频流)

html 部分

html 复制代码
<template>
    <div ref="videoPlayerBox" class="component">
        <video class="videoPlayer video-js"></video>
    </div>
</template>

JS 部分

javascript 复制代码
<template>
    <div ref="videoPlayerBox" class="component">
        <video class="videoPlayer video-js"></video>
    </div>
</template>
<script>
import { VueExtend } from 'vdrag-lib'
import videojs from 'video.js'
import 'video.js/dist/video-js.min.css'
import 'videojs-contrib-hls'
import 'videojs-flvjs-es6'
import 'videojs-flash'
import SWF_URL from 'videojs-swf/dist/video-js.swf'

export default {
    data () {
        return {
            player: null,
            streamType: 'RTMP',
            streamURL: 'rtmp://mobliestream.c3tv.com:554/live/goodtv.sdp'
        }
    },
    watch: {
        streamType: function () {
            console.log('change streamType')
            this.$nextTick(() => {
                this.loadPlayer()
            })
        },
        streamURL: function () {
            console.log('change streamURL')
            this.$nextTick(() => {
                this.loadPlayer()
            })
        },
    },
    mounted () {
        this.initPlayer()
    },
    beforeDestroy () {
        this.disposePlayer()
    },
    methods: {
        // 初始化播放器
        initPlayer () {
            this.$nextTick(() => {
                let playerOption = {
                    preload: 'auto', // 预加载
                    autoplay: true, // 自动播放
                    controls: true,
                    techOrder: ['html5', 'flvjs', 'flash'], // 这里的顺序一定要 'flvjs' 在 'flash' 前面,要不然 flv 格式的就无法播放了
                    // 如果报 app.js:242798 Uncaught TypeError: this.el_.vjs_getProperty is not a function 错误,只保留 'flash' 就不报错了
                    // 报错 The "flash" tech is undefined. Skipped browser support check for that tech. 可以查看 videojs-flash 里面 node_modules 查看需要的 video.js 的版本,然后修改video.js的版本就可以了
                    flash: {
                        hls: { withCredentials: false },
                        swf: SWF_URL // 引入静态文件swf
                    },
                    flvjs: {
                        mediaDataSource: {
                            cors: true,
                            withCredentials: false,
                        },
                    },
                    sources: [
                        {
                            src: this.streamURL,
                            type: this.getType(this.streamType)
                        }
                    ],
                }

                this.player = videojs(this.$el.querySelector('.videoPlayer'), playerOption, function onPlayerReady () {
                    console.log('onPlayerReady', this)
                })
            })
        },
        // 重新加载播放器
        loadPlayer () {
            this.$refs.videoPlayerBox.innerHTML = `<video class="videoPlayer video-js"></video>`
            this.$nextTick(() => {
                this.initPlayer()
            })
        },
        // 销毁播放器
        disposePlayer () {
            if (this.player) {
                this.player.dispose()
            }
        },
        getType (type) {
            let playerType = ''
            switch (type) {
                case 'FLV':
                    playerType = 'video/x-flv'
                    break
                case 'HLS':
                    playerType = 'application/x-mpegURL'
                    break
                case 'RTMP':
                    playerType = 'rtmp/flv'
                    break
                case 'RTSP':
                    playerType = 'video/mp4'
                    break
            }
            return playerType
        }
    }
}
</script>
相关推荐
ziyue75754 分钟前
vue修改element-ui的默认的class
前端·vue.js·ui
树叶会结冰25 分钟前
HTML语义化:当网页会说话
前端·html
冰万森31 分钟前
解决 React 项目初始化(npx create-react-app)速度慢的 7 个实用方案
前端·react.js·前端框架
牧羊人_myr44 分钟前
Ajax 技术详解
前端
浩男孩1 小时前
🍀封装个 Button 组件,使用 vitest 来测试一下
前端
蓝银草同学1 小时前
阿里 Iconfont 项目丢失?手把手教你将已引用的 SVG 图标下载到本地
前端·icon
布列瑟农的星空1 小时前
重学React —— React事件机制 vs 浏览器事件机制
前端
程序定小飞2 小时前
基于springboot的在线商城系统设计与开发
java·数据库·vue.js·spring boot·后端
一小池勺2 小时前
CommonJS
前端·面试