293 lines
8.4 KiB
Vue
293 lines
8.4 KiB
Vue
<template>
|
||
<div>
|
||
<div class="wrapper">
|
||
<video ref="videoStreamtopVideo" width="100%" autoplay muted controls></video>
|
||
<div class="swiper-container">
|
||
<div class="swiper-wrapper">
|
||
<template v-for="(item,index) in videoRoomSteamList">
|
||
<div :key="item.webrtcUrl" class="swiper-slide">
|
||
<video class="remoteVideo" :ref="'videoStream'+item.publishId" width="100%" autoplay
|
||
@click="videoClickAction(item.publishId)"></video>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- <video ref="localVideo" id="rtc_media_local_player" width="310" autoplay muted controls></video>-->
|
||
<!-- <van-button type="primary" @click="playVideo">主要按钮</van-button>-->
|
||
<!-- <van-button type="primary" @click="beginPublish">开始推流</van-button>-->
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import axios from "axios";
|
||
import Swiper from 'swiper'; // 注意引入的是Swiper
|
||
import 'swiper/css/swiper.min.css' // 注意这里的引入
|
||
|
||
/* eslint-disable */
|
||
export default {
|
||
name: "call_room",
|
||
data() {
|
||
return {
|
||
value: "webrtc://119.45.242.222/live/livestream123",
|
||
isPublish: 0,
|
||
isPlayer: 0,
|
||
uid: 0,
|
||
roomId: 0,
|
||
roomTimer: null,
|
||
topVideo: "",
|
||
videoRoomSteamList: [],
|
||
oldVideoStreamList: [],
|
||
swiperInstance: null,
|
||
};
|
||
},
|
||
mounted() {
|
||
this.isPublish = this.$route.query.isPublish;
|
||
this.isPlayer = this.$route.query.isPlayer;
|
||
this.uid = this.$route.query.uid;
|
||
this.roomId = this.$route.query.room;
|
||
this.topVideo = this.uid;
|
||
|
||
if (this.isPublish == 1) {
|
||
this.beginPublish()
|
||
}
|
||
if (this.isPlayer == 1) {
|
||
this.roomTimer = setInterval(() => {
|
||
this.getRoomVideoList();
|
||
}, 2000)
|
||
}
|
||
this.swiperInstance = new Swiper('.swiper-container', {
|
||
slidesPerView: 4,
|
||
spaceBetween: 30,
|
||
observer: true,
|
||
on: {},
|
||
})
|
||
|
||
},
|
||
beforeDestroy() {
|
||
clearInterval(this.roomTimer);
|
||
this.roomTimer = null;
|
||
this.leaveRoom();
|
||
},
|
||
methods: {
|
||
beginPublish() {
|
||
let _this = this;
|
||
//http://localhost:8080/hd-glasses-app/#/call_room?isPublish=1&isPlayer=1&uid=123&room=call_room
|
||
|
||
// var query = parse_query_string();
|
||
|
||
const publistUrl = process.env.VUE_APP_SRS_URL + this.roomId + "/" + this.uid;
|
||
|
||
// srs_init_rtc("#txt_url", publistUrl);
|
||
|
||
//初始化sdk
|
||
let sdk = null;
|
||
if (sdk) {
|
||
sdk.close();
|
||
}
|
||
sdk = new SrsRtcPublisherAsync();
|
||
//绑定本地视频流
|
||
// const localVideo = this.$refs.localVideo;
|
||
// localVideo.srcObject = null;
|
||
// localVideo.srcObject = sdk.stream;
|
||
|
||
sdk.publish(publistUrl).then((session) => {
|
||
_this.joinRoom()
|
||
}).catch(function (reason) {
|
||
console.error(reason)
|
||
// Throw by sdk.
|
||
// See https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#exceptions
|
||
if (reason instanceof DOMException) {
|
||
if (reason.name === 'NotFoundError') {
|
||
alert(`找不到麦克风和摄像头设备:getUserMedia ${reason.name} ${reason.message}`);
|
||
} else if (reason.name === 'NotAllowedError') {
|
||
alert(`你禁止了网页访问摄像头和麦克风:getUserMedia ${reason.name} ${reason.message}`);
|
||
} else if (['AbortError', 'NotAllowedError', 'NotFoundError', 'NotReadableError', 'OverconstrainedError', 'SecurityError', 'TypeError'].includes(reason.name)) {
|
||
alert(`getUserMedia ${reason.name} ${reason.message}`);
|
||
}
|
||
}
|
||
sdk.close();
|
||
console.error(reason);
|
||
});
|
||
|
||
|
||
},
|
||
playVideo(publishId = "", url = "") {
|
||
let sdk = null;
|
||
let video = null;
|
||
// const _key=`${}`
|
||
|
||
video = eval('this.$refs.videoStream' + publishId)[0]
|
||
|
||
// const video = this.$refs[_key];
|
||
if (video.srcObject != null) {
|
||
return false;
|
||
}
|
||
// console.warn(video.srcObject )
|
||
// console.warn(video.srcObject )
|
||
// console.warn(video.srcObject )
|
||
// console.warn(video.srcObject )
|
||
// console.warn(video.srcObject )
|
||
|
||
var query = parse_query_string();
|
||
|
||
srs_init_rtc("#txt_url", this.value);
|
||
|
||
if (sdk) {
|
||
sdk.close();
|
||
}
|
||
sdk = new SrsRtcPlayerAsync();
|
||
|
||
if (this.topVideo == publishId) {
|
||
const topVideo = this.$refs.videoStreamtopVideo
|
||
topVideo.srcObject = sdk.stream;
|
||
topVideo.onloadedmetadata = function (e) {
|
||
topVideo.play();
|
||
};
|
||
}
|
||
|
||
|
||
video.srcObject = sdk.stream;
|
||
video.onloadedmetadata = function (e) {
|
||
video.play();
|
||
};
|
||
|
||
// $('#rtc_media_player').prop('srcObject', sdk.stream);
|
||
// Optional callback, SDK will add track to stream.
|
||
// sdk.ontrack = function (event) { console.log('Got track', event); sdk.stream.addTrack(event.track); };
|
||
|
||
// For example: webrtc://r.ossrs.net/live/livestream
|
||
// var url = this.value
|
||
sdk.play(url).then(function (session) {
|
||
// $('#sessionid').html(session.sessionid);
|
||
// $('#simulator-drop').attr('href', session.simulator + '?drop=1&username=' + session.sessionid);
|
||
}).catch(function (reason) {
|
||
sdk.close();
|
||
$('#rtc_media_player').hide();
|
||
console.error(reason);
|
||
});
|
||
|
||
},
|
||
getRoomVideoList() {
|
||
axios({
|
||
method: "post",
|
||
url: process.env.VUE_APP_IM_API_URL + "/room/getRoomInfo",
|
||
headers: {
|
||
'Content-Type': 'application/json;charset=utf-8'
|
||
},
|
||
// mode: 'no-cors',
|
||
data: {
|
||
roomId: this.roomId
|
||
},
|
||
}).then(res => {
|
||
if (res.status == 200) {
|
||
this.generateVideoRoomStream(res.data.data)
|
||
}
|
||
})
|
||
},
|
||
leaveRoom() {
|
||
axios({
|
||
method: "post",
|
||
url: process.env.VUE_APP_IM_API_URL + "/room/leaveRoom",
|
||
headers: {
|
||
'Content-Type': 'application/json;charset=utf-8'
|
||
},
|
||
data: {
|
||
roomId: this.roomId,
|
||
publishId: this.uid,
|
||
type: 'webrtc'
|
||
},
|
||
}).then(res => {
|
||
console.log(res)
|
||
})
|
||
},
|
||
joinRoom() {
|
||
axios({
|
||
method: "post",
|
||
url: process.env.VUE_APP_IM_API_URL + "/room/joinRoom",
|
||
headers: {
|
||
'Content-Type': 'application/json;charset=utf-8'
|
||
},
|
||
// mode: 'no-cors',
|
||
data: {
|
||
roomId: this.roomId,
|
||
publishId: this.uid,
|
||
type: 'webrtc',
|
||
webrtcUrl: process.env.VUE_APP_SRS_URL + this.roomId + "/" + this.uid
|
||
},
|
||
}).then(res => {
|
||
console.log(res)
|
||
})
|
||
},
|
||
generateVideoRoomStream(videoList) {
|
||
let hasUpdate = false;
|
||
if (this.oldVideoStreamList == null) {
|
||
this.oldVideoStreamList = videoList;
|
||
} else {
|
||
if (JSON.stringify(this.oldVideoStreamList) != JSON.stringify(videoList)) {
|
||
hasUpdate = true
|
||
}
|
||
}
|
||
this.oldVideoStreamList = videoList;
|
||
this.videoRoomSteamList = videoList;
|
||
|
||
setTimeout(() => {
|
||
videoList.map((item) => {
|
||
this.playVideo(item.publishId, item.webrtcUrl)
|
||
})
|
||
if (hasUpdate) {
|
||
this.swiperInstance.update();
|
||
console.log("数据有变化,更新swipper")
|
||
//视频流有变化,检查置顶用户是否以及走掉
|
||
this.updateTopVideoStream();
|
||
|
||
}
|
||
|
||
}, 1000)
|
||
//videoSteamList
|
||
},
|
||
videoClickAction(publishId) {
|
||
this.topVideo = publishId;
|
||
var video = eval('this.$refs.videoStream' + publishId)[0]
|
||
console.log(video.srcObject)
|
||
this.$refs.videoStreamtopVideo.srcObject = video.srcObject;
|
||
},
|
||
//讲列表有人下线,判断top流是否正常,如果不正常则把列表第一个移到Top
|
||
updateTopVideoStream() {
|
||
console.log(this.$refs.videoStreamtopVideo.srcObject)
|
||
let topVideo = this.oldVideoStreamList.find(item => item.publishId == this.topVideo)
|
||
//如果置顶用户已经走掉,则把用户自己的视频置顶
|
||
if (topVideo == undefined) {
|
||
var video = eval('this.$refs.videoStream' + this.uid)[0]
|
||
this.$refs.videoStreamtopVideo.srcObject = video.srcObject;
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="less">
|
||
|
||
.slide {
|
||
height: 200px;
|
||
width: 200px;
|
||
}
|
||
|
||
.swiper-slide {
|
||
background: #000000;
|
||
width: 200px;
|
||
height: 180px;
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: center;
|
||
align-items: center;
|
||
margin-right: 20px;
|
||
|
||
.remoteVideo {
|
||
width: 100%;
|
||
height: auto;
|
||
}
|
||
}
|
||
</style>
|