Skip to content

Commit

Permalink
Copy and fix aiortc/examples/server/client.js to the frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
whitphx committed Jan 24, 2021
1 parent f6daf28 commit e3f70e4
Showing 1 changed file with 94 additions and 1 deletion.
95 changes: 94 additions & 1 deletion tiny_streamlit_webrtc/frontend/src/TinyWebrtc.tsx
Expand Up @@ -2,6 +2,7 @@ import {
Streamlit,
StreamlitComponentBase,
withStreamlitConnection,
ComponentProps,
} from "streamlit-component-lib"
import React, { ReactNode } from "react"

Expand All @@ -10,8 +11,100 @@ interface State {}
class TinyWebrtc extends StreamlitComponentBase<State> {
public state = {}

private pc: RTCPeerConnection | undefined
private videoRef: React.RefObject<HTMLVideoElement>

constructor(props: ComponentProps) {
super(props)

this.pc = undefined
this.videoRef = React.createRef()
}

public render = (): ReactNode => {
return <span></span>
return (
<div>
<button onClick={this.start}>Start</button>
<video ref={this.videoRef} autoPlay playsInline />
</div>
)
}

private createPeerConnection = () => {
const config: RTCConfiguration = {}
const pc = new RTCPeerConnection(config)

// connect audio / video
pc.addEventListener("track", (evt) => {
if (evt.track.kind === "video") {
const videoElement = this.videoRef.current
if (videoElement != null) {
videoElement.srcObject = evt.streams[0]
} else {
console.warn("Video element is not mounted.")
}
}
})

return pc
}

private negotiate = (pc: RTCPeerConnection) => {
return pc
.createOffer()
.then(function (offer) {
return pc.setLocalDescription(offer)
})
.then(function () {
// wait for ICE gathering to complete
return new Promise<void>(function (resolve) {
if (pc.iceGatheringState === "complete") {
resolve()
} else {
const checkState = () => {
if (pc.iceGatheringState === "complete") {
pc.removeEventListener("icegatheringstatechange", checkState)
resolve()
}
}
pc.addEventListener("icegatheringstatechange", checkState)
}
})
})
.then(function () {
const offer = pc.localDescription

if (offer == null) {
console.error("Offer is null.")
return
}

// Offer is created!
console.log(offer)
})
}

private start = () => {
const pc = this.createPeerConnection()

const constraints: MediaStreamConstraints = {
audio: false,
video: true,
}

navigator.mediaDevices.getUserMedia(constraints).then(
(stream) => {
stream.getTracks().forEach(function (track) {
pc.addTrack(track, stream)
})
return this.negotiate(pc)
},
function (err) {
alert("Could not acquire media: " + err)
}
)

this.pc = pc
}
}

Expand Down

0 comments on commit e3f70e4

Please sign in to comment.