You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
5.4 KiB
203 lines
5.4 KiB
let EZUIKitPlayerClass = null
|
|
|
|
let loadPromise = null
|
|
|
|
|
|
|
|
// scaleMode: 0=拉伸 1=等比完整显示 2=等比填满(会超出容器裁切)
|
|
|
|
const DEFAULT_SCALE_MODE = 1
|
|
|
|
|
|
|
|
function pickEZUIKitPlayer(mod) {
|
|
|
|
if (!mod) {
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
|
|
|
|
const candidates = [
|
|
|
|
mod.EZUIKitPlayer,
|
|
|
|
mod.default?.EZUIKitPlayer,
|
|
|
|
mod.default?.default?.EZUIKitPlayer,
|
|
|
|
typeof mod.default === 'function' ? mod.default : null
|
|
|
|
]
|
|
|
|
|
|
|
|
for (const item of candidates) {
|
|
|
|
if (typeof item === 'function') {
|
|
|
|
return item
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function loadEZUIKitPlayer() {
|
|
|
|
if (EZUIKitPlayerClass) {
|
|
|
|
return EZUIKitPlayerClass
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!loadPromise) {
|
|
|
|
loadPromise = import('ezuikit-js').then((mod) => {
|
|
|
|
EZUIKitPlayerClass = pickEZUIKitPlayer(mod)
|
|
|
|
if (!EZUIKitPlayerClass) {
|
|
|
|
throw new Error('EZUIKitPlayer 加载失败')
|
|
|
|
}
|
|
|
|
return EZUIKitPlayerClass
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
return loadPromise
|
|
|
|
}
|
|
|
|
|
|
|
|
export function resolveEzopenUrl(camera, playerConfig = {}) {
|
|
|
|
if (!camera) {
|
|
|
|
return ''
|
|
|
|
}
|
|
|
|
|
|
|
|
if (camera.ezopenUrl) {
|
|
|
|
return camera.ezopenUrl
|
|
|
|
}
|
|
|
|
|
|
|
|
const priority = playerConfig.urlPriority || ['hdPlayUrl', 'playUrl', 'ezopenUrl']
|
|
|
|
for (const key of priority) {
|
|
|
|
const value = camera[key]
|
|
|
|
if (value && String(value).startsWith('ezopen://')) {
|
|
|
|
return value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const serial = camera.serialNumber || camera.serial_number
|
|
|
|
const channel = camera.channelNumber ?? camera.channel_number ?? 1
|
|
|
|
if (serial) {
|
|
|
|
const quality = playerConfig.ezviz?.defaultQuality || 'hd.live'
|
|
|
|
return `ezopen://open.ys7.com/${serial}/${channel}.${quality}`
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const key of priority) {
|
|
|
|
const value = camera[key]
|
|
|
|
if (value) {
|
|
|
|
return value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ''
|
|
|
|
}
|
|
|
|
|
|
|
|
export function buildEzvizDomId(playerId) {
|
|
|
|
return `ezviz-player-${String(playerId).replace(/[^a-zA-Z0-9_-]/g, '_')}`
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getPlayerMeasureTarget(containerEl) {
|
|
|
|
return containerEl?.closest?.('.screen-body') || containerEl
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getPlayerMeasureSize(containerEl) {
|
|
|
|
const target = getPlayerMeasureTarget(containerEl)
|
|
|
|
const width = Math.floor(target.clientWidth || target.getBoundingClientRect().width)
|
|
|
|
const height = Math.floor(target.clientHeight || target.getBoundingClientRect().height)
|
|
|
|
return {
|
|
|
|
width: width > 0 ? width : 640,
|
|
|
|
height: height > 0 ? height : 360
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function syncPlayerContainer(containerEl) {
|
|
|
|
if (!containerEl) {
|
|
|
|
return { width: 0, height: 0 }
|
|
|
|
}
|
|
|
|
const measureTarget = getPlayerMeasureTarget(containerEl)
const { width, height } = getPlayerMeasureSize(containerEl)
measureTarget.style.overflow = 'hidden'
containerEl.style.width = `${width}px`
containerEl.style.height = `${height}px`
containerEl.style.maxWidth = `${width}px`
containerEl.style.maxHeight = `${height}px`
return { width, height }
}
function resolveScaleMode(playerConfig = {}) {
const mode = playerConfig.ezviz?.scaleMode
return mode === 0 || mode === 1 || mode === 2 ? mode : DEFAULT_SCALE_MODE
}
export function applyPlayerLayout(player, containerEl, playerConfig = {}) {
if (!player || !containerEl) {
return { width: 0, height: 0 }
}
const scaleMode = resolveScaleMode(playerConfig)
const { width, height } = syncPlayerContainer(containerEl)
if (typeof player.setScaleMode === 'function') {
player.setScaleMode(scaleMode)
}
if (width > 0 && height > 0) {
if (typeof player.reSize === 'function') {
player.reSize(width, height)
} else if (typeof player.resize === 'function') {
player.resize(width, height)
}
}
return { width, height }
}
export async function createEzvizPlayer(containerEl, { url, accessToken, playerConfig = {} }) {
if (!containerEl || !url || !accessToken) {
return null
}
const EZUIKitPlayer = await loadEZUIKitPlayer()
const scaleMode = resolveScaleMode(playerConfig)
const { width, height } = syncPlayerContainer(containerEl)
const player = new EZUIKitPlayer({
id: containerEl.id,
accessToken,
url,
width,
height,
staticPath: playerConfig.staticPath || '/ezuikit_static',
template: playerConfig.ezviz?.template || 'simple',
scaleMode,
audio: playerConfig.ezviz?.audio ?? false
})
const relayout = () => applyPlayerLayout(player, containerEl, playerConfig)
requestAnimationFrame(relayout)
window.setTimeout(relayout, 100)
if (player?.eventEmitter?.on) {
player.eventEmitter.on('firstFrameDisplay', relayout)
player.eventEmitter.on('decoderLoaded', relayout)
player.eventEmitter.on('resize', relayout)
}
return player
}
export async function destroyEzvizPlayer(player) {
if (!player) {
return
}
try {
if (typeof player.stop === 'function') {
await player.stop()
}
} catch (_) {
// ignore stop errors during teardown
}
try {
if (typeof player.destroy === 'function') {
player.destroy()
}
} catch (_) {
// ignore destroy errors during teardown
}
}
export async function resizeEzvizPlayer(player, containerEl, playerConfig = {}) {
applyPlayerLayout(player, containerEl, playerConfig)
}
|