
11 changed files with 331 additions and 261 deletions
File diff suppressed because one or more lines are too long
@ -1 +1 @@ |
|||
.root textarea{background:transparent;color:#0ff} |
|||
@-webkit-keyframes blink-data-v-42a5fa69{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}@keyframes blink-data-v-42a5fa69{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}.blink[data-v-42a5fa69]{-webkit-animation:blink-data-v-42a5fa69 1s infinite;animation:blink-data-v-42a5fa69 1s infinite} |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,98 +1,130 @@ |
|||
<template> |
|||
<div class="root"> |
|||
Browser SDP |
|||
<br /> |
|||
<textarea readonly="true" rows="10" cols="100">{{localSDP||"loading..."}}</textarea> |
|||
<br />Golang SDP |
|||
<br /> |
|||
<textarea rows="10" cols="100">{{remoteSDP}}</textarea> |
|||
<br /> |
|||
<mu-text-field v-model="streamPath" label="streamPath"></mu-text-field> |
|||
<m-button @click="startSession" v-if="localSDP">Start</m-button> |
|||
<br /> |
|||
|
|||
<br />Video |
|||
<br /> |
|||
<video id="video1" width="160" height="120" autoplay muted></video> |
|||
<br />Logs |
|||
<br /> |
|||
<div id="logs"></div> |
|||
<div> |
|||
<pre v-if="$parent.titleTabActive == 1">{{localSDP}}</pre> |
|||
<pre v-else-if="$parent.titleTabActive == 2">{{remoteSDP}}</pre> |
|||
<div v-else> |
|||
<mu-text-field v-model="streamPath" label="streamPath"></mu-text-field> |
|||
<span class="blink" v-if="!localSDP || ask">Connecting</span> |
|||
<m-button @click="startSession" v-else-if="iceConnectionState!='connected'">Start</m-button> |
|||
<m-button @click="stopSession" v-else-if="iceConnectionState=='connected'">Stop</m-button> |
|||
<br /> |
|||
<video ref="video1" :srcObject.prop="stream" width="640" height="480" autoplay muted></video> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
let pc = new RTCPeerConnection({ |
|||
const config = { |
|||
iceServers:[ |
|||
{ |
|||
urls:[ |
|||
"stun:stun.ekiga.net", |
|||
"stun:stun.ideasip.com", |
|||
"stun:stun.schlund.de", |
|||
"stun:stun.stunprotocol.org:3478", |
|||
"stun:stun.voiparound.com", |
|||
"stun:stun.voipbuster.com", |
|||
"stun:stun.voipstunt.com", |
|||
"stun:stun.voxgratia.org", |
|||
"stun:stun.services.mozilla.com", |
|||
"stun:stun.xten.com", |
|||
"stun:stun.softjoys.com", |
|||
"stun:stunserver.org", |
|||
"stun:stun.schlund.de", |
|||
"stun:stun.rixtelecom.se", |
|||
"stun:stun.iptel.org", |
|||
"stun:stun.ideasip.com", |
|||
"stun:stun.fwdnet.net", |
|||
"stun:stun.ekiga.net", |
|||
"stun:stun01.sipphone.com", |
|||
"stun:stun.ekiga.net", |
|||
"stun:stun.ideasip.com", |
|||
"stun:stun.schlund.de", |
|||
"stun:stun.stunprotocol.org:3478", |
|||
"stun:stun.voiparound.com", |
|||
"stun:stun.voipbuster.com", |
|||
"stun:stun.voipstunt.com", |
|||
"stun:stun.voxgratia.org", |
|||
"stun:stun.services.mozilla.com", |
|||
"stun:stun.xten.com", |
|||
"stun:stun.softjoys.com", |
|||
"stun:stunserver.org", |
|||
"stun:stun.schlund.de", |
|||
"stun:stun.rixtelecom.se", |
|||
"stun:stun.iptel.org", |
|||
"stun:stun.ideasip.com", |
|||
"stun:stun.fwdnet.net", |
|||
"stun:stun.ekiga.net", |
|||
"stun:stun01.sipphone.com", |
|||
] |
|||
} |
|||
] |
|||
}); |
|||
} |
|||
let pc = new RTCPeerConnection(config); |
|||
var stream = null |
|||
var streamPath = "live/rtc" |
|||
export default { |
|||
data() { |
|||
return { |
|||
localSDP: "", |
|||
remoteSDP: "", |
|||
streamPath:"live/rtc" |
|||
localSDP: pc&&pc.localDescription&&pc.localDescription.sdp, |
|||
remoteSDP: pc&&pc.remoteDescription&&pc.remoteDescription.sdp, |
|||
streamPath, |
|||
iceConnectionState:pc&&pc.iceConnectionState, |
|||
stream, |
|||
ask:false |
|||
}; |
|||
}, |
|||
methods: { |
|||
startSession() { |
|||
this.ask = true |
|||
this.ajax({type: 'POST',processData:false,data: JSON.stringify(pc.localDescription),url:"/webrtc/answer?streamPath="+this.streamPath,dataType:"json"}).then(result => { |
|||
this.remoteSDP = result.sdp; |
|||
pc.setRemoteDescription(new RTCSessionDescription(result)); |
|||
this.ask = false |
|||
if (result.errmsg){ |
|||
this.$toast.error(result.errmsg) |
|||
}else{ |
|||
streamPath = this.streamPath |
|||
this.remoteSDP = result.sdp; |
|||
this.$parent.titleTabs = ["摄像头", "localSDP","remoteSDP"]; |
|||
pc.setRemoteDescription(new RTCSessionDescription(result)); |
|||
} |
|||
}); |
|||
}, |
|||
stopSession(){ |
|||
pc.close() |
|||
pc = new RTCPeerConnection(config) |
|||
this.remoteSDP = "" |
|||
this.localSDP = "" |
|||
this.connectICE().catch(err=> this.$toast.error(err.message)) |
|||
}, |
|||
async connectICE(){ |
|||
pc.addStream(stream); |
|||
await pc.setLocalDescription(await pc.createOffer()) |
|||
pc.oniceconnectionstatechange = e => { |
|||
this.$toast.info(pc.iceConnectionState) |
|||
this.iceConnectionState = pc.iceConnectionState |
|||
}; |
|||
pc.onicecandidate = event => { |
|||
if (event.candidate === null) { |
|||
this.localSDP = pc.localDescription.sdp; |
|||
this.$parent.titleTabs = ["摄像头", "localSDP"]; |
|||
} |
|||
}; |
|||
} |
|||
}, |
|||
mounted() { |
|||
/* eslint-env browser */ |
|||
var log = msg => { |
|||
document.getElementById("logs").innerHTML += msg + "<br>"; |
|||
}; |
|||
|
|||
navigator.mediaDevices |
|||
.getUserMedia({ video: true, audio: true }) |
|||
.then(stream => { |
|||
pc.addStream((document.getElementById("video1").srcObject = stream)); |
|||
pc.createOffer() |
|||
.then(d => pc.setLocalDescription(d)) |
|||
.catch(log); |
|||
}) |
|||
.catch(log); |
|||
|
|||
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState); |
|||
pc.onicecandidate = event => { |
|||
if (event.candidate === null) { |
|||
this.localSDP = pc.localDescription.sdp; |
|||
async mounted() { |
|||
if (this.localSDP){ |
|||
let tabs = ["摄像头"] |
|||
if(this.localSDP)tabs.push("localSDP") |
|||
if(this.remoteSDP)tabs.push("remoteSDP") |
|||
this.$parent.titleTabs = tabs; |
|||
} else { |
|||
try{ |
|||
if(!this.stream) |
|||
this.stream = stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true }) |
|||
await this.connectICE() |
|||
}catch(err){ |
|||
this.$toast.error(err.message) |
|||
} |
|||
}; |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style> |
|||
.root textarea{ |
|||
background: transparent; |
|||
color: cyan; |
|||
} |
|||
<style scoped> |
|||
@keyframes blink { |
|||
0% { |
|||
opacity: 0.2; |
|||
} |
|||
50% { |
|||
opacity: 1; |
|||
} |
|||
100% { |
|||
opacity: 0.2; |
|||
} |
|||
} |
|||
.blink { |
|||
animation: blink 1s infinite; |
|||
} |
|||
|
|||
</style> |
Loading…
Reference in new issue