<template>
|
<div class="c">
|
<div class="bg">
|
<div class="main">
|
<div class="list">
|
<div class="card list-con" v-for="(item,index) in curriculum" :key="index">
|
<img src="@/assets/img/teach/list-card-bg.jpg" style="height:220px;width:350px" alt=""
|
v-if="!item.start">
|
<video :id="`video-${item.id}`" v-show="item.start" height="220px" width="350px"></video>
|
<div class="list-con-t">
|
<p>上课时间</p>
|
<span>{{ item.time }}</span>
|
</div>
|
<div class="list-con-op">
|
<el-button colorType="default">资料上传</el-button>
|
<el-button colorType="deepBlue" @click="handleStart(item)">开始上课</el-button>
|
</div>
|
</div>
|
</div>
|
<div class="flex" style="justify-content:center;margin-top:20px;">
|
<el-pagination background layout="prev, pager, next" :total="1000">
|
</el-pagination>
|
</div>
|
</div>
|
</div>
|
|
<s-dialog v-model="dialog" title="请选择授课方式">
|
<template>
|
<div style="width:300px; padding:20px; justify-content:space-between" class="flex">
|
<el-button colorType="default">语音授课</el-button>
|
<el-button colorType="deepBlue" @click="selectScreen">视频授课</el-button>
|
</div>
|
</template>
|
</s-dialog>
|
|
<el-dialog title="选择授课屏幕" :visible.sync="dialogScreenVisible" width="60%">
|
<div v-for="(source, index) in sources" :key="source.id" class="sourceDiv"
|
:class="{ defaultSelect: index === selectIndex }" @click="selectSource(index, source)">
|
<video width="220" height="140" :id="`video-${source.id}`">
|
您的浏览器不支持 video 标签。
|
</video>
|
{{ source.name }}
|
</div>
|
|
<span slot="footer" class="dialog-footer">
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button type="primary" @click="dialogScreenVisible = false; screenConfirm()">确 定</el-button>
|
</span>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script>
|
import { desktopCapturer } from 'electron';
|
|
export default {
|
data () {
|
return {
|
dialog: false,
|
dialogScreenVisible: false,
|
sources: null,
|
selectIndex: 0,
|
currentSource: null,
|
currentItem: null,
|
curriculum: [
|
{
|
id: 1,
|
start: false,
|
time: '12:30 - 13:30'
|
},
|
{
|
id: 2,
|
start: false,
|
time: '12:30 - 13:30'
|
},
|
{
|
id: 3,
|
start: false,
|
time: '12:30 - 13:30'
|
},
|
{
|
id: 4,
|
start: false,
|
time: '12:30 - 13:30'
|
},
|
{
|
id: 5,
|
start: false,
|
time: '12:30 - 13:30'
|
},
|
{
|
id: 6,
|
start: false,
|
time: '12:30 - 13:30'
|
},
|
],
|
|
}
|
},
|
methods: {
|
handleStart (i) {
|
this.dialog = true;
|
this.currentItem = i
|
},
|
selectSource (index, source) {
|
this.selectIndex = index
|
this.currentSource = source
|
},
|
screenConfirm () {
|
this.getSource(this.currentSource, `video-${this.currentItem.id}`, true)
|
},
|
async selectScreen () {
|
this.dialog = false
|
const sources = await desktopCapturer.getSources({ types: ['window', 'screen'] })
|
this.sources = sources
|
this.getSources(sources)
|
},
|
async getSources (sources, containerId) {
|
const _this = this
|
await sources.forEach(source => {
|
_this.getSource(source, containerId)
|
})
|
},
|
async getSource (source, containerId, isPush) {
|
const constraints = {
|
audio: false,
|
video: {
|
mandatory: {
|
chromeMediaSource: 'desktop',
|
chromeMediaSourceId: source.id,
|
minWidth: 1440,
|
maxWidth: 1920,
|
minHeight: 900,
|
maxHeight: 1080
|
}
|
}
|
}
|
await this.getUserMedia(source, containerId, constraints, isPush)
|
},
|
async getUserMedia (source, containerId, constraints, isPush) {
|
const _this = this
|
|
await navigator.mediaDevices.getUserMedia(constraints)
|
.then(function (mediaStream) {
|
if (!isPush) {
|
_this.dialogScreenVisible = true
|
} else {
|
_this.dialogScreenVisible = false
|
_this.currentItem.start = true
|
}
|
var video = document.getElementById(containerId ? containerId : `video-${source.id}`);
|
|
video.srcObject = mediaStream;
|
video.onloadedmetadata = async function (e) {
|
video.play();
|
if (isPush) {
|
let stream = new MediaStream()
|
stream.addTrack(mediaStream.getVideoTracks()[0])
|
|
let audio1 = await getDisplayMediaSource('microphone')
|
// if (audio1) {
|
|
// stream.addTrack(audio1.getAudioTracks()[0])
|
|
// // _this.sdk.ontrack()
|
// // console.log(audio1.getAudioTracks()[0])
|
// // mediaStream.addTrack(audio1.getAudioTracks()[0])
|
// }
|
let audio2 = await getDisplayMediaSource('system')
|
// if (audio2) {
|
// stream.addTrack(audio2.getAudioTracks()[0])
|
// // 将获取的音频流数据添加到视频流
|
// // mediaStream.addTrack(audio2.getAudioTracks()[0])
|
// }
|
stream.addTrack(...mergeAudioStreams(audio1, audio2))
|
startPublish(`teacher/${_this.currentItem.id}`, stream)
|
// // SrsRtcPublisherAsync().publish('webrtc://192.168.3.115/live/livestream', mediaStream)
|
}
|
|
};
|
})
|
.catch(function (err) { console.log(err.name + ": " + err.message); }); // 总是在最后检查错误
|
|
},
|
}
|
}
|
</script>
|
|
<style scoped lang="scss">
|
.flex {
|
display: flex;
|
}
|
|
.card {
|
background: white;
|
box-shadow: 2px 2px 2px 2px rgba(0, 0, 0, 0.2);
|
padding: 20px;
|
box-sizing: border-box;
|
margin-bottom: 20px;
|
border-radius: 10px;
|
}
|
|
.list {
|
margin-top: 50px;
|
width: 1262px;
|
display: flex;
|
justify-content: space-between;
|
flex-wrap: wrap;
|
|
&-con {
|
&-t {
|
&>p {
|
margin-top: 10px;
|
margin-bottom: 0px;
|
}
|
|
&>span {
|
color: #777;
|
}
|
}
|
|
&-op {
|
justify-content: space-between;
|
display: flex;
|
}
|
}
|
}
|
|
.sourceDiv {
|
display: inline-flex;
|
margin-right: 10px;
|
flex-direction: column;
|
padding: 5px;
|
}
|
|
.sourceDiv.defaultSelect {
|
background-color: cornsilk;
|
}
|
|
.sourceDiv:hover {
|
background-color: aliceblue;
|
}
|
|
.sourceDiv:active {
|
background-color: cornsilk;
|
}
|
</style>
|