1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
| import {onMounted, ref} from "vue";
export const useMedia = () => {
const player = ref<HTMLVideoElement>()
const remotePlayer = ref<HTMLVideoElement>()
const pc = ref<RTCPeerConnection>()
const localStream = ref<MediaStream>()
const ws = ref()
const state = ref('开始通话')
const username = (Math.random() + 1).toString(36).substring(7)
onMounted(() => {
if (!ws.value)
ws.value = new WebSocket('ws://localhost:8080/ws')
})
const open = () => {
initWs()
getMediaDevices().then(() => {
createRtcConnection()
addLocalStreamToRTC()
})
}
const initWs = () => {
// ws.value.onopen = () => console.log('ws 已经打开')
ws.value.onmessage = wsOnMessage
}
const wsOnMessage = (e: MessageEvent) => {
const wsData = JSON.parse(e.data)
// console.log('wsData', wsData)
const wsUsername = wsData['username']
// console.log('wsUsername', wsUsername)
if (username === wsUsername) return
const wsType = wsData['type']
if (wsType === 'offer') {
const wsOffer = wsData['data']
pc.value?.setRemoteDescription(new RTCSessionDescription(JSON.parse(wsOffer)))
state.value = '请接听通话'
}
if (wsType === 'answer') {
const wsAnswer = wsData['data']
pc.value?.setRemoteDescription(new RTCSessionDescription(JSON.parse(wsAnswer)))
state.value = '通话中'
}
if (wsType === 'candidate') {
const wsCandidate = JSON.parse(wsData['data'])
pc.value?.addIceCandidate(new RTCIceCandidate(wsCandidate))
}
}
const sendMessage = (type: string, data: any) => {
ws.value.send(JSON.stringify({
username,
type,
data,
}))
}
const getMediaDevices = async () => {
const stream = await navigator.mediaDevices.getUserMedia({video: true, audio: false})
localStream.value = stream
player.value!.srcObject = stream
}
const createRtcConnection = () => {
const _pc = new RTCPeerConnection({
iceServers: [{urls: ['stun:stun.stunprotocol.org:3478']}]
})
_pc.onicecandidate = ({candidate}) => {
if (candidate) sendMessage('candidate', JSON.stringify(candidate))
}
_pc.ontrack = e => {
remotePlayer.value!.srcObject = e.streams[0]
console.log(remotePlayer.value!.srcObject)
}
pc.value = _pc
}
const createOffer = async () => {
const sdp = await pc.value?.createOffer({
offerToReceiveAudio: true,
offerToReceiveVideo: true
})
pc.value?.setLocalDescription(sdp)
sendMessage('offer', JSON.stringify(sdp))
state.value = '等待对方接听'
}
const createAnswer = async () => {
const sdp = await pc.value?.createAnswer({
offerToReceiveVideo: true,
offerToReceiveAudio: true,
})
pc.value?.setLocalDescription(sdp)
sendMessage('answer', JSON.stringify(sdp))
state.value = '通话中'
}
const addLocalStreamToRTC = () => {
localStream
.value
?.getTracks()
.forEach(track => {
pc.value?.addTrack(track, localStream.value!)
})
}
return {
player,
getMediaDevices,
createOffer,
remotePlayer,
createAnswer,
state,
open
}
}
|