Create "working" example
This commit is contained in:
111
gobot-gui/frontend/src/lib/Feedtes.svelte
Normal file
111
gobot-gui/frontend/src/lib/Feedtes.svelte
Normal file
@@ -0,0 +1,111 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
|
||||
let videoElementIn: HTMLVideoElement;
|
||||
let videoElementOut: HTMLVideoElement;
|
||||
let peerConnection: RTCPeerConnection;
|
||||
let incomingStream: MediaStream;
|
||||
let outgoingStream: MediaStream;
|
||||
|
||||
let offerBase64Out: string;
|
||||
let offerBase64In: string;
|
||||
let answerBase64Out: string;
|
||||
let answerBase64In: string;
|
||||
let iceCandidate: RTCIceCandidate[] = [];
|
||||
|
||||
onMount(() => {
|
||||
|
||||
})
|
||||
|
||||
async function getIce(d: RTCSessionDescription | RTCSessionDescriptionInit): Promise<RTCIceCandidate[]> {
|
||||
let icecandidate: RTCIceCandidate[] = [];
|
||||
peerConnection.addEventListener("icecandidate", (event) => {
|
||||
if(event.candidate) {
|
||||
icecandidate.push(event.candidate);
|
||||
}
|
||||
});
|
||||
|
||||
await peerConnection.setLocalDescription(d);
|
||||
|
||||
console.log("2asd");
|
||||
|
||||
await new Promise((resolve) => {
|
||||
if(peerConnection.iceGatheringState === 'complete') {
|
||||
resolve(null);
|
||||
} else {
|
||||
peerConnection.addEventListener('icegatheringstatechange', () => {
|
||||
console.log(peerConnection.iceGatheringState);
|
||||
if(peerConnection.iceGatheringState === 'complete') {
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
console.log("3asd");
|
||||
|
||||
return icecandidate;
|
||||
}
|
||||
|
||||
|
||||
async function start_rx() {
|
||||
peerConnection = new RTCPeerConnection({
|
||||
certificates: [],
|
||||
iceServers: [],
|
||||
iceTransportPolicy: "all",
|
||||
// @ts-ignore
|
||||
rtcpMuxPolicy: 'negotiate' // Workaround, typescript doesn't know about this property
|
||||
});
|
||||
|
||||
const offer = await peerConnection.createOffer();
|
||||
|
||||
iceCandidate = await getIce(offer);
|
||||
console.log("asd");
|
||||
console.log(iceCandidate);
|
||||
}
|
||||
|
||||
async function start_tx() {
|
||||
console.log("Starting TX");
|
||||
peerConnection = new RTCPeerConnection({
|
||||
certificates: [],
|
||||
iceServers: [],
|
||||
iceTransportPolicy: "all",
|
||||
// @ts-ignore
|
||||
rtcpMuxPolicy: 'negotiate' // Workaround, typescript doesn't know about this property
|
||||
});
|
||||
|
||||
iceCandidate = await getIce();
|
||||
|
||||
}
|
||||
|
||||
async function copy_to_clip_board(s: string) {
|
||||
await navigator.clipboard.writeText(s);
|
||||
console.log("Copied to clipboard");
|
||||
}
|
||||
</script>
|
||||
|
||||
<main>
|
||||
|
||||
<video bind:this={videoElementIn} autoplay playsinline></video>
|
||||
<video bind:this={videoElementOut} autoplay playsinline></video>
|
||||
|
||||
<button on:click={start_tx}>Start TX</button>
|
||||
<button on:click={start_rx}>Start RX</button>
|
||||
<br>
|
||||
|
||||
<p>Offer: {offerBase64Out}</p>
|
||||
<button on:click={() => copy_to_clip_board(offerBase64Out)}>Copy Offer</button>
|
||||
<input type="text" bind:value={offerBase64In}>
|
||||
<br>
|
||||
|
||||
<p>Answere: {answerBase64Out}</p>
|
||||
<button on:click={() => copy_to_clip_board(answerBase64Out)}>Copy Answer</button>
|
||||
<input type="text" bind:value={offerBase64In}>
|
||||
|
||||
<br>
|
||||
<p>Ice Candiates</p>
|
||||
{#each iceCandidate as ice}
|
||||
<p>{ice.address}, {ice.port}, {ice.protocol}</p>
|
||||
{/each}
|
||||
</main>
|
||||
@@ -3,11 +3,25 @@
|
||||
|
||||
let peerConnection: RTCPeerConnection;
|
||||
let videoElement: HTMLVideoElement;
|
||||
let incommingStream: MediaStream;
|
||||
|
||||
async function negotiateWebRTC(peerConn: RTCPeerConnection) {
|
||||
incommingStream = new MediaStream();
|
||||
videoElement.srcObject = incommingStream;
|
||||
peerConn.addTransceiver('video', { direction: 'recvonly' });
|
||||
|
||||
const offer = await peerConn.createOffer();
|
||||
const offer = await peerConn.createOffer({
|
||||
offerToReceiveVideo: true
|
||||
});
|
||||
let icecandidate: RTCIceCandidate[] = [];
|
||||
|
||||
peerConnection.addEventListener("icecandidate", (event) => {
|
||||
if(event.candidate) {
|
||||
icecandidate.push(event.candidate);
|
||||
}
|
||||
});
|
||||
|
||||
// This does ICE gathering
|
||||
await peerConn.setLocalDescription(offer);
|
||||
|
||||
await new Promise((resolve) => {
|
||||
@@ -15,9 +29,9 @@
|
||||
resolve(null);
|
||||
} else {
|
||||
peerConn.addEventListener('icegatheringstatechange', () => {
|
||||
console.log(peerConn.iceGatheringState);
|
||||
if(peerConn.iceGatheringState === 'complete')
|
||||
if(peerConn.iceGatheringState === 'complete') {
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -27,34 +41,50 @@
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ offer })
|
||||
body: JSON.stringify({ offer, ice: icecandidate})
|
||||
})).json();
|
||||
|
||||
//console.log(remoteOffer.sdp);
|
||||
|
||||
await peerConn.setRemoteDescription(remoteOffer);
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
peerConnection = new RTCPeerConnection({
|
||||
iceServers: []
|
||||
certificates: [],
|
||||
iceServers: [],
|
||||
iceTransportPolicy: "all",
|
||||
// @ts-ignore
|
||||
rtcpMuxPolicy: 'negotiate' // Workaround, typescript doesn't know about this property
|
||||
});
|
||||
|
||||
peerConnection.addEventListener('track', (event) => {
|
||||
console.log('track', event);
|
||||
videoElement.srcObject = event.streams[0];
|
||||
event.streams[0].getTracks().forEach(track => {
|
||||
incommingStream.addTrack(track);
|
||||
});
|
||||
});
|
||||
|
||||
peerConnection.addEventListener("icecandidate", (event) => {
|
||||
if(event.candidate) {
|
||||
console.log(event.candidate.candidate);
|
||||
}
|
||||
});
|
||||
|
||||
await negotiateWebRTC(peerConnection);
|
||||
peerConnection.onconnectionstatechange = () => {
|
||||
console.log("PC State:", peerConnection.connectionState);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
function start_playing() {
|
||||
videoElement.play();
|
||||
}
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<video bind:this={videoElement}></video>
|
||||
<!-- svelte-ignore a11y-media-has-caption -->
|
||||
<video bind:this={videoElement} autoplay playsinline></video>
|
||||
|
||||
<button>stop</button>
|
||||
<button>start</button>
|
||||
<button on:click={start_playing}>start</button>
|
||||
</main>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<script>
|
||||
import Feedtes from "$lib/Feedtes.svelte";
|
||||
import LiveFeed from "$lib/LiveFeed.svelte";
|
||||
|
||||
</script>
|
||||
|
||||
<LiveFeed/>
|
||||
<Feedtes/>
|
||||
|
||||
<!--
|
||||
<LiveFeed/>
|
||||
-->
|
||||
Reference in New Issue
Block a user