409 lines
13 KiB
Vue
409 lines
13 KiB
Vue
<template>
|
||
<div class="liveing">
|
||
|
||
<div class="top">
|
||
<div class="left">直播页面</div>
|
||
<div class="right">
|
||
<img src="@/static/images/liveshare.png" alt="" @click="fenxiang()" />
|
||
<img src="@/static/images/liveend.png" alt="" @click="visible = true" />
|
||
</div>
|
||
</div>
|
||
<div class="info">
|
||
<LiveingWatcher></LiveingWatcher>
|
||
<div class="LivePlaying">
|
||
<LivePlaying></LivePlaying>
|
||
<div class="comment">
|
||
<div class="commentitem">
|
||
<span>13:32:30</span>
|
||
<span class="name"> Andy : </span>
|
||
<span> 老师,这个部分可以讲的慢一些吗? </span>
|
||
</div>
|
||
<div class="commentitem">
|
||
<span>13:32:30</span>
|
||
<span class="name"> Andy : </span>
|
||
<span> 老师,这个部分可以讲的慢一些吗? </span>
|
||
</div>
|
||
<div class="commentitem">
|
||
<span>13:32:30</span>
|
||
<span class="name"> Andy : </span>
|
||
<span> 老师,这个部分可以讲的慢一些吗? </span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="others">
|
||
<div :id="'s-' + item.memberid" class="othersitem" v-for="(item, index) in roominfo.studentlist" :key="index">
|
||
<div class="watcher"></div>
|
||
<div class="name">{{item.name}}</div>
|
||
<!-- <img src="" alt="" /> -->
|
||
</div>
|
||
<!-- <div class="othersitem">
|
||
<div class="watcher"></div>
|
||
<div class="name">asdsada</div>
|
||
<img src="" alt="" />
|
||
</div>
|
||
<div class="othersitem">
|
||
<div class="watcher"></div>
|
||
<div class="name">asdsada</div>
|
||
<img src="" alt="" />
|
||
</div>
|
||
<div class="othersitem">
|
||
<div class="watcher"></div>
|
||
<div class="name">asdsada</div>
|
||
<img src="" alt="" />
|
||
</div> -->
|
||
|
||
|
||
</div>
|
||
</div>
|
||
<a-modal v-model:visible="visible" title="Basic Modal" @ok="guanbi">
|
||
<p>您确认关闭直播吗</p>
|
||
</a-modal>
|
||
</div>
|
||
</template>
|
||
<style lang="scss" scoped>
|
||
.liveing ::v-deep(.ant-breadcrumb) > span:last-child {
|
||
color: #08ae98;
|
||
}
|
||
.liveing {
|
||
width: 1320px;
|
||
height: 563px;
|
||
.top {
|
||
width: 1321px;
|
||
height: 57px;
|
||
background: white;
|
||
border-radius: 18px;
|
||
margin-top: 23px;
|
||
margin-bottom: 29px;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
color: #121212;
|
||
font-size: 13px;
|
||
align-items: center;
|
||
.left {
|
||
margin-left: 40px;
|
||
font-weight: bold;
|
||
}
|
||
.right {
|
||
margin-right: 27px;
|
||
> img {
|
||
margin-right: 10px;
|
||
}
|
||
}
|
||
}
|
||
.info {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
.LivePlaying {
|
||
border-radius: 18px;
|
||
margin: 0 35px;
|
||
.comment {
|
||
width: 797px;
|
||
height: 153px;
|
||
background: white;
|
||
border-radius: 18px;
|
||
margin-top: 29px;
|
||
padding: 30px;
|
||
font-size: 12px;
|
||
|
||
color: #121212;
|
||
|
||
.commentitem {
|
||
margin-bottom: 17px;
|
||
.name {
|
||
margin-left: 28px;
|
||
color: #08ae98;
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
}
|
||
.liveinfo {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
height: 58px;
|
||
align-items: center;
|
||
.left {
|
||
display: flex;
|
||
color: #121212;
|
||
font-size: 13px;
|
||
margin-left: 29px;
|
||
> div {
|
||
margin-right: 57px;
|
||
}
|
||
.icon {
|
||
width: 25px;
|
||
height: 24px;
|
||
margin-right: 6px;
|
||
}
|
||
}
|
||
.right {
|
||
width: 74px;
|
||
height: 29px;
|
||
border: 1px solid #08ae98;
|
||
border-radius: 3px;
|
||
margin-right: 29px;
|
||
color: #08ae98;
|
||
font-size: 13px;
|
||
line-height: 29px;
|
||
font-weight: bold;
|
||
text-align: center;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.others {
|
||
width: 252px;
|
||
height: 630px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
.othersitem {
|
||
position: relative;
|
||
width: 100%;
|
||
height: 132px;
|
||
margin-bottom: 35px;
|
||
background-color: #eee;
|
||
border-radius: 18px 18px 0px 0px;
|
||
overflow: hidden;
|
||
.watcher {
|
||
width: 100%;
|
||
height: 29px;
|
||
background: #000000;
|
||
color: white;
|
||
position: absolute;
|
||
opacity: 0.1;
|
||
border-radius: 18px 18px 0px 0px;
|
||
top: 0;
|
||
}
|
||
> img {
|
||
width: 228px;
|
||
height: 132px;
|
||
border-radius: 18px;
|
||
}
|
||
.name {
|
||
position: absolute;
|
||
top: 9px;
|
||
left: 28px;
|
||
font-size: 12px;
|
||
color: #fff;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|
||
<script lang="ts">
|
||
import { defineComponent, onMounted, ref } from "vue";
|
||
import LivePlaying from "@/components/LivePlaying.vue";
|
||
import LiveingWatcher from "@/components/LiveingWatcher.vue";
|
||
import TRTC from "trtc-js-sdk"
|
||
import { getliveinfo, livestop, luzhi, usersig } from '@/api';
|
||
import { useRoute } from 'vue-router';
|
||
import store from '@/store';
|
||
import { message } from 'ant-design-vue';
|
||
|
||
export default defineComponent({
|
||
components: {
|
||
LivePlaying,
|
||
LiveingWatcher,
|
||
},
|
||
setup() {
|
||
console.log(1);
|
||
let client: any;
|
||
let localStream: any;
|
||
let statie = true;
|
||
let userSing = '';
|
||
let type = false;
|
||
const visible = ref(false);
|
||
const roominfo = ref<any>([]);
|
||
console.log(useRoute())
|
||
const id = useRoute().query.id;
|
||
TRTC.checkSystemRequirements().then((result: any) => {
|
||
if(!result) {
|
||
message.error("您的浏览器不支持视频通话,请下载新版chrome浏览器")
|
||
}
|
||
})
|
||
async function qiehuan(){
|
||
// 1 屏幕分享 2 摄像头
|
||
client.unpublish(localStream)
|
||
localStream = type ? TRTC.createStream({ userid: store.state.userinfo.memberid, audio: true, screen: true }) : TRTC.createStream({ userId: 10, audio: false, video: true });
|
||
type = !type;
|
||
localStream.initialize().then(()=>{
|
||
client
|
||
.publish(localStream)
|
||
.catch((error: string) => {
|
||
console.error('本地流发布失败 ' + error);
|
||
})
|
||
.then(() => {
|
||
|
||
localStream.play('local_stream');
|
||
console.log('本地流发布成功');
|
||
});
|
||
});
|
||
|
||
}
|
||
async function shexiang(){
|
||
localStream = TRTC.createStream({ userId: store.state.userinfo.memberid, audio: true, video: true });
|
||
const id = localStream.getId();
|
||
await localStream
|
||
.initialize()
|
||
.catch((error: string) => {
|
||
console.error('初始化本地流失败 ' + error);
|
||
})
|
||
.then(() => {
|
||
console.log('初始化本地流成功');
|
||
client
|
||
.publish(localStream)
|
||
.catch((error: string) => {
|
||
console.error('本地流发布失败 ' + error);
|
||
})
|
||
.then(() => {
|
||
const el = document.querySelector("#local_stream");
|
||
if(el){
|
||
el.innerHTML = ""
|
||
}
|
||
localStream.play('local_stream');
|
||
console.log('本地流发布成功');
|
||
console.log(id, 123)
|
||
});
|
||
});
|
||
}
|
||
|
||
async function pingmu(){
|
||
const result = await TRTC.checkSystemRequirements()
|
||
console.log(result,11111)
|
||
if(!result) {
|
||
message.error("您的浏览器不支持屏幕分享,请下载新版chrome");
|
||
shexiang()
|
||
return ;
|
||
}
|
||
|
||
localStream = TRTC.createStream({ userid: store.state.userinfo.memberid, audio: true, screen: true });
|
||
const id = localStream.getId();
|
||
await localStream
|
||
.initialize()
|
||
.catch((error: string) => {
|
||
console.error('初始化本地流失败 ' + error);
|
||
message.error("请选择分享的内容")
|
||
|
||
setTimeout(()=>{
|
||
pingmu()
|
||
}, 1000)
|
||
})
|
||
.then(() => {
|
||
console.log('初始化本地流成功');
|
||
client
|
||
.publish(localStream)
|
||
.catch((error: string) => {
|
||
console.log('本地流发布失败 ' + error);
|
||
|
||
})
|
||
.then(() => {
|
||
const el = document.querySelector("#local_stream");
|
||
if(el){
|
||
el.innerHTML = ""
|
||
}
|
||
localStream.play('local_stream');
|
||
console.log('本地流发布成功');
|
||
console.log(id , 123)
|
||
});
|
||
});
|
||
}
|
||
|
||
async function init(fun: any, userSig: string): Promise<void>{
|
||
console.log(userSig)
|
||
const el = document.querySelector("#local_stream");
|
||
if(el){
|
||
el.innerHTML = ""
|
||
}
|
||
if (typeof id == "string") {
|
||
roominfo.value = await getliveinfo(parseInt(id))
|
||
console.log(roominfo.value)
|
||
}
|
||
|
||
|
||
client = TRTC.createClient({
|
||
mode: 'rtc',
|
||
sdkAppId: '1400400340',
|
||
userId: store.state.userinfo.memberid,
|
||
userSig: userSig
|
||
});
|
||
client.on('stream-added', (event: { stream: any }) => {
|
||
const remoteStream = event.stream;
|
||
console.log('远端流增加: ' + remoteStream.getId());
|
||
//订阅远端流
|
||
client.subscribe(remoteStream);
|
||
});
|
||
client.on('stream-subscribed', (event: { stream: any }) => {
|
||
const remoteStream = event.stream;
|
||
console.log(remoteStream);
|
||
// 播放远端流
|
||
remoteStream.play('s-' + remoteStream.userId_);
|
||
});
|
||
client
|
||
.join({ roomId: roominfo.value.roomid})
|
||
.catch((error: string) => {
|
||
console.error('进房失败 ' + error);
|
||
})
|
||
.then(() => {
|
||
console.log('进房成功');
|
||
// if(typeof id == "string"){
|
||
luzhi(roominfo.value.roomid)
|
||
// }
|
||
fun()
|
||
});
|
||
}
|
||
async function fenxiang(){
|
||
console.log(localStream)
|
||
|
||
|
||
await client.unpublish(localStream).then(() => {
|
||
// 关闭屏幕分享流
|
||
console.log("关闭")
|
||
// client.leave().then(() => {
|
||
// // leaving room success
|
||
// console.log("关闭成功")
|
||
// }).catch((error: string) => {
|
||
// console.error('leaving room failed: ' + error);
|
||
// });
|
||
const el = document.querySelector("#local_stream");
|
||
if(el){
|
||
el.innerHTML = ""
|
||
}
|
||
});
|
||
statie ? await shexiang() : await pingmu();
|
||
statie = !statie;
|
||
console.log(localStream.getId())
|
||
}
|
||
|
||
function guanbi(){
|
||
client.leave().then(() => {
|
||
// leaving room success
|
||
visible.value = false;
|
||
if(typeof id == "string"){
|
||
livestop(id, roominfo.value.roomid)
|
||
}
|
||
}).catch((error: string) => {
|
||
message.error('关闭失败: ' + error);
|
||
});
|
||
}
|
||
|
||
onMounted(async ()=>{
|
||
const si = setInterval(async ()=>{
|
||
if(store.state.userinfo.memberid != 0 && store.state.userinfo.memberid){
|
||
clearInterval(si);
|
||
userSing = await usersig(store.state.userinfo.memberid);
|
||
init(pingmu, userSing);
|
||
|
||
}
|
||
})
|
||
|
||
})
|
||
|
||
return{
|
||
fenxiang,
|
||
qiehuan,
|
||
roominfo,
|
||
guanbi,
|
||
visible
|
||
}
|
||
},
|
||
});
|
||
</script> |