Skip to content
This repository has been archived by the owner on Mar 16, 2022. It is now read-only.

Commit

Permalink
Add examples/echo
Browse files Browse the repository at this point in the history
The echo example demonstrates how to have Pion
send back to the user exactly what it receives
using the same PeerConnection.

Relates to pion#560

Co-authored-by: Patrice Ferlet <[email protected]>
  • Loading branch information
Sean-Der and metal3d committed May 19, 2019
1 parent c13256b commit 77cacbb
Show file tree
Hide file tree
Showing 8 changed files with 212 additions and 0 deletions.
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ For more full featured examples that use 3rd party libraries see our **[example-

### Overview
#### Media API
* [Echo](echo): The echo example demonstrates how to have Pion send back to the user exactly what it receives using the same PeerConnection .
* [Save to Disk](save-to-disk): The save-to-disk example shows how to record your webcam and save the footage to disk on the server side.
* [SFU Minimal](sfu-minimal): The SFU example demonstrates how to broadcast a video to multiple peers. A broadcaster uploads the video once and the server forwards it to all other peers.

Expand Down
27 changes: 27 additions & 0 deletions examples/echo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# echo
echo demonstrates how with one PeerConnection you can send video to Pion and have the packets sent back. This example could be easily extended to do server side processing.

## Instructions
### Download echo
```
go get github.com/pion/webrtc/examples/echo
```

### Open echo example page
[jsfiddle.net](https://jsfiddle.net/3m0zute8/) you should see two text-areas and a 'Start Session' button.

### Run echo, with your browsers SessionDescription as stdin
In the jsfiddle the top textarea is your browser, copy that and:
#### Linux/macOS
Run `echo $BROWSER_SDP | echo`
#### Windows
1. Paste the SessionDescription into a file.
1. Run `echo < my_file`

### Input echo's SessionDescription into your browser
Copy the text that `echo` just emitted and copy into second text area

### Hit 'Start Session' in jsfiddle, enjoy your video!
Your browser should send video to Pion, and then it will be relayed right back to you.

Congrats, you have used pion-WebRTC! Now start building something cool
4 changes: 4 additions & 0 deletions examples/echo/jsfiddle/demo.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
textarea {
width: 500px;
min-height: 75px;
}
5 changes: 5 additions & 0 deletions examples/echo/jsfiddle/demo.details
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
name: echo
description: Example of how to have Pion send back to the user exactly what it receives using the same PeerConnection.
authors:
- Sean DuBois
14 changes: 14 additions & 0 deletions examples/echo/jsfiddle/demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Browser base64 Session Description<br />
<textarea id="localSessionDescription" readonly="true"></textarea> <br />

Golang base64 Session Description<br />
<textarea id="remoteSessionDescription"></textarea> <br/>
<button onclick="window.startSession()"> Start Session </button><br />

<br />

Video<br />
<div id="remoteVideos"></div> <br />

Logs<br />
<div id="div"></div>
46 changes: 46 additions & 0 deletions examples/echo/jsfiddle/demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* eslint-env browser */

let pc = new RTCPeerConnection({
iceServers: [
{
urls: 'stun:stun.l.google.com:19302'
}
]
})
var log = msg => {
document.getElementById('logs').innerHTML += msg + '<br>'
}

navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(stream => {
pc.addStream(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) {
document.getElementById('localSessionDescription').value = btoa(JSON.stringify(pc.localDescription))
}
}
pc.ontrack = function (event) {
var el = document.createElement(event.track.kind)
el.srcObject = event.streams[0]
el.autoplay = true
el.controls = true

document.getElementById('remoteVideos').appendChild(el)
}

window.startSession = () => {
let sd = document.getElementById('remoteSessionDescription').value
if (sd === '') {
return alert('Session Description must not be empty')
}

try {
pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(sd))))
} catch (e) {
alert(e)
}
}
109 changes: 109 additions & 0 deletions examples/echo/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package main

import (
"fmt"
"math/rand"
"time"

"github.com/pion/rtcp"
"github.com/pion/webrtc/v2"

"github.com/pion/webrtc/v2/examples/internal/signal"
)

func main() {
// Everything below is the pion-WebRTC API! Thanks for using it ❤️.

// Prepare the configuration
config := webrtc.Configuration{
ICEServers: []webrtc.ICEServer{
{
URLs: []string{"stun:stun.l.google.com:19302"},
},
},
}

// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewPeerConnection(config)
if err != nil {
panic(err)
}

// Create Track that we send video back to browser on
outputTrack, err := peerConnection.NewTrack(webrtc.DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion")
if err != nil {
panic(err)
}

// Add this newly created track to the PeerConnection
if _, err = peerConnection.AddTrack(outputTrack); err != nil {
panic(err)
}

// Set a handler for when a new remote track starts, this handler copies inbound RTP packets,
// replaces the SSRC and sends them back
peerConnection.OnTrack(func(track *webrtc.Track, receiver *webrtc.RTPReceiver) {
// Send a PLI on an interval so that the publisher is pushing a keyframe every rtcpPLIInterval
// This is a temporary fix until we implement incoming RTCP events, then we would push a PLI only when a viewer requests it
go func() {
ticker := time.NewTicker(time.Second * 3)
for range ticker.C {
errSend := peerConnection.WriteRTCP([]rtcp.Packet{&rtcp.PictureLossIndication{MediaSSRC: track.SSRC()}})
if errSend != nil {
fmt.Println(errSend)
}
}
}()

fmt.Printf("Track has started, of type %d: %s \n", track.PayloadType(), track.Codec().Name)
for {
// Read RTP packets being sent to Pion
rtp, readErr := track.ReadRTP()
if readErr != nil {
panic(readErr)
}

// Replace the SSRC with the SSRC of the outbound track.
// The only change we are making replacing the SSRC, the RTP packets are unchanged otherwise
rtp.SSRC = outputTrack.SSRC()
rtp.PayloadType = webrtc.DefaultPayloadTypeVP8

if writeErr := outputTrack.WriteRTP(rtp); writeErr != nil {
panic(writeErr)
}
}
})
// Set the handler for ICE connection state
// This will notify you when the peer has connected/disconnected
peerConnection.OnICEConnectionStateChange(func(connectionState webrtc.ICEConnectionState) {
fmt.Printf("Connection State has changed %s \n", connectionState.String())
})

// Wait for the offer to be pasted
offer := webrtc.SessionDescription{}
signal.Decode(signal.MustReadStdin(), &offer)

// Set the remote SessionDescription
err = peerConnection.SetRemoteDescription(offer)
if err != nil {
panic(err)
}

// Create an answer
answer, err := peerConnection.CreateAnswer(nil)
if err != nil {
panic(err)
}

// Sets the LocalDescription, and starts our UDP listeners
err = peerConnection.SetLocalDescription(answer)
if err != nil {
panic(err)
}

// Output the answer in base64 so we can paste it in browser
fmt.Println(signal.Encode(answer))

// Block forever
select {}
}
6 changes: 6 additions & 0 deletions examples/examples.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
"description": "The data-channels-detach is an example that shows how you can detach a data channel.",
"type": "browser"
},
{
"title": "Echo",
"link": "echo",
"description": "The echo example demonstrates how to have Pion send back to the user exactly what it receives using the same PeerConnection.",
"type": "browser"
},
{
"title": "Pion to Pion",
"link": "#",
Expand Down

0 comments on commit 77cacbb

Please sign in to comment.