<template>
<div>
<div class="video-box" :style="isTabsBoxOpen ? 'width: 70%':'width: 100%'">
<video
:src="cTwoVideoUlr"
ref="myvideo1"
class="isVideo"
:style="myStyle"
@canplay="getTotal"
@timeupdate="timeupdate"
v-if="cTwoVideoUlr"
playsinline
playsinline=""
></video>
<video
:src="cVideoUlr"
@mouseover="handleMouseOver()"
@mousemove.self="handleMouseMove()"
@dblclick="toggleFullScreen()"
ref="myvideo"
@click="play"
@canplay="getTotal"
@timeupdate="timeupdate"
:class=" ['object-fit: cover']"
playsinline
v-if="cVideoUlr"
:style="videoItem"
playsinline=""
></video>
<transition name="fade">
<div @mouseover="ctrlMouseOver" v-show="isShowOperate">
<div class="progress">
<el-slider
v-model="currentTimeVal"
:max="durationProgress"
:show-tooltip="false"
@change="getNewTime"
>
</el-slider>
<div
v-for="(marker, index) in markers"
:key="index"
class="marker"
:style="{ left: `${marker.time}%` }"
>
<div class="marker-dot" @click="getNewTime(marker.times)"></div>
<div class="marker-name">{{ marker.text }}</div>
</div>
</div>
<div class="control">
<div class="flex-center">
<i
class="iconfonts"
:class="
isPaused
? 'iconzanting1 el-icon-video-pause'
: 'iconicon_play el-icon-video-play'
"
@click="play()"
></i>
<span class="time">{{ currentTime }} / {{ totalTime }}</span>
</div>
<div class="flex">
<div class="line" @click="isLine('none')">
<div class="flex">
<i class="el-icon-connection"></i>
</div>
<div>{{display ? '隐藏':'显示'}}</div>
</div>
<div class="line" @click="isLine('is_video')">
<div class="flex">
<i class="el-icon-sort"></i>
</div>
<div>交换</div>
</div>
<div
class="line"
@click="isLine('leftTop')"
:style="{ color: leftTop ? 'orange' : '' }"
>
<div class="flex">
<i class="el-icon-top-left"></i>
</div>
<div>左上</div>
</div>
<div
class="line"
@click="isLine('leftBottom')"
:style="{ color: leftBottom ? 'orange' : '' }"
>
<div class="flex">
<i class="el-icon-bottom-left"></i>
</div>
<div>左下</div>
</div>
<div
class="line"
@click="isLine('rightTop')"
:style="{ color: rightTop ? 'orange' : '' }"
>
<div class="flex">
<i class="el-icon-top-right"></i>
</div>
<div>右上</div>
</div>
<div
class="line"
@click="isLine('rightBottom')"
:style="{ color: rightBottom ? 'orange' : '' }"
>
<div class="flex">
<i class="el-icon-bottom-right"></i>
</div>
<div>右下</div>
</div>
<div class="line" @click="isLine('leftright')"
:style="{ color: leftright ? 'orange' : '' }"
>
<div class="flex">
<i class="el-icon-rank"></i>
</div>
<div>左右</div>
</div>
<div class="line" @click="isLine(1)">
<div class="flex">
<img
src="../../assets/image/line.png"
v-if="is_line"
alt=""
/>
<img src="../../assets/image/is_line.png" v-else alt="" />
</div>
<div>线路1</div>
</div>
<div class="line" @click="isLine(2)">
<div class="flex">
<img
src="../../assets/image/line.png"
v-if="is_line2"
alt=""
/>
<img src="../../assets/image/is_line.png" v-else alt="" />
</div>
<div>线路2</div>
</div>
<i class="iconfont el-icon-help" @click="toggleFullScreen"></i>
</div>
</div>
</div>
</transition>
</div>
<video
ref="myvideo2"
class="video-js vjs-default-skin vjs-big-play-centered"
style="width: 100%"
v-if="cVideoUlr"
@seeked="onSeeked"
@pause='handlePause'
@play="onPlay"
playsinline
>
<source id="source" :src="cVideoUlr" />
</video>
<el-dialog
title="修改"
:visible.sync="isUpdataCourseEvaluation"
width="50%">
<el-input
type="textarea"
:rows="12"
placeholder="请修改课评"
v-model="courseEvaluation">
</el-input>
<span slot="footer" class="dialog-footer">
<el-button @click="isUpdataCourseEvaluation = false">取 消</el-button>
<el-button type="primary" @click="UpdataCourseEvaluation">确 定</el-button>
</span>
</el-dialog>
<el-dialog
title="修改"
:visible.sync="isUpdataCourseEvaluationSections"
width="50%">
<el-input
type="textarea"
:rows="4"
placeholder="请修改"
v-model="sectionsTitle">
</el-input>
<span slot="footer" class="dialog-footer">
<el-button @click="isUpdataCourseEvaluationSections = false">取 消</el-button>
<el-button type="primary" @click="submitSections">确 定</el-button>
</span>
</el-dialog>
<el-dialog
title="修改"
:visible.sync="isUpdataTree"
width="50%">
<el-input
type="textarea"
:rows="4"
placeholder="请修改"
v-model="treeName">
</el-input>
<span slot="footer" class="dialog-footer">
<el-button @click="isUpdataTree = false">取 消</el-button>
<el-button type="primary" @click="submitTree">确 定</el-button>
</span>
</el-dialog>
<el-dialog
title="历史记录"
:visible.sync="isRecords"
width="50%">
<el-select
v-model="isType"
placeholder="类型"
clearable
size="small"
@change="records"
style="width: 150px;margin-bottom:20px"
>
<el-option
v-for="dict in recordsList"
:key="dict.value"
:label="dict.name"
:value="dict.value"
></el-option>
</el-select>
<el-table
:data="courseList"
width="100%"
border
>
<el-table-column
prop="nickName"
label="修改人"
align="left"
show-overflow-tooltip
width="100"
>
</el-table-column>
<el-table-column
prop="content"
label="修改内容"
align="left"
show-overflow-tooltip
>
<template slot-scope="{row}">
<div v-html="row.content"></div>
</template>
</el-table-column>
<el-table-column
prop="createTime"
label="修改时间"
align="left"
show-overflow-tooltip
width="120"
>
</el-table-column>
</el-table>
<span slot="footer" class="dialog-footer">
<el-button @click="isRecords = false">取 消</el-button>
</span>
</el-dialog>
<el-dialog
title="生成ppt"
:visible.sync="visible"
width="80%">
<iframe
:src='getUrlParams()'
width="100%"
height="800px"
v-if="visible"
frameborder="0"
seamless
></iframe>
<span slot="footer" class="dialog-footer">
<el-button @click="cancel">取消</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import videojs from "video.js";
import "video.js/dist/video-js.css";
import "videojs-contrib-hls";
import {
getVideo,
getCheckVideo,
getStrongVideo,
fabulousCourse,
getVodVideoEnd,
getUserCourseNote,
addCourseNote,
updateCourseEvaluation,
getCourseEvaluationHistory,
courseEvaluationAnalysis
} from "@/api/course/course";
import * as echarts from "echarts";
import getTreeConfig from '../coursemanage/course/config/getTreeConfig'
export default {
name: "error",
data() {
return {
subArray: {
tableContents:{
structureList:[]
}
},
visible:false,
isRecords:false,
recordsList:[
{
name:'Ai评课',
value:0,
},
{
name:'课程导读',
value:1,
},
{
name:'思维脑图',
value:2,
},
],
isTabsBoxOpen: true,
activeName: 'courseEvaluation',
courseEvaluation:'',
textarea:'',
isUpdataCourseEvaluation:false,
isUpdataCourseEvaluationSections:false,
sectionsTitle:'',
timePoint:null,
treeName:null,
treeNameCopy:null,
mindMap:null,
display:true,
bodyStyle:{
background: '#F3F2FF',
cursor: 'pointer',
},
isUpdataTree:false,
volume: 30, // 音量
videochannalList: [], // 全部视频
timeout1: null, // 定时器
fullFlag: false, // 是否全屏(默认否)
isShowOperate: false, // 是否显示播放控件(默认否)
val:'rightBottom',
// 选集列表
videoinglist: [
{
url: "https://www.yy.com/ftpurl/medical-record/video/2020/07/01/1593596146146382.mp4",
channelDesc: "导播",
},
{
url: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4",
channelDesc: "导播",
},
],
cVideoUlr: "",
// "https://cdn-nas.eduzhida.com/2023/09/22/198415ea-6d6f-4c2a-9a9a-690c73e6d159.mp4", // 正在播放视频地址
cTwoVideoUlr: "",
videoItem:{},
myvideo: "",
myvideo1: "",
isPaused: false, //标记当前的播放状态
currentTime: "00:00", //当前播放时间
totalTime: "00:00", //总时长
currentTimeVal: 0, // 进度条当前播放时间,必须是number类型
durationProgress: 0, // 进度条的最大值,必须是number类型
currentIndex: "",
leftTop: false,
leftBottom: false,
rightTop: false,
rightBottom: true,
leftright:false,
is_line: true,
is_line2: false,
player: "",
markers: [],
courseKnowledgeList:[],
isType:0,
courseList:[],
myStyle: {
bottom: "90px",
right: "30%",
},
};
},
beforeDestroy() {
// 恢复浏览器滚动
this.enableScroll();
document.removeEventListener(
"fullscreenchange",
this.handleFullScreenChange
);
},
watch:{
durationProgress:function(newValue, oldValue){
if(this.courseKnowledgeList.length){
this.markers = this.courseKnowledgeList.map((ele) => {
let percentage = (ele.time / newValue) * 100;
let roundedPercentage = Number(percentage) - 2;
return {
time: roundedPercentage.toFixed(0),
text: ele.text,
times: ele.time,
};
});
}
}
},
mounted() {
//获取播放器元素
this.disableScroll();
document.addEventListener("fullscreenchange", this.handleFullScreenChange);
this.getVVideo(this.$route.query.id);
},
methods: {
cancel(){
this.visible = false
},
DownLoadPPT(row){
this.visible = true
},
handleCourseEvaluationAnalysis(){
courseEvaluationAnalysis(this.$route.query.id,this.$route.query.iscType == 0 ? 0 :1)
this.msgSuccess(`课评已在分析,请稍后刷新页面查看`)
},
handleCourseEvaluationAnalysis(){
courseEvaluationAnalysis(this.$route.query.id,this.$route.query.iscType == 0 ? 0 :1)
this.msgSuccess(`课评已在分析,请稍后刷新页面查看`)
},
getUrlParams () {
let htmlTagRegex = /<\/?[a-zA-Z][^>]*>/g;
const test = this.subArray.courseEvaluation.replace(htmlTagRegex, '')
let test1 = test.replace(/"/g, '')
console.log(test1);
return `https://ppt.bsyxedu.com?userId=${this.$route.query.id}_couser&test=${test1}`
// return `http://192.168.8.182:5173?userId=${this.$route.query.id}_couser&test=${test1}`
},
records(type){
if(!type && type !=0){
this.isType = 0
switch (this.activeName){
case 'courseEvaluation':
this.isType = 0
break;
case 'first':
this.isType = 1
break;
case 'second':
this.isType = 2
break;
}
}
let param = {
courseId:this.$route.query.id,
type:type ? type :this.isType
}
this.isRecords = true
this.$forceUpdate()
getCourseEvaluationHistory(param).then(res=>{
this.courseList = res.data
})
},
handelsections(item){
this.isUpdataCourseEvaluationSections = true
this.sectionsTitle = item.title
this.timePoint = item.timePoint
console.log(item);
},
submitSections(){
let name = ''
this.subArray.tableContents.structureList.forEach((ele)=>{
ele.sections.find(row=>{
if(row.timePoint == this.timePoint){
name = row.title
row.title = this.sectionsTitle
}
})
})
let param = {
cId:this.$route.query.id,
tableContents:JSON.stringify(this.subArray.tableContents),
historyContent:`${name}---> ${this.sectionsTitle}`
}
updateCourseEvaluation(param).then(res=>{
if(res.code == 200){
this.msgSuccess(res.msg)
this.isUpdataCourseEvaluationSections = false
}
})
},
UpdataCourseEvaluation(){
let param = {
cId:this.$route.query.id,
courseEvaluation:this.courseEvaluation,
historyContent:this.courseEvaluation,
}
updateCourseEvaluation(param).then(res=>{
if(res.code == 200){
this.msgSuccess(res.msg)
this.isUpdataCourseEvaluation = false
this.subArray.courseEvaluation = this.courseEvaluation.replace(/\n/g, '<br>')
}
})
},
toggleTabsBox() {
this.isTabsBoxOpen = !this.isTabsBoxOpen;
console.log(this.val,'val');
console.log(this.myStyle,'myStyle');
if(this.val == "rightTop" ){
if(this.isTabsBoxOpen){
this.myStyle = { top: "0", right: "30%" };
}else{
this.myStyle = { top: "0", right: "0" };
}
}
else if(this.val == "rightBottom" ){
if(this.isTabsBoxOpen){
this.myStyle = { bottom: "90px", right: "30%" };
}else{
this.myStyle = { bottom: "90px", right: "0" };
}
this.videoItem = {
width: `100%`,
}
}else if(this.val == "leftright" ){
const videoBox = document.querySelector('.video-box');
const isVideo = document.querySelector('.isVideo');
const top = `${Math.max(0, (videoBox.offsetHeight - isVideo.offsetHeight) / 2 -90)}px`
if(this.isTabsBoxOpen){
this.videoItem = {
width: videoBox.offsetWidth/2 +'px',
height: 'auto',
marginTop: top
}
this.myStyle = { width: videoBox.offsetWidth/2 +'px !important', height: 'auto !important', right:'30%' ,marginTop: top };
}else{
this.videoItem = {
width: videoBox.offsetWidth/2 +'px',
height: 'auto',
marginTop: '15%'
}
this.myStyle = { width: videoBox.offsetWidth/2 +'px !important', height: 'auto !important', right:'0' ,marginTop: '15%' };
}
} else if(this.val == 'none'){
if(this.isTabsBoxOpen){
if(this.myStyle?.right){
this.myStyle.right = "30%"
}
}else{
if(this.myStyle?.right){
this.myStyle.right = "0"
}
}
}
},
handleResize() {
this.$nextTick(() => {
if (this.points) {
this.points.resize();
}
});
},
submitTree(){
console.log(this.treeName);
const findNodeByName = this.findNodeByName(this.mindMap,this.treeNameCopy)
console.log(findNodeByName);
findNodeByName.name = this.treeName
let param = {
cId:this.$route.query.id,
mindMap:JSON.stringify(this.mindMap),
historyContent:`${this.treeNameCopy}---> ${this.treeName}`
}
updateCourseEvaluation(param).then(res=>{
if(res.code == 200){
this.isUpdataTree = false
this.msgSuccess(res.msg)
this.points.setOption(getTreeConfig(this.mindMap));
}
})
},
initChart(data) {
this.$nextTick(() => {
console.log(data,'data');
this.points = echarts.init(this.$refs.points, "macarons");
this.points.setOption(getTreeConfig(data));
this.points.on('click',(params)=>{
this.treeName = params.name
this.treeNameCopy = params.name
if(this.permissions.includes('*:*:*') || this.permissions.includes('course:knowledge:evaluation')){
this.isUpdataTree = true
}
})
});
},
findNodeByName(root, targetName) {
// 1. 检查当前节点的name是否匹配目标
if (root.name === targetName) {
return root; // 找到目标节点,返回
}
// 2. 递归遍历子节点(如果有children)
if (root.children && Array.isArray(root.children)) {
for (const child of root.children) {
// 递归查找子节点
const found = this.findNodeByName(child, targetName);
if (found) { // 子节点中找到目标,提前返回
return found;
}
}
}
// 3. 未找到目标节点
return null;
},
cardClick(item){
const timePoint = item.timePoint.split('-')[0]; // 将时间字符串分割成小时、分钟和秒
const time = this.timeToSeconds(timePoint)
// const player = videojs(document.querySelector("video"))
// player.currentTime(time || 0)
this.getNewTime(time)
},
timeToSeconds(timeStr) {
const parts = timeStr.split(':').map(Number);
let seconds = 0;
if (parts.length === 3) { // 完整格式 HH:mm:ss
seconds = parts[0] * 3600 + parts[1] * 60 + parts[2];
} else if (parts.length === 2) { // 省略小时格式 mm:ss
seconds = parts[0] * 60 + parts[1];
} else if (parts.length === 1) { // 仅秒数格式 ss
seconds = parts[0];
}
return seconds;
},
handleSubmit(){
if(!this.textarea) return
else{
addCourseNote({courseId:this.$route.query.id,content:this.textarea,type:this.$route.query.iscType == 0 ? 0 :1}).then(res=>{
if(res.code == 200)
this.msgSuccess('保存成功')
})
}
},
handleClick(tab, event) {
console.log(tab);
if(tab.name == "third"){
getUserCourseNote({courseId:this.$route.query.id,type:this.$route.query.iscType == 0 ? 0 :1}).then(res=>{
this.textarea = res.data ? res.data.content :''
// this.subArray = data
})
}else if(tab.name =="second"){
this.initChart(JSON.parse(this.subArray.mindMap))
}
},
onPlay() {
console.log('Video is playing...');
const customElement = document.querySelector('.overlay-module');
customElement.play()
},
handlePause(event) {
// 处理视频暂停的逻辑
console.log('Video paused at time:', event.target.currentTime);
const customElement = document.querySelector('.overlay-module');
customElement.pause()
},
onSeeked(event){
const video = event.target;
const currentTime = video.currentTime;
console.log('用户点击进度条,当前时间:', currentTime);
const customElement = document.querySelector('.overlay-module');
customElement.currentTime = currentTime
},
getUrl(id, name) {
console.log(name, "namee");
if (name == "getVideo") {
this.getVVideo(id);
} else if (name == "getCheckVideo") {
this.getEVideo(id);
} else if (name == "getStrongVideo") {
this.getSVideo(id);
} else {
this.getBoutiqueVideo(id);
}
},
//播放课程视频
getVVideo(id) {
getVideo(id).then((res) => {
const { cVideoUlr, cTwoVideoUlr } = res.data;
this.cTwoVideoUlr = cTwoVideoUlr;
this.cVideoUlr = cVideoUlr;
this.subArray = res.data;
if(this.subArray.tableContents){
this.subArray.tableContents = JSON.parse(this.subArray.tableContents)
}
this.courseEvaluation = res.data.courseEvaluation
if(this.subArray.courseEvaluation){
this.subArray.courseEvaluation = res.data.courseEvaluation.replace(/\n/g, '<br>')
}
this.mindMap = JSON.parse(this.subArray.mindMap)
// this.$route.query.id;
this.$nextTick(() => {
this.myvideo = this.$refs.myvideo;
this.myvideo1 = this.$refs.myvideo1;
this.myvideo1.volume = 0
let arr = [],
result = [];
if (res.data?.courseKnowledgeList) {
arr = res.data.courseKnowledgeList.map((ele) => {
return { time: ele.payDateSeconds, text: ele.knowledgeName };
});
this.courseKnowledgeList = arr
}
console.log(this.courseKnowledgeList,'courseKnowledgeList');
const player1 = videojs(this.$refs.myvideo);
player1.on("play", () => {
if (player1.userActive()) {
this.$nextTick(() => {
console.log('demo');
this.demo(result);
});
// 执行其他操作...
}
});
this.$nextTick(() => {
const player = videojs(
this.$refs.myvideo2,
{
controls: true,
},
() => {
player.pause();
}
);
if (arr.length) {
result = arr.map((item) => item.text);
}
console.log(arr,'arr');
player.markers({
markerTip: {
display: true,
text: function (marker) {
return `${marker.text}`;
},
},
markerStyle: {
// 标记点样式
width: "1em",
height: "1em",
bottom: "-0.20em",
"border-radius": "50%",
"background-color": "rgb(194,158,206)",
position: "absolute",
"font-size": "16px",
},
markers: arr,
});
});
});
// if(res.data.isXy == 1) url =res.data.cPlaybackUlr
// else url = res.data.cVideoUlr;
});
},
disableScroll() {
document.body.style.overflow = "hidden";
window.addEventListener("touchmove", this.preventDefault, {
passive: false,
});
},
enableScroll() {
document.body.style.overflow = "";
window.removeEventListener("touchmove", this.preventDefault);
},
preventDefault(event) {
event.preventDefault();
},
// 鼠标在控件内
ctrlMouseOver() {
clearTimeout(this.timeout1);
this.isShowOperate = true;
},
handleMouseOver() {
this.isShowOperate = true;
},
handleMouseMove() {
this.isShowOperate = true;
clearTimeout(this.timeout1); // 使用定时器前先清除定时器
this.timeout1 = setTimeout(() => {
this.isShowOperate = false;
}, 1000);
},
isLine(val) {
console.log(this.isTabsBoxOpen,'isTabsBoxOpen');
this.val = val
let isVideos = document.querySelector('.isVideo');
switch (val) {
case "none":
console.log(isVideos.style.display);
this.display = !this.display
isVideos.style.display = this.display ? 'block' :'none'
break ;
case "is_video":
let currentTime = this.$refs.myvideo.currentTime
let currentTime1 = this.$refs.myvideo1.currentTime
let cTwoVideoUlr = this.cTwoVideoUlr;
let cVideoUlr = this.cVideoUlr;
this.cVideoUlr = cTwoVideoUlr;
this.cTwoVideoUlr = cVideoUlr;
this.$nextTick(() => {
this.$refs.myvideo.currentTime = currentTime
this.$refs.myvideo1.currentTime = currentTime1
if(this.isPaused){
this.$refs.myvideo.play();
this.$refs.myvideo1.play();
}
})
break;
case 1:
this.is_line = !this.is_line;
console.log(this.is_line,'this.is_line');
this.myvideo.volume = this.is_line ? 1 : 0; //赋值
break;
case 2:
this.is_line2 = !this.is_line2;
this.myvideo1.volume = this.is_line2 ? 1 : 0; //赋值
break;
case "leftTop":
this.leftTop = true;
(this.leftBottom = false),
(this.rightTop = false),
(this.rightBottom = false);
this.leftright = false
this.myStyle = { top: "0", left: "0" };
this.videoItem = {
width: `100%`,
}
break;
case "leftBottom":
this.leftTop = false;
(this.leftBottom = true),
(this.rightTop = false),
(this.rightBottom = false);
this.leftright = false
this.myStyle = { bottom: "90px", left: "0" };
this.videoItem = {
width: `100%`,
}
break;
case "rightTop":
this.leftTop = false;
(this.leftBottom = false),
(this.rightTop = true),
(this.rightBottom = false);
this.leftright = false
if(this.isTabsBoxOpen){
this.myStyle = { top: "0", right: "30%" };
}else{
this.myStyle = { top: "0", right: "0" };
}
this.videoItem = {
width: `100%`,
}
break;
case "rightBottom":
this.leftTop = false;
(this.leftBottom = false),
(this.rightTop = false),
(this.rightBottom = true);
this.leftright = false
if(this.isTabsBoxOpen){
this.myStyle = { bottom: "90px", right: "30%" };
}else{
this.myStyle = { bottom: "90px", right: "0" };
}
this.videoItem = {
width: `100%`,
}
break;
case "leftright":
this.leftTop = false;
(this.leftBottom = false),
(this.rightTop = false),
(this.rightBottom = false);
this.leftright = true
const videoBox = document.querySelector('.video-box');
const isVideo = document.querySelector('.isVideo');
const top = `${Math.max(0, (videoBox.offsetHeight - isVideo.offsetHeight) / 2 -90)}px`
if(this.isTabsBoxOpen){
this.videoItem = {
width: videoBox.offsetWidth/2 +'px',
height: 'auto',
marginTop: top
}
this.myStyle = { width: videoBox.offsetWidth/2 +'px !important', height: 'auto !important', right:'30%' ,marginTop: top };
}else{
this.videoItem = {
width: videoBox.offsetWidth/2 +'px',
height: 'auto',
marginTop: '15%'
}
this.myStyle = { width: videoBox.offsetWidth/2 +'px !important', height: 'auto !important', right:'0' ,marginTop: '15%' };
}
break;
}
},
//获取课程详情
demo(list) {
const arr = list ?? [];
const transparentElements = document.querySelectorAll(".vjs-marker");
transparentElements.forEach(function (element, index) {
// 在这里对每个透明元素进行进一步的操作
const textNode = document.createElement("div");
textNode.textContent = arr[index];
var textLength = textNode.innerHTML.length;
var width = textLength * 10; // 假设每个字符宽度为 10px
textNode.style.whiteSpace = "nowrap";
textNode.style.position = "absolute";
textNode.style.bottom = "10px";
// textNode.style.color = 'orange'
// textNode.style.left = `-${width}px`
textNode.style.fontSize = "14px";
textNode.style.background = "rgba(0,0,0,0.5)";
textNode.style.padding = "10px";
textNode.classList.add("is_element");
element.insertBefore(textNode, element.firstChild);
});
},
// 选集
changevideo(val) {
console.log(val);
if (this.cVideoUlr == val) {
this.isPaused = false;
this.myvideo.pause();
}
},
play() {
//修改当前的播放状态
this.isPaused = !this.isPaused;
if (this.isPaused) {
this.myvideo.play();
this.myvideo1.play();
} else {
this.myvideo.pause();
this.myvideo1.pause();
}
},
// 进度条拖动时间
getNewTime(val) {
console.log(val);
this.myvideo.currentTime = val;
this.myvideo1.currentTime = val;
},
// 音量控制
getNewVoice(val) {
this.volume = val;
let newVc = val / 100; //h5规定,volume的值必须再0-1之间,比如0.5就是50%的音量,但是进度条的值为100,因此这里做个除法
this.myvideo.volume = newVc; //赋值
},
//时间格式化处理
timeFormat(time) {
let minute = Math.floor((time % 3600) / 60);
let second = Math.floor(time % 60);
minute = minute < 10 ? "0" + minute : minute;
second = second < 10 ? "0" + second : second;
return `${minute}:${second}`;
},
//获取总时长
getTotal() {
this.totalTime = this.timeFormat(this.myvideo.duration);
this.durationProgress = this.myvideo.duration;
// if(res.customKpointList.length){
// arr = res.customKpointList.map(ele=>{
// return {time:ele.nodeSeconds,text:ele.kpointName}
// })
// }
},
//获取当前视频播放到的时间
timeupdate() {
if (this.myvideo.currentTime == this.myvideo.duration) {
this.isPaused = !this.isPaused;
this.myvideo.pause();
this.myvideo1.pause();
}
this.currentTime = this.timeFormat(this.myvideo.currentTime);
this.currentTimeVal = this.myvideo.currentTime;
},
handleFullScreenChange() {
const playerVideo = this.$refs.myvideo2;
const that = this;
if (!document.fullscreenElement) {
that.myvideo.currentTime = playerVideo.currentTime;
that.myvideo1.currentTime = playerVideo.currentTime;
// that.isOpacity = false
this.$nextTick(()=>{
console.log(document.querySelectorAll('video')[2].style,'document.querySelectorAll("video")');
document.querySelectorAll('video')[2].style.width = 0
})
that.myvideo.play();
that.myvideo1.play();
this.myvideo1.volume = this.is_line2 ? 1 : 0; //赋值
this.myvideo.volume = this.is_line ? 1 : 0; //赋值
playerVideo.pause();
const customElement = document.querySelector('.overlay-module');
customElement.pause();
customElement.remove();
this.isPaused = true
// 执行退出全屏后的逻辑
}else{
this.$refs.myvideo.pause();
this.$refs.myvideo1.pause();
const playerVideo = this.$refs.myvideo;
// console.log(playerVideo.currentTime,'playerVideo.currentTime');
// // const isVideo = document.querySelector(".isVideo");
const newElement = document.createElement("video"); // 创建新的 div 元素
newElement.classList.add('overlay-module')
newElement.style.position = `absolute`;
newElement.style.objectFit = `cover`;
// newElement.style.right = `0`;
newElement.src = this.cTwoVideoUlr;
// newElement.controls = true;
// newElement.autoplay = true;
const video2 = document.querySelectorAll('.vjs-tech')[1]
console.log(this.myStyle,'this.myStyle');
console.log(video2,'this.video2');
console.log(newElement,'this.newElement');
if(this.myStyle?.height){
newElement.style.width = '50%';
newElement.style.height = 'auto';
newElement.style.top = '25%';
video2.style.width = '50%';
video2.style.top = '25%';
video2.style.height = 'auto';
}else{
newElement.style.width = '30%';
newElement.style.height = '30%';
video2.style.width = '100%';
video2.style.top = '0';
video2.style.height = '100%';
}
newElement.volume = 0
newElement.currentTime = playerVideo.currentTime
if(this.myStyle?.bottom){
console.log('bottom');
newElement.style.bottom = this.myStyle.bottom
}
if(this.myStyle?.right){
newElement.style.right = 0
}
if(this.myStyle?.top){
newElement.style.top = this.myStyle.top
console.log('top');
}
if(this.myStyle?.bottom){
newElement.style.left = this.myStyle.left
console.log('left');
}
newElement.autoplay = true
const videoJsContainer = document.querySelector(".video-js");
if(this.display){
videoJsContainer.appendChild(newElement);
}
}
},
//全屏切换
toggleFullScreen(event) {
this.$nextTick(() => {
this.$refs.myvideo.pause();
this.$refs.myvideo1.pause();
const player = videojs(this.$refs.myvideo2);
if (player) {
player.src({
src: this.cVideoUlr,
// type: 'video/mp4', // 根据你的视频格式来设置
});
// this.$refs.myvideo1.pause();
// 如果你想要在新的视频加载后立即播放,可以调用 player.play()
// 但是请注意浏览器对自动播放的限制
// this.player.play();
player.play()
player.volume = 0
}
player.currentTime(this.myvideo.currentTime);
//如果当前是全屏状态,就退出全屏,否则进入全屏状态
//获取当前的全屏状态
let isFullscreen = document.webkitIsFullScreen || document.fullscreen;
if (!isFullscreen) {
const inFun =
player.requestFullscreen || player.webkitRequestFullScreen;
//让当前播放器进入全屏状态
inFun.call(player);
console.log(1);
} else {
const exitFun =
document.exitFullscreen || document.webkitExitFullScreen;
//退出全屏状态要使用document
exitFun.call(document);
console.log(2);
// this.$refs.myvideo2.style.width='100px'
// this.$refs.myvideo2.style.height='100px'
}
// if (player.requestFullscreen) {
// player.requestFullscreen();
// } else if (player.mozRequestFullScreen) {
// player.mozRequestFullScreen(); // Firefox
// } else if (player.webkitRequestFullscreen) {
// player.webkitRequestFullscreen(); // Chrome, Safari and Opera
// } else if (player.msRequestFullscreen) {
// player.msRequestFullscreen(); // IE/Edge
// }
});
},
},
};
</script>
<style lang="scss" scoped>
.video-box,
.info-box {
// float: left;
background: #fff;
height: 100%;
box-sizing: border-box;
}
.iconfonts {
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
}
.iconfont {
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
cursor: pointer;
}
.courseEvaluation{
font-size: 14px;
color: #585a73;
line-height: 24px;
padding: 0 20px 0 10px;
}
.coures-icon{
font-size: 18px;
padding: 10px 20px 0 10px;
cursor: pointer;
}
.chapter{
font-size: 15px;
color: rgb(64, 64, 64);
margin: 20px 0;
}
.isOpen{
position: fixed;
// right: 0;
top: 50%;
z-index: 99;
cursor: pointer;
transition: right 0.3s ease;
color: #585a73;
.isOpen-icon{
font-size: 40px
}
}
.tabs-box.collapsed {
right: -30%;
}
.records{
position: absolute;
right: 30px;
top: 0px;
cursor: pointer;
z-index: 999;
}
.tabs-box{
width: 30%;
padding: 20px 30px;
height: 100%;
overflow-y: scroll;
position: fixed;
right: 0;
top: 0;
background-color: white;
transition: right 0.3s ease;
/deep/.el-tabs__item {
font-size: 16px;
}
.points {
width: 26vw;
height: 80vh;
display: flex;
align-items: center;
justify-content: center;
}
}
.primary-submit{
color: #FFFFFF;
background-color: #7F1083;
border-color: #7F1083;
text-align: center;
width: 80px;
cursor: pointer;
height: 30px;
border-radius: 4px;
font-size: 14px;
line-height: 30px;
margin: 0 auto;
margin-top: 20px;
}
.video-box {
width: 100%;
box-sizing: border-box;
position: relative;
height: 100vh;
overflow: hidden;
.isVideo {
width: 30% !important;
height: 30% !important;
position: fixed;
z-index: 99;
}
video {
width: 100%;
height: 100vh;
object-fit: cover;
cursor: pointer;
}
.control {
width: 100%;
height: 90px;
padding-top: 18px;
padding-right: 20px;
position: absolute;
bottom: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: space-between;
color: #fff;
.iconicon_play {
cursor: pointer;
width: 50px;
height: 50px;
}
.iconzanting1 {
cursor: pointer;
width: 50px;
height: 50px;
}
.line:hover {
color: orange;
}
.line {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 14px;
margin-right: 15px;
cursor: pointer;
img {
width: 25px;
height: 25px;
}
i {
font-size: 25px;
}
}
/deep/.el-select .el-input .el-select__caret {
color: #fff;
}
/deep/.el-input__inner {
color: #fff;
&::placeholder {
color: #fff;
}
&::-webkit-input-placeholder {
/* WebKit browsers 适配谷歌 */
color: #fff;
}
&:-moz-placeholder {
/* Mozilla Firefox 4 to 18 适配火狐 */
color: #fff;
}
&::-moz-placeholder {
/* Mozilla Firefox 19+ 适配火狐 */
color: #fff;
}
&:-ms-input-placeholder {
/* Internet Explorer 10+ 适配ie*/
color: #fff;
}
}
.time {
margin-left: 0.22rem;
color: #f5f5fa;
}
.iconyinliang-gao {
margin-left: 2.68rem;
}
/deep/.el-input,
div.el-select {
width: 1.1rem !important;
background-color: transparent;
.el-input__inner {
background-color: transparent;
}
}
.anthology {
margin: 0 0.2rem 0 0.24rem;
}
.iconquanping-video,
.iconquanping {
margin-left: 0.44rem;
cursor: pointer;
}
}
/deep/ .el-slider {
width: 0.88rem;
margin-left: 0.1rem;
.el-slider__runway,
.el-slider__bar {
height: 6px !important;
}
// .el-slider__button {
// width: 0.13rem;
// height: 0.13rem;
// }
.el-slider__button-wrapper {
top: -16px;
}
}
.progress {
width: 100%;
position: absolute;
bottom: 44px;
left: 0;
// overflow: hidden;
z-index: 999;
padding: 0 1%;
.el-slider {
width: 100%;
// margin-left: 0;
}
}
.operating-room-video::-webkit-scrollbar {
// height: 4px;
// background:#bababa;
}
.operating-room-video {
width: 100%;
height: 100px;
border: 1px solid;
white-space: nowrap;
overflow-x: auto;
overflow-y: hidden;
> div.lunb {
width: max-content;
height: 1.2rem;
> div.sing {
width: 2.07rem;
display: block;
height: 1.2rem;
float: left;
position: relative;
cursor: pointer;
> img {
width: 2.08rem;
height: 1.2rem;
}
.name {
width: 100%;
position: absolute;
bottom: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.1);
text-align: center;
color: #fff;
}
}
}
}
}
.video-info-height {
height: 6.3rem;
}
.info-box {
width: 3.92rem;
/deep/ .el-tabs__nav-scroll {
display: flex;
justify-content: space-around;
.el-tabs__item {
font-size: 0.18rem;
padding: 0 0.5rem;
color: #999;
}
.el-tabs__active-bar {
width: 0.75rem !important;
background-color: red;
}
.is-active {
color: #333;
}
}
.video-info {
padding: 0.1rem 0.4rem;
> div {
line-height: 0.34rem;
display: flex;
> div:first-child {
color: red;
margin-right: 0.1rem;
min-width: 0.7rem;
}
> div {
display: inline-block;
}
}
}
.patient-info {
> div {
> div:first-child {
min-width: 0.9rem;
}
}
}
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 1s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
.marker {
position: absolute;
top: -30px; /* 根据需要调整与滑块的距离 */
text-align: center;
pointer-events: none;
}
.marker-dot {
display: inline-block;
width: 15px;
height: 15px;
background-color: rgb(127, 16, 131);
border-radius: 50%;
margin-bottom: -38px; /* 与名称之间的间距 */
cursor: pointer;
}
.marker-name {
font-size: 12px;
color: #fff;
}
/deep/.vjs_video_3-dimensions{
width: 100%;
}
</style>视频没问题 为什么我在移动端就播放不起了
最新发布