| | |
| | | </template> |
| | | <script> |
| | | export default { |
| | | name: 'VueAliplayerV2', |
| | | name: "VueAliplayerV2", |
| | | props: { |
| | | source: { //播放源(此属性存在则优先于options.source) 动态切换,目前只支持同种格式(mp4/flv/m3u8)之间切换。暂不支持直播rtmp流切换。 |
| | | source: { |
| | | //播放源(此属性存在则优先于options.source) 动态切换,目前只支持同种格式(mp4/flv/m3u8)之间切换。暂不支持直播rtmp流切换。 |
| | | required: false, |
| | | type: [String], |
| | | default: null |
| | | default: null, |
| | | }, |
| | | markers: { |
| | | required: false, |
| | | type: Array, |
| | | default: null |
| | | } |
| | | default: null, |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | player: null, //播放器实例 |
| | | playerId: `player-${Math.random().toString(36).substr(2).toLocaleUpperCase()}`, |
| | | player: null, //播放器实例 |
| | | playerId: `player-${Math.random() |
| | | .toString(36) |
| | | .substr(2) |
| | | .toLocaleUpperCase()}`, |
| | | cssLink: `/apps/shuohuangMonitorAnalyze/aliplayer-min.css`, |
| | | scriptSrc: `/apps/shuohuangMonitorAnalyze/aliplayer-min.js`, |
| | | config: { |
| | | id: null, //播放器的ID |
| | | width: '100%', |
| | | height: '100%', |
| | | id: null, //播放器的ID |
| | | width: "100%", |
| | | height: "100%", |
| | | autoplay: false, |
| | | // skinLayout: false, |
| | | progressMarkers: false, |
| | |
| | | // source: 'rtmp://182.145.195.238:1935/hls/1194076936807170050', |
| | | skinLayout: [ |
| | | { |
| | | "name": "bigPlayButton", |
| | | "align": "blabs", |
| | | "x": 30, |
| | | "y": 80 |
| | | name: "bigPlayButton", |
| | | align: "blabs", |
| | | x: 30, |
| | | y: 80, |
| | | }, |
| | | { |
| | | "name": "H5Loading", |
| | | "align": "cc" |
| | | name: "H5Loading", |
| | | align: "cc", |
| | | }, |
| | | { |
| | | "name": "errorDisplay", |
| | | "align": "tlabs", |
| | | "x": 0, |
| | | "y": 0 |
| | | name: "errorDisplay", |
| | | align: "tlabs", |
| | | x: 0, |
| | | y: 0, |
| | | }, |
| | | { |
| | | "name": "infoDisplay" |
| | | name: "infoDisplay", |
| | | }, |
| | | { |
| | | "name": "tooltip", |
| | | "align": "blabs", |
| | | "x": 0, |
| | | "y": 56 |
| | | name: "tooltip", |
| | | align: "blabs", |
| | | x: 0, |
| | | y: 56, |
| | | }, |
| | | { |
| | | "name": "thumbnail" |
| | | name: "thumbnail", |
| | | }, |
| | | { |
| | | "name": "controlBar", |
| | | "align": "blabs", |
| | | "x": 0, |
| | | "y": 0, |
| | | "children": [ |
| | | name: "controlBar", |
| | | align: "blabs", |
| | | x: 0, |
| | | y: 0, |
| | | children: [ |
| | | { |
| | | "name": "progress", |
| | | "align": "blabs", |
| | | "x": 0, |
| | | "y": 44 |
| | | name: "progress", |
| | | align: "blabs", |
| | | x: 0, |
| | | y: 44, |
| | | }, |
| | | { |
| | | "name": "playButton", |
| | | "align": "tl", |
| | | "x": 15, |
| | | "y": 12 |
| | | name: "playButton", |
| | | align: "tl", |
| | | x: 15, |
| | | y: 12, |
| | | }, |
| | | { |
| | | "name": "timeDisplay", |
| | | "align": "tl", |
| | | "x": 10, |
| | | "y": 7 |
| | | name: "timeDisplay", |
| | | align: "tl", |
| | | x: 10, |
| | | y: 7, |
| | | }, |
| | | { |
| | | "name": "fullScreenButton", |
| | | "align": "tr", |
| | | "x": 10, |
| | | "y": 12 |
| | | name: "fullScreenButton", |
| | | align: "tr", |
| | | x: 10, |
| | | y: 12, |
| | | }, |
| | | { |
| | | "name": "volume", |
| | | "align": "tr", |
| | | "x": 5, |
| | | "y": 10 |
| | | } |
| | | ] |
| | | }] |
| | | name: "volume", |
| | | align: "tr", |
| | | x: 5, |
| | | y: 10, |
| | | }, |
| | | ], |
| | | }, |
| | | ], |
| | | }, |
| | | options: { |
| | | // source:'//player.alicdn.com/video/aliyunmedia.mp4', |
| | | isLive: false, //切换为直播流的时候必填 |
| | | controlBarVisibility: "always", |
| | | isLive: false, //切换为直播流的时候必填 |
| | | controlBarVisibility: "hover", |
| | | preload: true, |
| | | playsinline: true, |
| | | language: "zh-cn", |
| | | |
| | | // useFlashPrism: false, //指定为flash |
| | | // disableSeek: true //禁用进度条的Seek,默认值为false |
| | | // disableSeek: true //禁用进度条的Seek,默认值为false |
| | | }, |
| | | events: [ |
| | | /** |
| | |
| | | * 播放器UI初始设置需要此事件后触发,避免UI被初始化所覆盖。 |
| | | * 播放器提供的方法需要在此事件发生后才可以调用。 |
| | | */ |
| | | 'ready', |
| | | "ready", |
| | | /** |
| | | * 视频由暂停恢复为播放时触发。 |
| | | */ |
| | | 'play', |
| | | "play", |
| | | /** |
| | | * 视频暂停时触发。 |
| | | */ |
| | | 'pause', |
| | | "pause", |
| | | /** |
| | | * 能够开始播放音频/视频时发生,会多次触发,仅H5播放器。 |
| | | */ |
| | | 'canplay', |
| | | "canplay", |
| | | /** |
| | | * 播放中,会触发多次。 |
| | | */ |
| | | 'playing', |
| | | "playing", |
| | | /** |
| | | * 当前视频播放完毕时触发。 |
| | | */ |
| | | 'ended', |
| | | "ended", |
| | | /** |
| | | * 直播流中断时触发。 |
| | | * m3u8/flv/rtmp在重试5次未成功后触发。 |
| | | * 提示上层流中断或需要重新加载视频。 |
| | | * PS:m3u8一直自动重试,不需要上层添加重试。 |
| | | */ |
| | | 'liveStreamStop', |
| | | "liveStreamStop", |
| | | /** |
| | | * m3u8直播流中断后重试事件,每次断流只触发一次。 |
| | | */ |
| | | 'onM3u8Retry', |
| | | "onM3u8Retry", |
| | | /** |
| | | * 控制栏自动隐藏事件。 |
| | | */ |
| | | 'hideBar', |
| | | "hideBar", |
| | | /** |
| | | * 控制栏自动显示事件。 |
| | | */ |
| | | 'showBar', |
| | | "showBar", |
| | | /** |
| | | * 数据缓冲事件。 |
| | | */ |
| | | 'waiting', |
| | | "waiting", |
| | | /** |
| | | * 播放位置发生改变时触发,仅H5播放器。 |
| | | * 可通过getCurrentTime方法,得到当前播放时间。 |
| | | */ |
| | | 'timeupdate', |
| | | "timeupdate", |
| | | /** |
| | | * 截图完成。 |
| | | */ |
| | | 'snapshoted', |
| | | "snapshoted", |
| | | /** |
| | | * 全屏事件,仅H5支持。 |
| | | */ |
| | | 'requestFullScreen', |
| | | "requestFullScreen", |
| | | /** |
| | | * 取消全屏事件,iOS下不会触发,仅H5支持。 |
| | | */ |
| | | 'cancelFullScreen', |
| | | "cancelFullScreen", |
| | | /** |
| | | * 错误事件。 |
| | | */ |
| | | 'error', |
| | | "error", |
| | | /** |
| | | * 开始拖拽,参数返回拖拽点的时间。 |
| | | */ |
| | | 'startSeek', |
| | | "startSeek", |
| | | /** |
| | | * 完成拖拽,参数返回拖拽点的时间。 |
| | | */ |
| | | 'completeSeek' |
| | | "completeSeek", |
| | | ], |
| | | }; |
| | | }, |
| | | watch: { |
| | | source() { //监听播放源变化 |
| | | source() { |
| | | //监听播放源变化 |
| | | this.init(); |
| | | }, |
| | | |
| | | options: { //配置项是对象,只能深度监听 |
| | | options: { |
| | | //配置项是对象,只能深度监听 |
| | | handler() { |
| | | this.init(); |
| | | }, |
| | | deep: true |
| | | } |
| | | deep: true, |
| | | }, |
| | | |
| | | markers(newVal) { |
| | | this.player.setProgressMarkers(newVal); |
| | | }, |
| | | }, |
| | | mounted() { |
| | | this.$nextTick(() => { |
| | |
| | | }); |
| | | }, |
| | | methods: { |
| | | |
| | | /** |
| | | * 创建script和css |
| | | * 加载Alipayer的SDK |
| | | */ |
| | | init() { |
| | | const linkID = 'app__aliplayer-min-css'; |
| | | const scriptID = 'app__aliplayer-min-js'; |
| | | const head = document.getElementsByTagName('head'); |
| | | const html = document.getElementsByTagName('html'); |
| | | const linkID = "app__aliplayer-min-css"; |
| | | const scriptID = "app__aliplayer-min-js"; |
| | | const head = document.getElementsByTagName("head"); |
| | | const html = document.getElementsByTagName("html"); |
| | | let scriptTag = document.getElementById(scriptID); |
| | | let linkIDTag = document.getElementById(linkID); |
| | | if (!linkIDTag) { |
| | | // console.log('linkIDTag'); |
| | | const link = document.createElement('link'); |
| | | link.type = 'text/css'; |
| | | link.rel = 'stylesheet'; |
| | | const link = document.createElement("link"); |
| | | link.type = "text/css"; |
| | | link.rel = "stylesheet"; |
| | | link.href = this.cssLink; |
| | | link.id = linkID; |
| | | // link.className = linkID; |
| | |
| | | } |
| | | if (!scriptTag) { |
| | | // console.log('scriptTag'); |
| | | scriptTag = document.createElement('script'); |
| | | scriptTag = document.createElement("script"); |
| | | scriptTag.type = "text/javascript"; |
| | | scriptTag.id = scriptID; |
| | | // scriptTag.className = scriptID; |
| | | scriptTag.src = this.scriptSrc; |
| | | html[0].appendChild(scriptTag); |
| | | } else { |
| | | this.initPlayer(); //这样是为了兼容页面上有多个播放器 |
| | | this.initPlayer(); //这样是为了兼容页面上有多个播放器 |
| | | } |
| | | //兼容单页加载和硬加载 |
| | | scriptTag.addEventListener("load", () => { |
| | |
| | | * @description SDK文档地址:https://help.aliyun.com/document_detail/125572.html?spm=a2c4g.11186623.6.1084.131d1c4cJT7o5Z |
| | | */ |
| | | initPlayer() { |
| | | if (typeof window.Aliplayer != 'undefined') { |
| | | if (typeof window.Aliplayer != "undefined") { |
| | | const options = this.deepCloneObject(this.options); |
| | | if (options) { |
| | | for (const key in options) { |
| | |
| | | this.config.id = this.playerId; //赋值播放器容器id |
| | | this.config.progressMarkers = this.markers; // 标注 |
| | | // console.log("alipayer config", this.config); |
| | | this.player && this.player.dispose(); //防止实例的重复 |
| | | this.player && this.player.dispose(); //防止实例的重复 |
| | | this.player = Aliplayer(this.config); |
| | | for (const ev in this.events) { |
| | | this.player && this.player.on(this.events[ev], (e) => { |
| | | // console.log(`object ${this.events[ev]}`,e); |
| | | this.$emit(this.events[ev], e); |
| | | }); |
| | | this.player && |
| | | this.player.on(this.events[ev], (e) => { |
| | | // console.log(`object ${this.events[ev]}`,e); |
| | | this.$emit(this.events[ev], e); |
| | | }); |
| | | } |
| | | //通过播放器实例的off方法取消订阅 |
| | | //player.off('ready',handleReady); |
| | |
| | | * @param 播放凭证 |
| | | * @description 仅MPS用户时使用 仅MPS用户时使用 参数顺序为:vid、accId、accSecret、stsToken、authInfo、domainRegion |
| | | */ |
| | | replayByVidAndAuthInfo(vid, accId, accSecret, stsToken, authInfo, domainRegion) { |
| | | replayByVidAndAuthInfo( |
| | | vid, |
| | | accId, |
| | | accSecret, |
| | | stsToken, |
| | | authInfo, |
| | | domainRegion |
| | | ) { |
| | | // console.log(`replayByVidAndAuthInfo 参数顺序为:vid、accId、accSecret、stsToken、authInfo、domainRegion`,vid, accId, accSecret, stsToken, authInfo, domainRegion); |
| | | this.player && this.player.replayByVidAndAuthInfo(vid, accId, accSecret, stsToken, authInfo, domainRegion); |
| | | this.player && |
| | | this.player.replayByVidAndAuthInfo( |
| | | vid, |
| | | accId, |
| | | accSecret, |
| | | stsToken, |
| | | authInfo, |
| | | domainRegion |
| | | ); |
| | | }, |
| | | |
| | | /** |
| | |
| | | */ |
| | | requestFullScreen() { |
| | | // console.log(`播放器全屏,仅H5支持`); |
| | | this.player && this.player.fullscreenService && this.player.fullscreenService.requestFullScreen(); |
| | | this.player && |
| | | this.player.fullscreenService && |
| | | this.player.fullscreenService.requestFullScreen(); |
| | | }, |
| | | |
| | | /** |
| | |
| | | */ |
| | | cancelFullScreen() { |
| | | // console.log(`播放器全屏,仅H5支持`); |
| | | this.player && this.player.fullscreenService && this.player.fullscreenService.cancelFullScreen(); |
| | | this.player && |
| | | this.player.fullscreenService && |
| | | this.player.fullscreenService.cancelFullScreen(); |
| | | }, |
| | | |
| | | /** |
| | |
| | | */ |
| | | getIsFullScreen() { |
| | | // console.log(`获取播放器全屏状态,仅H5支持。`,this.player && this.player.fullscreenService && this.player && this.player.fullscreenService.getIsFullScreen()); |
| | | return this.player && this.player.fullscreenService && this.player.fullscreenService.getIsFullScreen(); |
| | | return ( |
| | | this.player && |
| | | this.player.fullscreenService && |
| | | this.player.fullscreenService.getIsFullScreen() |
| | | ); |
| | | }, |
| | | |
| | | /** |
| | |
| | | */ |
| | | setLiveTimeRange(beginTime, endTime) { |
| | | // console.log(`设置直播的开始时间:${beginTime},结束时间:${endTime},开启直播时移功能时使用。`); |
| | | this.player && this.player.liveShiftSerivce && this.player.liveShiftSerivce.setLiveTimeRange(beginTime, endTime); |
| | | this.player && |
| | | this.player.liveShiftSerivce && |
| | | this.player.liveShiftSerivce.setLiveTimeRange(beginTime, endTime); |
| | | }, |
| | | |
| | | /** |
| | |
| | | this.player && this.player.off(ev, handle); |
| | | }, |
| | | |
| | | |
| | | /** |
| | | * 深度拷贝 |
| | | * @param {*} obj |
| | | */ |
| | | deepCloneObject(obj) { |
| | | let objClone = Array.isArray(obj) ? [] : {}; |
| | | if (obj && typeof obj === 'object') { |
| | | if (obj && typeof obj === "object") { |
| | | for (let key in obj) { |
| | | if (Object.prototype.hasOwnProperty.call(obj, key)) { |
| | | //判断ojb子元素是否为对象,如果是,递归复制 |
| | | if (obj[key] && typeof obj[key] === 'object') { |
| | | if (obj[key] && typeof obj[key] === "object") { |
| | | objClone[key] = this.deepCloneObject(obj[key]); |
| | | } else { |
| | | //如果不是,简单复制 |
| | |
| | | } |
| | | } |
| | | return objClone; |
| | | } |
| | | |
| | | }, |
| | | }, |
| | | beforeDestroy() { //防止重复创建 |
| | | beforeDestroy() { |
| | | //防止重复创建 |
| | | this.dispose(); //销毁播放器(防止直播播放的情况下,播放器已经销毁,而后台还在继续下载资源造成卡顿的bug) |
| | | // const head = document.querySelector('head'); |
| | | // const cssNodes = document.querySelectorAll(`link.app__aliplayer-min-css`); |
| | |
| | | // (html && jsNodes.length > 1) && jsNodes.forEach((item, index)=>{ |
| | | // if(index != 0) html.removeChild(item); |
| | | // }); |
| | | } |
| | | }, |
| | | }; |
| | | </script> |
| | |
| | | |
| | | * { |
| | | box-sizing: content-box; |
| | | color: #425277; |
| | | } |
| | | .el-input__inner { |
| | | border: 1px solid #d7dce8; |
| | |
| | | padding: 10px 0 20px; |
| | | } |
| | | } |
| | | |
| | | .el-dialog__wrapper { |
| | | top: -22px; |
| | | } |
| | | .dialog-video { |
| | | .el-dialog { |
| | | width: 1340px; |
| | | top: 70px; |
| | | transform: none; |
| | | } |
| | | .el-dialog__body { |
| | | background: #eaeaea; |
| | |
| | | } |
| | | .dialog-event { |
| | | z-index: 2096 !important; |
| | | |
| | | .el-dialog { |
| | | width: 1000px; |
| | | height: 800px; |
| | |
| | | <div class="video-area"> |
| | | <!-- 播放器区域 --> |
| | | <div class="players" ref="playerWrap"> |
| | | <div class="single"></div> |
| | | <template v-if="guid == 1"> |
| | | <div |
| | | class="video-item" |
| | | class="video-item single" |
| | | :ref="`gridVideoItem_${index}`" |
| | | v-for="(item, index) in videoWrapArr" |
| | | :key="item.id" |
| | |
| | | <div style="display: none"></div> |
| | | <div class="currentPlayer"> |
| | | <ali-player |
| | | @pause="isStop = true" |
| | | @play="isStop = false" |
| | | @pause="singlePause" |
| | | @play="singlePlay" |
| | | @timeupdate="timeUpdate" |
| | | :source="curVideo.VideoPath | fixPath" |
| | | :markers="curVideo.marks" |
| | | :markers="marks_filter" |
| | | :ref="`player_${curVideo.id}`" |
| | | /> |
| | | </div> |
| | |
| | | <ali-player |
| | | @timeupdate="timeUpdate(e, index)" |
| | | :source="videoArrs[index].VideoPath | fixPath" |
| | | :markers="videoArrs[index].marks" |
| | | :markers="marks_filter_arr[index].marks" |
| | | @pause="isStop = true" |
| | | @play="isStop = false" |
| | | :ref="`player_${videoArrs[index].id}`" |
| | |
| | | <div class="progress-bar"> |
| | | <el-tooltip |
| | | placement="top" |
| | | v-for="(item, index) in eventMarks" |
| | | v-for="(item, index) in eventMarks_filter" |
| | | :key="item.offset + index" |
| | | > |
| | | <div slot="content"> |
| | |
| | | curTime(newVal) { |
| | | this.curPlayTime = this.getTimeStr(newVal); |
| | | }, |
| | | /* showHand() { |
| | | let arr = this.videoArrs.map((item) => { |
| | | item.marks = item.marks.filter((mark) => { |
| | | console.log(mark.text); |
| | | return mark.text != "手比: 手比"; |
| | | }); |
| | | }); |
| | | console.log(arr); |
| | | }, */ |
| | | }, |
| | | mounted() { |
| | | setTimeout(() => { |
| | | console.log(this.yinhuanArr); |
| | | }, 1000); |
| | | this.renderLabelOpts(); |
| | | |
| | | this.setGuid(1); |
| | | |
| | | this.getCurVideos(this.videoDetails); |
| | | |
| | | this.getRelatedVideos(this.videoDetails); |
| | | // this.getRelatedVideos(this.videoDetails); |
| | | }, |
| | | destroyed() { |
| | | this.videoArrs.length = 0; |
| | |
| | | this.progressChange(this.curTime); |
| | | }, |
| | | progressChange(val) { |
| | | this.showPlayBtn = false; |
| | | this.showPlayBtn = true; |
| | | let that = this; |
| | | if (this.guid == 1) { |
| | | this.$refs[`player_${this.curVideo.id}`][0].pause(); |
| | |
| | | } else { |
| | | this.videoArrs.forEach((v, i) => { |
| | | this.$refs[`player_${v.id}`][0].seek(val); |
| | | this.$refs[`player_${v.id}`][0].pause(); |
| | | if (i == 0) { |
| | | let curT = this.$refs[`player_${v.id}`][0].getCurrentTime(); |
| | | } |
| | |
| | | console.log(this.$refs); |
| | | }); |
| | | }, |
| | | |
| | | // 分窗口 |
| | | setGuid(guid) { |
| | | let _this = this; |
| | | this.guid = guid; |
| | |
| | | this.showLocChoise = true; |
| | | } else { |
| | | this.showLocChoise = false; |
| | | console.log(this.$refs[`player_${this.curVideo.id}`]); |
| | | this.$refs[`player_${this.curVideo.id}`][0].pause(); |
| | | this.$refs[`player_${this.curVideo.id}`][0].seek(0); |
| | | } |
| | |
| | | closeHand() { |
| | | this.showHand = false; |
| | | }, |
| | | singlePause() { |
| | | this.isStop = true; |
| | | this.showPlayBtn = true; |
| | | }, |
| | | singlePlay() { |
| | | this.isStop = false; |
| | | this.showPlayBtn = false; |
| | | }, |
| | | }, |
| | | computed: { |
| | | yinhuanArr() { |
| | | console.log(this.curVideo.IsOperate); |
| | | if (this.curVideo.IsOperate == 0) { |
| | | return []; |
| | | } |
| | | console.log(this.eventMarks); |
| | | return this.eventMarks.filter((x) => { |
| | | return ( |
| | | (x.text.indexOf("进出站") > -1 || |
| | |
| | | x.state == 0 |
| | | ); |
| | | }); |
| | | }, |
| | | marks_filter() { |
| | | if (this.showHand) { |
| | | return this.curVideo.marks; |
| | | } else |
| | | return this.curVideo.marks.map((item) => { |
| | | if (item.text != "手比: 手比") { |
| | | return item; |
| | | } |
| | | }); |
| | | }, |
| | | marks_filter_arr() { |
| | | if (this.showHand) { |
| | | return this.videoArrs; |
| | | } else { |
| | | let arr = this.videoArrs.map((item) => { |
| | | let obj = { ...item }; |
| | | let temp = []; |
| | | obj.marks.forEach((mark) => { |
| | | if (mark.text != "手比: 手比") { |
| | | temp.push(mark); |
| | | } |
| | | }); |
| | | obj.marks = temp; |
| | | return obj; |
| | | }); |
| | | return arr; |
| | | } |
| | | }, |
| | | eventMarks_filter() { |
| | | if (this.showHand) { |
| | | return this.eventMarks; |
| | | } else { |
| | | let arr = []; |
| | | this.eventMarks.map((item) => { |
| | | if (item.text != "手比: 手比") { |
| | | arr.push(item); |
| | | } |
| | | }); |
| | | return arr; |
| | | } |
| | | }, |
| | | }, |
| | | }; |
| | |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | height: 512px; |
| | | .single { |
| | | .prism-controlbar { |
| | | display: none !important; |
| | | } |
| | | } |
| | | .video-item { |
| | | background: black; |
| | | box-sizing: border-box; |
| | |
| | | } |
| | | } |
| | | } |
| | | .el-tooltip__popper { |
| | | * { |
| | | color: #fff; |
| | | } |
| | | } |
| | | |
| | | .prism-marker-text { |
| | | p { |
| | | color: #fff; |
| | | } |
| | | } |
| | | |
| | | .video-box-top b { |
| | | color: #fff; |
| | | } |
| | | </style> |