|
|
@ -20,18 +20,19 @@ |
|
|
|
</el-col> |
|
|
|
<el-col :span="10"> |
|
|
|
<el-row> |
|
|
|
<el-col :span="12"> |
|
|
|
<video ref="videoEL1" class="canvasClass"></video> |
|
|
|
<el-col :span="12" v-for="studentItem in tableData" :key="studentItem._id"> |
|
|
|
<!-- <img v-if="imageSrc" :src="imageSrc" class="canvasClass" alt="Video Frame" /> --> |
|
|
|
<canvas :ref="`videoEL${studentItem._id}`" class="canvasClass"></canvas> |
|
|
|
</el-col> |
|
|
|
<el-col :span="12"> |
|
|
|
<video ref="videoEL2" class="canvasClass"></video> |
|
|
|
<!-- <el-col :span="12"> |
|
|
|
<canvas ref="videoEL2" class="canvasClass"></canvas> |
|
|
|
</el-col> |
|
|
|
<el-col :span="12"> |
|
|
|
<video ref="videoEL3" class="canvasClass"></video> |
|
|
|
<canvas ref="videoEL3" class="canvasClass"></canvas> |
|
|
|
</el-col> |
|
|
|
<el-col :span="12"> |
|
|
|
<video ref="videoEL4" class="canvasClass"></video> |
|
|
|
</el-col> |
|
|
|
<canvas ref="videoEL4" class="canvasClass"></canvas> |
|
|
|
</el-col> --> |
|
|
|
</el-row> |
|
|
|
</el-col> |
|
|
|
</el-row> |
|
|
@ -204,6 +205,8 @@ export default { |
|
|
|
formDisabled: false, |
|
|
|
socket: null, |
|
|
|
videoStream: null, |
|
|
|
imageSrc: "", |
|
|
|
canvasObj: {}, |
|
|
|
}; |
|
|
|
}, |
|
|
|
watch: {}, |
|
|
@ -213,6 +216,7 @@ export default { |
|
|
|
this.dealFormHeader() |
|
|
|
await this.init(); |
|
|
|
await this.initWebSocket() |
|
|
|
await this.initCanvas() |
|
|
|
|
|
|
|
}, |
|
|
|
methods: { |
|
|
@ -243,7 +247,7 @@ export default { |
|
|
|
let res = await getUser({ |
|
|
|
...params, |
|
|
|
}); |
|
|
|
this.tableData = res.list; |
|
|
|
this.tableData = _.filter(res.list, o => o.isAdmin === 0); |
|
|
|
}, |
|
|
|
// 打开新增学生的模态框 |
|
|
|
async addUserData() { |
|
|
@ -349,6 +353,15 @@ export default { |
|
|
|
}); |
|
|
|
}) |
|
|
|
}, |
|
|
|
// |
|
|
|
async initCanvas() { |
|
|
|
for (let i = 0; i < this.tableData.length; i++) { |
|
|
|
let element = this.tableData[i]; |
|
|
|
if (this.$refs[`videoEL${element._id}`]) { |
|
|
|
this.canvasObj[`context${element._id}`] = this.$refs[`videoEL${element._id}`][0].getContext('2d'); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
// 初始化实时传输信息 |
|
|
|
async initWebSocket() { |
|
|
|
this.socket = io('http://localhost:5000/ws/video', |
|
|
@ -360,19 +373,14 @@ export default { |
|
|
|
}); |
|
|
|
this.socket.on('teacherVideo', (data) => { |
|
|
|
// 在这里处理接收到的视频帧 |
|
|
|
|
|
|
|
const arrayBuffer = event.data; |
|
|
|
const blob = new Blob([arrayBuffer], { type: 'image/jpeg' }); |
|
|
|
const urlCreator = window.URL || window.webkitURL; |
|
|
|
const imageUrl = urlCreator.createObjectURL(blob); |
|
|
|
const img = new Image(); |
|
|
|
img.onload = function () { |
|
|
|
urlCreator.revokeObjectURL(this.src); |
|
|
|
let blob = this.dataURLToBlob(data.data); |
|
|
|
let urlCreator = window.URL || window.webkitURL; |
|
|
|
let imageUrl = urlCreator.createObjectURL(blob); |
|
|
|
let image = new Image(); |
|
|
|
image.onload = () => { |
|
|
|
this.canvasObj[`context${data.userId}`].drawImage(image, 0, 0, image.width, image.height, 0, 0, 300, 150); |
|
|
|
}; |
|
|
|
img.src = imageUrl; |
|
|
|
this.$refs.videoEL1.srcObject = null; // 清空当前流 |
|
|
|
this.$refs.videoEL1.src = imageUrl; // 设置新图像作为视频源 |
|
|
|
this.$refs.videoEL1.play(); |
|
|
|
image.src = imageUrl; |
|
|
|
}); |
|
|
|
}, |
|
|
|
stopVideoStream() { |
|
|
@ -385,6 +393,24 @@ export default { |
|
|
|
this.socket.disconnect(); |
|
|
|
} |
|
|
|
}, |
|
|
|
dataURLToBlob(dataURL) { |
|
|
|
let parts = dataURL.split(';base64,'); |
|
|
|
let contentType = parts[0].split(':')[1]; |
|
|
|
let byteCharacters = atob(parts[1]); |
|
|
|
let byteArrays = []; |
|
|
|
|
|
|
|
for (let offset = 0; offset < byteCharacters.length; offset += 1024) { |
|
|
|
let slice = byteCharacters.slice(offset, offset + 1024); |
|
|
|
let byteNumbers = new Array(slice.length); |
|
|
|
for (let i = 0; i < slice.length; i++) { |
|
|
|
byteNumbers[i] = slice.charCodeAt(i); |
|
|
|
} |
|
|
|
let byteArray = new Uint8Array(byteNumbers); |
|
|
|
byteArrays.push(byteArray); |
|
|
|
} |
|
|
|
let blob = new Blob(byteArrays, { type: contentType }); |
|
|
|
return blob; |
|
|
|
}, |
|
|
|
}, |
|
|
|
beforeUnmount() { |
|
|
|
this.stopVideoStream(); |
|
|
|