添加分屏插件
This commit is contained in:
parent
b8614392e2
commit
4099756085
61
src/plugins/screens/README.md
Normal file
61
src/plugins/screens/README.md
Normal 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
|
||||||
|
})
|
||||||
|
},
|
||||||
|
```
|
||||||
25
src/plugins/screens/api.js
Normal file
25
src/plugins/screens/api.js
Normal 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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
39
src/plugins/screens/index.css
Normal file
39
src/plugins/screens/index.css
Normal 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;
|
||||||
|
}
|
||||||
204
src/plugins/screens/index.js
Normal file
204
src/plugins/screens/index.js
Normal 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
|
||||||
|
}
|
||||||
7
src/plugins/screens/request.js
Normal file
7
src/plugins/screens/request.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
const http = axios.create({
|
||||||
|
// baseURL: 'http://122.112.239.62:9000'
|
||||||
|
})
|
||||||
|
|
||||||
|
export default http
|
||||||
Loading…
x
Reference in New Issue
Block a user