Skip to content

Commit

Permalink
feat: web rtc 前端
Browse files Browse the repository at this point in the history
  • Loading branch information
lebornjose committed Nov 19, 2024
1 parent 88edb98 commit 12f0081
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 11 deletions.
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
<script src="/public/js/video-view.js"></script>
</body>
</html>
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@webav/av-cliper": "^0.14.4",
"@webav/av-recorder": "^0.16.0",
"ant-design-vue": "4.0.0-rc.6",
"socket.io-client": "^4.8.1",
"vue": "^3.3.4"
},
"devDependencies": {
Expand Down
2 changes: 2 additions & 0 deletions public/js/video-view.js

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import Canvas2Mp4 from '../view/canvas_to2_mp4.vue'
import GreenScreen from '../view/webAv/greenScreen.vue'
import CanvasRecord from '../view/canvasToMp4/canvas_record.vue'
import WebRtc from '../view/webRtc/index.vue'
import Room from '../view/webRtc/Room.vue'
const routes = [
{
path: '/',
Expand Down Expand Up @@ -166,6 +167,11 @@ const routes = [
path: '/web_rtc',
name: 'webRtc',
component: WebRtc
},
{
path: '/webrtc_room',
name: 'room',
component: Room
}
]

Expand Down
4 changes: 4 additions & 0 deletions src/utils/socket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import io from 'socket.io-client';
const host = 'localhost:3000';
const socket = io.connect(host);
export default socket;
168 changes: 157 additions & 11 deletions src/view/webRtc/Room.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,27 @@
发起视频
</el-button>
</div>
<div v-else>
<h1>当前域名的浏览器不支持WebRTC!</h1>
</div>
</div>
</div>
<div v-else>
<h1>当前域名的浏览器不支持WebRTC!</h1>
</div>
</div>
</template>

<script setup>
import { onMounted } from 'vue';
import socket from '../../utils/socket'
import { onMounted, ref, reactive } from 'vue'
const canSupportVideo = ref(false)
const showFormArea = ref(false)
const sockId = ref('') // 客户端id
const localStream = ref(null) // 本地视频流
const canSupportVideo = ref(false) // 是否支持视频
const showFormArea = ref(true) // 是否显示表单
const roomUsers = ref([]) // 房间在线用户
const canClickBtn = ref(true) // 是否可以点击按钮
const peer = ref(null) // peer
const canClickBtn = ref(true)
// 房间信息
const roomForm = reactive({
roomId: '',
nickname: ''
Expand Down Expand Up @@ -78,8 +81,151 @@ const canSupportWebRTC = () => {
getDevices();
return true;
}
const createLocalVideoStream = async () => {
const constraints = { audio: true, video: true };
const localStream = await navigator.mediaDevices.getUserMedia(constraints);
return localStream;
}
const initPeerListen = () => {
peer.value.onicecandidate = (event) => {
if (event.candidate) {
socket.emit('addIceCandidate', { candidate: event.candidate, user: user.value });
}
};
peer.value.onaddstream = (event) => {
// 拿到对方的视频流
document.querySelector('#echat-remote-1').srcObject = event.stream;
};
this.peer.onclose = () => {};
}
const initSocketEvents = () => {
// 离开页面
window.onbeforeunload = () => {
socket.emit('userLeave', {
userName: this.roomForm.userName,
sockId: this.sockId,
roomId: this.roomForm.roomId,
});
};
// 连接成功
socket.on('connectionSuccess', (sockId) => {
sockId.value = sockId;
console.log('connectionSuccess client sockId:', sockId);
});
// 检查房间成功
socket.on('checkRoomSuccess', (exsitRoomUsers) => {
debugger
this.canClickBtn = true;
if (exsitRoomUsers && exsitRoomUsers.length > 1) {
this.$message.info('当前房间人数已满~请换个房间id');
} else {
showFormArea.value = false;
roomUsers.value = [
{
userName: roomForm.userName + '(我)',
sockId: sockId.value,
roomId: roomForm.roomId,
}
];
}
});
// 加入房间成功
socket.on('joinRoomSuccess', (roomUsers) => {
console.log('joinRoomSuccess client user:', roomUsers);
const otherUser = roomUsers.find(item => item.sockId !== this.sockId);
if (!otherUser) return false;
this.$message.success(`${otherUser.userName}加入了房间`);
roomUsers.value = [otherUser, {
userName: roomForm.userName + '(我)',
sockId: sockId.value,
roomId: roomForm.roomId,
}];
});
// 用户离开
socket.on('userLeave', (roomUsers) => {
console.log('userLeave client user:', roomUsers);
if (!roomUsers.value.length) {
showFormArea.value = true;
sockId.value = '';
}
const serverSockIdArr = roomUsers.map(item => item.sockId);
roomUsers.value.forEach(item => {
if (serverSockIdArr.indexOf(item.sockId) === -1) {
this.$message.info(`${item.userName}离开了房间`);
if (item.sockId === this.sockId) {
showFormArea.value = true;
sockId.value = '';
}
}
});
roomUsers.value = roomUsers;
roomUsers.value.forEach((item) => {
if (item.sockId === sockId.value) {
item.userName = item.userName + '(我)';
}
});
// TODO: 挂断视频
VIDEO_VIEW.hideAllVideoModal();
});
// 取消发送视频
socket.on('cancelSendVideo', (user) => {
const infoTips = user.sockId === sockId ? '您取消了发送视频' : '对方取消了发送视频';
this.$message.info(infoTips);
VIDEO_VIEW.hideAllVideoModal();
});
// 接收视频邀请
socket.on('receiveVideo', (sender) => {
if (this.user.sockId === sender.sockId) return false;
VIDEO_VIEW.showReceiveVideoModalBySender(sender);
});
// 拒绝接收视频
socket.on('rejectReceiveVideo', (user) => {
const infoTips = user.sockId === sockId.value ? '您拒绝了接收视频' : '对方拒绝了接收视频';
this.$message.info(infoTips);
VIDEO_VIEW.hideAllVideoModal();
});
// 接听视频
socket.on('answerVideo', async (user) => {
VIDEO_VIEW.showInvideoModal();
// 创建本地视频流信息
const localStream = await createLocalVideoStream();
localStream.value = localStream
peer.value = new RTCPeerConnection()
console.log(peer.value)
initPeerListen()
peer.value.addStream(this.localStream)
if (user.sockId === this.sockId) {
// 接收方
} else {
// 发送方 创建offer
const offer = await peer.value.createOffer(this.offerOption);
await peer.value.setLocalDescription(offer);
socket.emit('receiveOffer', { user: this.user, offer });
}
});
}
onMounted(() => {
canSupportWebRTC()
if(canSupportWebRTC()) {
initSocketEvents()
}
})
</script>

<style>
.m-room-wrapper{
width: 880px;
margin: 20px auto!important;
}
.m-room-wrapper .box-card {
width: 480px;
}
.m-room-wrapper .box-card .item{
padding: 18px 0;
}
.ant-form-item-control-input-content{
display: flex;
gap: 12px;
}
</style>

0 comments on commit 12f0081

Please sign in to comment.