添加分屏插件

This commit is contained in:
杜海鹏 2022-07-22 11:50:00 +08:00
parent b8614392e2
commit 4099756085
5 changed files with 336 additions and 0 deletions

View File

@ -0,0 +1,61 @@
# lives
> A Vue.js project
## 使用
1. 安装依赖
```
// 安装
npm install --save flv.js
npm install --save js-md5
npm install --save js-base64
npm install --save axios
// 依赖包
"dependencies": {
"axios": "^0.27.2",
"flv.js": "^1.6.2",
"js-base64": "^3.7.2",
"js-md5": "^0.7.3",
}
```
2. 引入插件
```
// Test.vue
import Live from '@/utils'
```
3. 调用 api
```
<template>
<!-- 为需要注入分屏插件的容器元素设置 id并设定宽高 -->
<div id="wrapper" style="width: 1200px;height: 800px"> </div>
</template>
// 调用 init 方法,传入绑定的 dom 元素注入分屏插件
mounted () {
// 1. 登录
Live.login('http://122.112.239.62', '9000', 'jxj', 'admin123')
// 2. 绑定插件
this.screens = Live.init(document.getElementById('wrapper'))
// 3. 配置参数加载视频
this.screens.setOptions(/* 这里传入配置对象 */ {
deviceId: '1202291000447',
channelNum: 1,
streamType: 0,
mediaType: 'FLV',
recordTimeStart: '2022-07-16 04:00:00',
recordTimeEnd: '2022-07-16 06:00:00',
source: 'device',
isDownload: 0,
tokenType: 'Dynamic',
expireTime: '0',
https: false
})
},
```

View File

@ -0,0 +1,25 @@
import http from './request'
export const apiLogin = (baseURL, Authorization, data = {}) => {
return http({
baseURL,
url: '/login',
method: 'post',
data,
headers: {
Authorization
}
})
}
export const apiQueryPlaybackUri = (baseURL, token, data) => {
return http({
baseURL,
url: '/queryPlaybackUri',
method: 'post',
data,
headers: {
token
}
})
}

View File

@ -0,0 +1,39 @@
.live-screens-screen-wrap {
position: relative;
background-color: #000;
}
.live-screens-screen-item {
box-sizing: border-box;
border: 1px solid #fff;
}
.live-screens-screen-close {
position: absolute;
width: 60px;
height: 30px;
line-height: 30px;
text-align: center;
color: red;
cursor: pointer;
}
.live-setting-btn-wrap {
margin-top:8px;
display: flex;
justify-content: flex-end;
}
.live-setting-btn-item {
margin-right: 10px;
width: 60px;
height: 30px;
line-height: 30px;
text-align:center;
border: 1px solid #666;
cursor: pointer;
}
.actived {
border: 1px solid orangered !important;
}

View File

