import { Zondy } from '../../base'
import { LoadStatus, VideoSourceType } from '../../base/enum'
import { defaultValue, defined, getVideoType, Log } from '../../util'
import { Layer } from './baseLayer'
/**
* 视频地图图层
* @private
* @class VideoMapLayer
* @moduleEX LayerModule
* @extends Evented
* @param {Object} options 构造参数
* @param {Extent} [options.Extent = undefined] 图层范围
* @param {String} [options.id = ''] 图层ID
* @param {Boolean} [options.visible = true] 图层可见性
* @param {String} [options.description = ''] 图层描述信息
* @param {String} [options.copyright = '中地数码版权所有'] 版权
* @param {SpatialReference} [options.spatialReference = undefined] 图层坐标系
* @param {String} [options.loadStatus = LoadStatus.notLoaded] 图层状态
* @param {String} [options.source] 视频地图图层视频源地址
* @param {String} [options.container] 视频图层容器
*/
class VideoMapLayer extends Layer {
constructor(options) {
super(options)
options = defaultValue(options, {})
this._source = defaultValue(options.source, null)
if (!this._source) {
Log.error('The video source is lost.')
return
}
if (typeof options.container === 'string') {
this._container = document.getElementById(options.container)
} else {
this._container = options.container
}
if (!this._container) {
Log.error('The videoHTML container is lost.')
return
}
if (!defined(window.videojs)) {
Log.error('The video.js library is lost.')
return
}
this._videoHtml = null
this._hlsPlayer = null
this._rtmpPlayer = null
this._width = 0
this._height = 0
}
get videoHtml() {
return this._videoHtml
}
get rtmpPlayer() {
return this._rtmpPlayer
}
get width() {
return this._width
}
get height() {
return this._height
}
/**
* @function VideoMapLayer.prototype.isLoaded
* @description 判断图层是否加载成功
* @return {Boolean} 图层加载状态
*/
isLoaded() {
if (this.loadStatus === LoadStatus.loaded) {
return true
} else {
return false
}
}
/**
* @function VideoMapLayer.load
* @description 图层资源加载
* @return {Promise<Layer>} 资源加载完毕的图层
*/
load() {
const videoType = getVideoType(this._source)
return new Promise((resolve, reject) => {
if (videoType === VideoSourceType.videoPlayer) {
this._source.on('play', () => {
this._width = this._source.videoWidth()
this._height = this._source.videoHeight()
resolve(this)
})
return
} else if (videoType === VideoSourceType.videoHTML) {
this._width = this._source.videoWidth
this._height = this._source.videoHeight
resolve(this)
return
}
this._videoHtml = document.createElement('video')
this._videoHtml.id = 'video'
this._videoHtml.style.position = 'absolute'
this._videoHtml.style.zIndex = '0'
this._container.appendChild(this._videoHtml)
// rtmp流中所有的标签页都需要有width,height
// **特别注意必须要先设置样式的width和height**,否则rtmp视频流不会播放
this._videoHtml.style.width = '100%'
this._videoHtml.style.height = '100%'
if (videoType === VideoSourceType.mp4) {
// ---------mp4-----------
this._videoHtml.crossOrigin = 'anonymous'
this._videoHtml.autoplay = true
this._videoHtml.loop = true
this._videoHtml.src = this._source
this._videoHtml.play()
this._videoHtml.controls = true
} else if (videoType === VideoSourceType.hls) {
// ---------hls-----------
this._hlsPlayer = videojs(this._videoHtml)
this._hlsPlayer.src({
type: 'application/x-mpegURL',
src: this._source
})
this._hlsPlayer.load(this._source)
this._hlsPlayer.play()
this._hlsPlayer.loop(true)
const videoHTML = this._hlsPlayer.el().querySelector('video')
videoHTML.controls = true
} else if (videoType === VideoSourceType.rtmp) {
// ---------rtmp-----------
this._rtmpPlayer = videojs(
this._videoHtml,
{
sources: [
{
src: this._source,
type: 'rtmp/flv'
}
]
},
() => {
this._rtmpPlayer.play()
this._rtmpPlayer.loop(true)
}
)
this._rtmpPlayer.on('play', () => {
this._rtmpPlayer.width(this._rtmpPlayer.videoWidth())
this._rtmpPlayer.height(this._rtmpPlayer.videoHeight())
this._videoHtml.oncanplay()
})
}
this._videoHtml.oncanplay = () => {
this.loadStatus = LoadStatus.loaded
this.loaded = true
this._width = this._videoHtml.videoWidth
? this._videoHtml.videoWidth
: this._rtmpPlayer
? this._rtmpPlayer.videoWidth()
: 1
this._height = this._videoHtml.videoHeight
? this._videoHtml.videoHeight
: this._rtmpPlayer
? this._rtmpPlayer.videoHeight()
: 1
this._videoHtml.style.width = this._width
this._videoHtml.style.height = this._height
resolve(this)
}
this._videoHtml.onerror = () => {
let err = '未知错误'
switch (this._videoHtml.error.code) {
case 1:
err = '视频加载中断'
break
case 2:
err = '网络链接错误'
break
case 3:
err = '视频解码失败'
break
case 4:
err = '不支持的视频'
break
}
Log.error(`出现错误:${err}错误代码:${this._videoHtml.error.code}`)
this.loadStatus = LoadStatus.failed
reject(this._videoHtml.error)
}
})
}
}
Zondy.Layer.VideoMapLayer = VideoMapLayer
export default VideoMapLayer