mirror of
https://github.com/pion/webrtc.git
synced 2025-10-13 02:43:48 +08:00

committed by
Michiel De Backker

parent
756d74196d
commit
7a527fadb3
@@ -10,7 +10,7 @@ We've build an extensive collection of examples covering common use-cases. Modif
|
|||||||
* [data-channels](data-channels/README.md): Use data channels to send text between Pion WebRTC and your browser
|
* [data-channels](data-channels/README.md): Use data channels to send text between Pion WebRTC and your browser
|
||||||
* [data-channels-create](data-channels/README.md): Similar to data channels but now Pion initiates the creation of the data channel.
|
* [data-channels-create](data-channels/README.md): Similar to data channels but now Pion initiates the creation of the data channel.
|
||||||
* [sfu](sfu/README.md): Broadcast a video to many peers, while only requiring the broadcaster to upload once
|
* [sfu](sfu/README.md): Broadcast a video to many peers, while only requiring the broadcaster to upload once
|
||||||
* [WIP] [pion-to-pion](pion-to-pion/README.md): An example of two Pion instances communicating directly.
|
* [pion-to-pion](pion-to-pion/README.md): An example of two Pion instances communicating directly.
|
||||||
|
|
||||||
All examples can be executed on your local machine.
|
All examples can be executed on your local machine.
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@ go get github.com/pions/webrtc/examples/data-channels-create
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Open data-channels-create example page
|
### Open data-channels-create example page
|
||||||
[jsfiddle.net](https://jsfiddle.net/swgxrp94/19/)
|
[jsfiddle.net](https://jsfiddle.net/swgxrp94/20/)
|
||||||
|
|
||||||
### Run data-channels-create
|
### Run data-channels-create
|
||||||
Just run run `data-channels-create`.
|
Just run run `data-channels-create`.
|
||||||
|
@@ -15,7 +15,7 @@ pc.onsignalingstatechange = e => log(pc.signalingState)
|
|||||||
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState)
|
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState)
|
||||||
pc.onicecandidate = event => {
|
pc.onicecandidate = event => {
|
||||||
if (event.candidate === null) {
|
if (event.candidate === null) {
|
||||||
document.getElementById('localSessionDescription').value = btoa(pc.localDescription.sdp)
|
document.getElementById('localSessionDescription').value = btoa(JSON.stringify(pc.localDescription))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,6 +41,6 @@ window.startSession = () => {
|
|||||||
return alert('Session Description must not be empty')
|
return alert('Session Description must not be empty')
|
||||||
}
|
}
|
||||||
|
|
||||||
pc.setRemoteDescription(new RTCSessionDescription({type: 'offer', sdp: atob(sd)})).catch(log)
|
pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(sd)))).catch(log)
|
||||||
pc.createAnswer().then(d => pc.setLocalDescription(d)).catch(log)
|
pc.createAnswer().then(d => pc.setLocalDescription(d)).catch(log)
|
||||||
}
|
}
|
||||||
|
@@ -39,8 +39,8 @@ func main() {
|
|||||||
// Register channel opening handling
|
// Register channel opening handling
|
||||||
dataChannel.OnOpen(func() {
|
dataChannel.OnOpen(func() {
|
||||||
fmt.Printf("Data channel '%s'-'%d' open. Random messages will now be sent to any connected DataChannels every 5 seconds\n", dataChannel.Label, dataChannel.ID)
|
fmt.Printf("Data channel '%s'-'%d' open. Random messages will now be sent to any connected DataChannels every 5 seconds\n", dataChannel.Label, dataChannel.ID)
|
||||||
for {
|
|
||||||
time.Sleep(5 * time.Second)
|
for range time.NewTicker(5 * time.Second).C {
|
||||||
message := util.RandSeq(15)
|
message := util.RandSeq(15)
|
||||||
fmt.Printf("Sending %s \n", message)
|
fmt.Printf("Sending %s \n", message)
|
||||||
|
|
||||||
@@ -66,16 +66,10 @@ func main() {
|
|||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Output the offer in base64 so we can paste it in browser
|
// Output the offer in base64 so we can paste it in browser
|
||||||
fmt.Println(util.Encode(offer.Sdp))
|
fmt.Println(util.Encode(offer))
|
||||||
|
|
||||||
// Wait for the answer to be pasted
|
// Wait for the answer to be pasted
|
||||||
sd := util.Decode(util.MustReadStdin())
|
answer := util.Decode(util.MustReadStdin())
|
||||||
|
|
||||||
// Set the remote SessionDescription
|
|
||||||
answer := webrtc.RTCSessionDescription{
|
|
||||||
Type: webrtc.RTCSdpTypeAnswer,
|
|
||||||
Sdp: sd,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply the answer as the remote description
|
// Apply the answer as the remote description
|
||||||
err = peerConnection.SetRemoteDescription(answer)
|
err = peerConnection.SetRemoteDescription(answer)
|
||||||
|
@@ -8,7 +8,7 @@ go get github.com/pions/webrtc/examples/data-channels
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Open data-channels example page
|
### Open data-channels example page
|
||||||
[jsfiddle.net](http://jsfiddle.net/9tsx15mg/35/)
|
[jsfiddle.net](https://jsfiddle.net/9tsx15mg/90/)
|
||||||
|
|
||||||
### Run data-channels, with your browsers SessionDescription as stdin
|
### Run data-channels, with your browsers SessionDescription as stdin
|
||||||
In the jsfiddle the top textarea is your browser's session description, copy that and:
|
In the jsfiddle the top textarea is your browser's session description, copy that and:
|
||||||
|
@@ -19,7 +19,7 @@ sendChannel.onmessage = e => log(`Message from DataChannel '${sendChannel.label}
|
|||||||
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState)
|
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState)
|
||||||
pc.onicecandidate = event => {
|
pc.onicecandidate = event => {
|
||||||
if (event.candidate === null) {
|
if (event.candidate === null) {
|
||||||
document.getElementById('localSessionDescription').value = btoa(pc.localDescription.sdp)
|
document.getElementById('localSessionDescription').value = btoa(JSON.stringify(pc.localDescription))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ window.startSession = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
pc.setRemoteDescription(new RTCSessionDescription({type: 'answer', sdp: atob(sd)}))
|
pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(sd))))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert(e)
|
alert(e)
|
||||||
}
|
}
|
||||||
|
@@ -39,8 +39,8 @@ func main() {
|
|||||||
// Register channel opening handling
|
// Register channel opening handling
|
||||||
d.OnOpen(func() {
|
d.OnOpen(func() {
|
||||||
fmt.Printf("Data channel '%s'-'%d' open. Random messages will now be sent to any connected DataChannels every 5 seconds\n", d.Label, d.ID)
|
fmt.Printf("Data channel '%s'-'%d' open. Random messages will now be sent to any connected DataChannels every 5 seconds\n", d.Label, d.ID)
|
||||||
for {
|
|
||||||
time.Sleep(5 * time.Second)
|
for range time.NewTicker(5 * time.Second).C {
|
||||||
message := util.RandSeq(15)
|
message := util.RandSeq(15)
|
||||||
fmt.Printf("Sending %s \n", message)
|
fmt.Printf("Sending %s \n", message)
|
||||||
|
|
||||||
@@ -63,13 +63,9 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Wait for the offer to be pasted
|
// Wait for the offer to be pasted
|
||||||
sd := util.Decode(util.MustReadStdin())
|
offer := util.Decode(util.MustReadStdin())
|
||||||
|
|
||||||
// Set the remote SessionDescription
|
// Set the remote SessionDescription
|
||||||
offer := webrtc.RTCSessionDescription{
|
|
||||||
Type: webrtc.RTCSdpTypeOffer,
|
|
||||||
Sdp: string(sd),
|
|
||||||
}
|
|
||||||
err = peerConnection.SetRemoteDescription(offer)
|
err = peerConnection.SetRemoteDescription(offer)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
@@ -78,7 +74,7 @@ func main() {
|
|||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Output the answer in base64 so we can paste it in browser
|
// Output the answer in base64 so we can paste it in browser
|
||||||
fmt.Println(util.Encode(answer.Sdp))
|
fmt.Println(util.Encode(answer))
|
||||||
|
|
||||||
// Block forever
|
// Block forever
|
||||||
select {}
|
select {}
|
||||||
|
@@ -14,7 +14,7 @@ go get github.com/pions/webrtc/examples/gstreamer-receive
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Open gstreamer-receive example page
|
### Open gstreamer-receive example page
|
||||||
[jsfiddle.net](https://jsfiddle.net/usd3xmtz/45/) you should see your Webcam, two text-areas and a 'Start Session' button
|
[jsfiddle.net](https://jsfiddle.net/usd3xmtz/109/) you should see your Webcam, two text-areas and a 'Start Session' button
|
||||||
|
|
||||||
### Run gstreamer-receive with your browsers SessionDescription as stdin
|
### Run gstreamer-receive with your browsers SessionDescription as stdin
|
||||||
In the jsfiddle the top textarea is your browser, copy that and:
|
In the jsfiddle the top textarea is your browser, copy that and:
|
||||||
|
@@ -18,7 +18,7 @@ navigator.mediaDevices.getUserMedia({video: true, audio: true})
|
|||||||
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState)
|
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState)
|
||||||
pc.onicecandidate = event => {
|
pc.onicecandidate = event => {
|
||||||
if (event.candidate === null) {
|
if (event.candidate === null) {
|
||||||
document.getElementById('localSessionDescription').value = btoa(pc.localDescription.sdp)
|
document.getElementById('localSessionDescription').value = btoa(JSON.stringify(pc.localDescription))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ window.startSession = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
pc.setRemoteDescription(new RTCSessionDescription({type: 'answer', sdp: atob(sd)}))
|
pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(sd))))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert(e)
|
alert(e)
|
||||||
}
|
}
|
||||||
|
@@ -48,13 +48,9 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Wait for the offer to be pasted
|
// Wait for the offer to be pasted
|
||||||
sd := util.Decode(util.MustReadStdin())
|
offer := util.Decode(util.MustReadStdin())
|
||||||
|
|
||||||
// Set the remote SessionDescription
|
// Set the remote SessionDescription
|
||||||
offer := webrtc.RTCSessionDescription{
|
|
||||||
Type: webrtc.RTCSdpTypeOffer,
|
|
||||||
Sdp: string(sd),
|
|
||||||
}
|
|
||||||
err = peerConnection.SetRemoteDescription(offer)
|
err = peerConnection.SetRemoteDescription(offer)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
@@ -63,7 +59,7 @@ func main() {
|
|||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Output the answer in base64 so we can paste it in browser
|
// Output the answer in base64 so we can paste it in browser
|
||||||
fmt.Println(util.Encode(answer.Sdp))
|
fmt.Println(util.Encode(answer))
|
||||||
|
|
||||||
// Block forever
|
// Block forever
|
||||||
select {}
|
select {}
|
||||||
|
@@ -52,16 +52,12 @@ func main() {
|
|||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Output the offer in base64 so we can paste it in browser
|
// Output the offer in base64 so we can paste it in browser
|
||||||
fmt.Println(util.Encode(offer.Sdp))
|
fmt.Println(util.Encode(offer))
|
||||||
|
|
||||||
// Wait for the answer to be pasted
|
// Wait for the answer to be pasted
|
||||||
sd := util.Decode(util.MustReadStdin())
|
answer := util.Decode(util.MustReadStdin())
|
||||||
|
|
||||||
// Set the remote SessionDescription
|
// Set the remote SessionDescription
|
||||||
answer := webrtc.RTCSessionDescription{
|
|
||||||
Type: webrtc.RTCSdpTypeAnswer,
|
|
||||||
Sdp: sd,
|
|
||||||
}
|
|
||||||
err = peerConnection.SetRemoteDescription(answer)
|
err = peerConnection.SetRemoteDescription(answer)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
|
@@ -14,7 +14,7 @@ go get github.com/pions/webrtc/examples/gstreamer-send
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Open gstreamer-send example page
|
### Open gstreamer-send example page
|
||||||
[jsfiddle.net](https://jsfiddle.net/Laf7ujeo/14/) you should see two text-areas and a 'Start Session' button
|
[jsfiddle.net](https://jsfiddle.net/Laf7ujeo/164/) you should see two text-areas and a 'Start Session' button
|
||||||
|
|
||||||
### Run gstreamer-send with your browsers SessionDescription as stdin
|
### Run gstreamer-send with your browsers SessionDescription as stdin
|
||||||
In the jsfiddle the top textarea is your browser, copy that and:
|
In the jsfiddle the top textarea is your browser, copy that and:
|
||||||
|
@@ -23,7 +23,7 @@ pc.ontrack = function (event) {
|
|||||||
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState)
|
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState)
|
||||||
pc.onicecandidate = event => {
|
pc.onicecandidate = event => {
|
||||||
if (event.candidate === null) {
|
if (event.candidate === null) {
|
||||||
document.getElementById('localSessionDescription').value = btoa(pc.localDescription.sdp)
|
document.getElementById('localSessionDescription').value = btoa(JSON.stringify(pc.localDescription))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ window.startSession = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
pc.setRemoteDescription(new RTCSessionDescription({type: 'answer', sdp: atob(sd)}))
|
pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(sd))))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert(e)
|
alert(e)
|
||||||
}
|
}
|
||||||
|
@@ -48,13 +48,9 @@ func main() {
|
|||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Wait for the offer to be pasted
|
// Wait for the offer to be pasted
|
||||||
sd := util.Decode(util.MustReadStdin())
|
offer := util.Decode(util.MustReadStdin())
|
||||||
|
|
||||||
// Set the remote SessionDescription
|
// Set the remote SessionDescription
|
||||||
offer := webrtc.RTCSessionDescription{
|
|
||||||
Type: webrtc.RTCSdpTypeOffer,
|
|
||||||
Sdp: string(sd),
|
|
||||||
}
|
|
||||||
err = peerConnection.SetRemoteDescription(offer)
|
err = peerConnection.SetRemoteDescription(offer)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
@@ -63,7 +59,7 @@ func main() {
|
|||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Output the answer in base64 so we can paste it in browser
|
// Output the answer in base64 so we can paste it in browser
|
||||||
fmt.Println(util.Encode(answer.Sdp))
|
fmt.Println(util.Encode(answer))
|
||||||
|
|
||||||
// Start pushing buffers on these tracks
|
// Start pushing buffers on these tracks
|
||||||
gst.CreatePipeline(webrtc.Opus, opusTrack.Samples).Start()
|
gst.CreatePipeline(webrtc.Opus, opusTrack.Samples).Start()
|
||||||
|
@@ -8,7 +8,7 @@ go get github.com/pions/webrtc/examples/save-to-disk
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Open save-to-disk example page
|
### Open save-to-disk example page
|
||||||
[jsfiddle.net](https://jsfiddle.net/dyj8qpek/1/) you should see your Webcam, two text-areas and a 'Start Session' button
|
[jsfiddle.net](https://jsfiddle.net/dyj8qpek/19/) you should see your Webcam, two text-areas and a 'Start Session' button
|
||||||
|
|
||||||
### Run save-to-disk, with your browsers SessionDescription as stdin
|
### Run save-to-disk, with your browsers SessionDescription as stdin
|
||||||
In the jsfiddle the top textarea is your browser, copy that and:
|
In the jsfiddle the top textarea is your browser, copy that and:
|
||||||
|
@@ -18,7 +18,7 @@ navigator.mediaDevices.getUserMedia({video: true, audio: true})
|
|||||||
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState)
|
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState)
|
||||||
pc.onicecandidate = event => {
|
pc.onicecandidate = event => {
|
||||||
if (event.candidate === null) {
|
if (event.candidate === null) {
|
||||||
document.getElementById('localSessionDescription').value = btoa(pc.localDescription.sdp)
|
document.getElementById('localSessionDescription').value = btoa(JSON.stringify(pc.localDescription))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ window.startSession = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
pc.setRemoteDescription(new RTCSessionDescription({type: 'answer', sdp: atob(sd)}))
|
pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(sd))))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert(e)
|
alert(e)
|
||||||
}
|
}
|
||||||
|
@@ -52,13 +52,9 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Wait for the offer to be pasted
|
// Wait for the offer to be pasted
|
||||||
sd := util.Decode(util.MustReadStdin())
|
offer := util.Decode(util.MustReadStdin())
|
||||||
|
|
||||||
// Set the remote SessionDescription
|
// Set the remote SessionDescription
|
||||||
offer := webrtc.RTCSessionDescription{
|
|
||||||
Type: webrtc.RTCSdpTypeOffer,
|
|
||||||
Sdp: string(sd),
|
|
||||||
}
|
|
||||||
err = peerConnection.SetRemoteDescription(offer)
|
err = peerConnection.SetRemoteDescription(offer)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
@@ -67,7 +63,7 @@ func main() {
|
|||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Output the answer in base64 so we can paste it in browser
|
// Output the answer in base64 so we can paste it in browser
|
||||||
fmt.Println(util.Encode(answer.Sdp))
|
fmt.Println(util.Encode(answer))
|
||||||
|
|
||||||
// Block forever
|
// Block forever
|
||||||
select {}
|
select {}
|
||||||
|
@@ -10,7 +10,7 @@ go get github.com/pions/webrtc/examples/sfu
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Open sfu example page
|
### Open sfu example page
|
||||||
[jsfiddle.net](https://jsfiddle.net/5cwx0rns/) You should see two buttons 'Publish a Broadcast' and 'Join a Broadcast'
|
[jsfiddle.net](https://jsfiddle.net/5cwx0rns/11/) You should see two buttons 'Publish a Broadcast' and 'Join a Broadcast'
|
||||||
|
|
||||||
### Run SFU
|
### Run SFU
|
||||||
#### Linux/macOS
|
#### Linux/macOS
|
||||||
|
@@ -14,7 +14,7 @@ window.createSession = isPublisher => {
|
|||||||
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState)
|
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState)
|
||||||
pc.onicecandidate = event => {
|
pc.onicecandidate = event => {
|
||||||
if (event.candidate === null) {
|
if (event.candidate === null) {
|
||||||
document.getElementById('localSessionDescription').value = btoa(pc.localDescription.sdp)
|
document.getElementById('localSessionDescription').value = btoa(JSON.stringify(pc.localDescription))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ window.createSession = isPublisher => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
pc.setRemoteDescription(new RTCSessionDescription({type: 'answer', sdp: atob(sd)}))
|
pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(sd))))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert(e)
|
alert(e)
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,7 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
|
||||||
"github.com/pions/webrtc"
|
"github.com/pions/webrtc"
|
||||||
|
"github.com/pions/webrtc/examples/util"
|
||||||
"github.com/pions/webrtc/pkg/media"
|
"github.com/pions/webrtc/pkg/media"
|
||||||
"github.com/pions/webrtc/pkg/media/samplebuilder"
|
"github.com/pions/webrtc/pkg/media/samplebuilder"
|
||||||
"github.com/pions/webrtc/pkg/rtcp"
|
"github.com/pions/webrtc/pkg/rtcp"
|
||||||
@@ -47,7 +48,7 @@ const (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
reader := bufio.NewReader(os.Stdin)
|
reader := bufio.NewReader(os.Stdin)
|
||||||
sd := mustReadStdin(reader)
|
offer := util.Decode(mustReadStdin(reader))
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
|
|
||||||
/* Everything below is the pion-WebRTC API, thanks for using it! */
|
/* Everything below is the pion-WebRTC API, thanks for using it! */
|
||||||
@@ -90,22 +91,19 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Set the remote SessionDescription
|
// Set the remote SessionDescription
|
||||||
check(peerConnection.SetRemoteDescription(webrtc.RTCSessionDescription{
|
check(peerConnection.SetRemoteDescription(offer))
|
||||||
Type: webrtc.RTCSdpTypeOffer,
|
|
||||||
Sdp: string(sd),
|
|
||||||
}))
|
|
||||||
|
|
||||||
// Sets the LocalDescription, and starts our UDP listeners
|
// Sets the LocalDescription, and starts our UDP listeners
|
||||||
answer, err := peerConnection.CreateAnswer(nil)
|
answer, err := peerConnection.CreateAnswer(nil)
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
// Get the LocalDescription and take it to base64 so we can paste in browser
|
// Get the LocalDescription and take it to base64 so we can paste in browser
|
||||||
fmt.Println(base64.StdEncoding.EncodeToString([]byte(answer.Sdp)))
|
fmt.Println(util.Encode(answer))
|
||||||
|
|
||||||
for {
|
for {
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
fmt.Println("Paste an SDP to start sendonly peer connection")
|
fmt.Println("Paste an SDP to start sendonly peer connection")
|
||||||
recvOnlyOffer := mustReadStdin(reader)
|
recvOnlyOffer := util.Decode(mustReadStdin(reader))
|
||||||
|
|
||||||
// Create a new RTCPeerConnection
|
// Create a new RTCPeerConnection
|
||||||
peerConnection, err := webrtc.New(peerConnectionConfig)
|
peerConnection, err := webrtc.New(peerConnectionConfig)
|
||||||
@@ -123,16 +121,14 @@ func main() {
|
|||||||
outboundSamplesLock.Unlock()
|
outboundSamplesLock.Unlock()
|
||||||
|
|
||||||
// Set the remote SessionDescription
|
// Set the remote SessionDescription
|
||||||
check(peerConnection.SetRemoteDescription(webrtc.RTCSessionDescription{
|
err = peerConnection.SetRemoteDescription(recvOnlyOffer)
|
||||||
Type: webrtc.RTCSdpTypeOffer,
|
check(err)
|
||||||
Sdp: string(recvOnlyOffer),
|
|
||||||
}))
|
|
||||||
|
|
||||||
// Sets the LocalDescription, and starts our UDP listeners
|
// Sets the LocalDescription, and starts our UDP listeners
|
||||||
answer, err := peerConnection.CreateAnswer(nil)
|
answer, err := peerConnection.CreateAnswer(nil)
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
// Get the LocalDescription and take it to base64 so we can paste in browser
|
// Get the LocalDescription and take it to base64 so we can paste in browser
|
||||||
fmt.Println(base64.StdEncoding.EncodeToString([]byte(answer.Sdp)))
|
fmt.Println(util.Encode(answer))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@@ -12,6 +13,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pions/webrtc"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Allows compressing offer/answer to bypass terminal input limits.
|
// Allows compressing offer/answer to bypass terminal input limits.
|
||||||
@@ -49,27 +52,32 @@ func MustReadStdin() string {
|
|||||||
|
|
||||||
// Encode encodes the input in base64
|
// Encode encodes the input in base64
|
||||||
// It can optionally zip the input before encoding
|
// It can optionally zip the input before encoding
|
||||||
func Encode(in string) string {
|
func Encode(sdp webrtc.RTCSessionDescription) string {
|
||||||
|
b, err := json.Marshal(sdp)
|
||||||
|
Check(err)
|
||||||
|
|
||||||
if compress {
|
if compress {
|
||||||
in = zip(in)
|
b = zip(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
return base64.StdEncoding.EncodeToString([]byte(in))
|
return base64.StdEncoding.EncodeToString(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes the input from base64
|
// Decode decodes the input from base64
|
||||||
// It can optionally unzip the input after decoding
|
// It can optionally unzip the input after decoding
|
||||||
func Decode(in string) string {
|
func Decode(in string) webrtc.RTCSessionDescription {
|
||||||
b, err := base64.StdEncoding.DecodeString(in)
|
b, err := base64.StdEncoding.DecodeString(in)
|
||||||
Check(err)
|
Check(err)
|
||||||
|
|
||||||
out := string(b)
|
|
||||||
|
|
||||||
if compress {
|
if compress {
|
||||||
out = unzip(out)
|
b = unzip(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
return out
|
var sdp webrtc.RTCSessionDescription
|
||||||
|
err = json.Unmarshal(b, &sdp)
|
||||||
|
Check(err)
|
||||||
|
|
||||||
|
return sdp
|
||||||
}
|
}
|
||||||
|
|
||||||
// RandSeq generates a random string to serve as dummy data
|
// RandSeq generates a random string to serve as dummy data
|
||||||
@@ -83,25 +91,25 @@ func RandSeq(n int) string {
|
|||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func zip(in string) string {
|
func zip(in []byte) []byte {
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
gz := gzip.NewWriter(&b)
|
gz := gzip.NewWriter(&b)
|
||||||
_, err := gz.Write([]byte(in))
|
_, err := gz.Write(in)
|
||||||
Check(err)
|
Check(err)
|
||||||
err = gz.Flush()
|
err = gz.Flush()
|
||||||
Check(err)
|
Check(err)
|
||||||
err = gz.Close()
|
err = gz.Close()
|
||||||
Check(err)
|
Check(err)
|
||||||
return string(b.Bytes())
|
return b.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
func unzip(in string) string {
|
func unzip(in []byte) []byte {
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
_, err := b.Write([]byte(in))
|
_, err := b.Write(in)
|
||||||
Check(err)
|
Check(err)
|
||||||
r, err := gzip.NewReader(&b)
|
r, err := gzip.NewReader(&b)
|
||||||
Check(err)
|
Check(err)
|
||||||
res, err := ioutil.ReadAll(r)
|
res, err := ioutil.ReadAll(r)
|
||||||
Check(err)
|
Check(err)
|
||||||
return string(res)
|
return res
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user