@ -0,0 +1,204 @@
import flvjs from 'flv.js'
import md5 from 'js-md5'
import { encode } from 'js-base64'
import { apiLogin, apiQueryPlaybackUri } from './api'
import './index.css'
let baseURL = ''
let token = ''
let Authorization = ''
const screenTypes = [
{text: '一屏', value: 1},
{text: '二屏', value: 2},
{text: '四屏', value: 4},
{text: '六屏', value: 6}
]
const createVideoEl = (vm, index = 0, width = '100%', height = '100%') => {
const videoEl = document.createElement('video')
videoEl.setAttribute('muted', 'muted')
// videoEl.setAttribute('controls', 'controls')
videoEl.setAttribute('width', width)
videoEl.setAttribute('height', height)
videoEl.className = 'live-screens-screen-item'
videoEl.addEventListener('click', e => {
vm.currentScreen = e.target
vm.screenIndex = index
vm.screens.map(screen => screen.classList.remove('actived'))
e.target.classList.add('actived')
})
return videoEl
}
const createScreenWrap = (el) => {
const width = el.offsetWidth
const height = el.offsetHeight - 40
const screenWrap = document.createElement('div')
screenWrap.style.cssText = `width: ${width}px;height: ${height}px;`
screenWrap.className = 'live-screens-screen-wrap'
return screenWrap
}
const createScreens = (vm, screenWrapEl, screens, screenCount) => {
const w = screenWrapEl.offsetWidth
const h = screenWrapEl.offsetHeight
let width = ''
let height = ''
switch (screenCount) {
case 2:
width = w / 2 + 'px'
height = h + 'px'
break
case 4:
width = w / 2 + 'px'
height = h / 2 + 'px'
break
case 6:
width = w / 3 + 'px'
height = h / 2 + 'px'
break
default:
width = '100%'
height = '100%'
break
}
const list = new Array(screenCount).fill(0)
screens.map(child => screenWrapEl.removeChild(child))
screens.splice(0)
list.map((item, index) => {
const videoEl = createVideoEl(vm, index, width, height)
screenWrapEl.appendChild(videoEl)
screens.push(videoEl)
})
}
const createScreenBtns = (ins) => {
const screenBtnGroupEl = document.createElement('div')
screenBtnGroupEl.className = 'live-setting-btn-wrap'
screenTypes.map(type => {
const btnEl = document.createElement('div')
btnEl.className = 'live-setting-btn-item'
btnEl.innerText = type.text
btnEl.addEventListener('click', () => {
ins.setScreenCount(type.value)
})
screenBtnGroupEl.appendChild(btnEl)
})
return screenBtnGroupEl
}
const createCloseEl = (vm) => {
const w = vm.currentScreen.offsetWidth
// const h = vm.currentScreen.offsetHeight
const left = vm.currentScreen.offsetLeft
const top = vm.currentScreen.offsetTop
const el = document.createElement('div')
el.className = 'live-screens-screen-close'
el.innerText = '关闭'
el.style.top = top + 10 + 'px'
el.style.left = left + w - 60 + 'px'
el.setAttribute('data-index', vm.screenIndex)
el.addEventListener('click', e => {
const index = e.target.getAttribute('data-index')
const videoEl = vm.screens[index]
videoEl.removeAttribute('controls')
videoEl.removeAttribute('src')
vm.screenWrapEl.removeChild(e.target)
})
vm.screenWrapEl.appendChild(el)
vm.currentScreen = null
}
const Initial = class {
constructor (el) {
const screen1 = createVideoEl(this)
const screenWrapEl = createScreenWrap(el)
screenWrapEl.appendChild(screen1)
el.appendChild(screenWrapEl)
el.appendChild(createScreenBtns(this))
this.currentScreen = screen1
this.screenCount = 1
this.screenIndex = 0
this.wrapEl = el
this.screenWrapEl = screenWrapEl
this.screens = [screen1]
this.players = []
}
setOptions (options = {
deviceId: '1202291000447',
channelNum: 1,
streamType: 0,
mediaType: 'FLV',
recordTimeStart: '2022-07-16 04:00:00',
recordTimeEnd: '2022-07-16 06:00:00',
source: 'device',
isDownload: 0,
tokenType: 'Dynamic',
expireTime: '0',
https: false
}) {
if (!this.currentScreen || this.currentScreen.src) {
return false
}
(async () => {
const res = await apiQueryPlaybackUri(baseURL, token, options).catch(console.log)
if (res.status === 200) {
const url = res.data.uri
this.player = this.getVideoPlayer(url)
this.currentScreen.setAttribute('controls', 'controls')
createCloseEl(this)
}
})()
// return this
}
getVideoPlayer (url) {
if (flvjs.isSupported()) {
const videoEl = this.currentScreen
const flvPlayer = flvjs.createPlayer({
type: 'flv',
url: url.replace('http://:9050', 'http://122.112.239.62:9050')
})
flvPlayer.attachMediaElement(videoEl)
flvPlayer.load()
// flvPlayer.play()
return flvPlayer
}
}
setScreenCount (screenCount) {
this.screenCount = screenCount
const closeEls = document.getElementsByClassName('live-screens-screen-close')
;[].slice.call(closeEls).map(el => this.screenWrapEl.removeChild(el))
createScreens(this, this.screenWrapEl, this.screens, screenCount)
}
}
const init = (el) => {
const screen = new Initial(el)
return {
setOptions: screen.setOptions.bind(screen)
}
}
const encryption = (host, port, username, pwd) => {
baseURL = `${host}:${port}`
const md5Pwd = md5(pwd)
Authorization = 'Basic ' + encode(username + ':' + md5Pwd)
}
const login = async (host, port, username, pwd) => {
encryption(host, port, username, pwd)
const res = await apiLogin(baseURL, Authorization).catch(console.log)
if (res.status === 200) {
token = res.headers.token
}
}
export default {
login,
init
}

View File

@ -0,0 +1,7 @@
import axios from 'axios'
const http = axios.create({
// baseURL: 'http://122.112.239.62:9000'
})
export default http