Skip to content

Instantly share code, notes, and snippets.

@testingbot
Created December 23, 2020 15:47
Show Gist options
  • Save testingbot/209178762864b6f61ee40673e7e3e732 to your computer and use it in GitHub Desktop.
Save testingbot/209178762864b6f61ee40673e7e3e732 to your computer and use it in GitHub Desktop.
pion
package net
import (
"context"
"fmt"
"io"
"bufio"
"log"
"os"
"time"
"strings"
"encoding/base64"
"encoding/json"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/pkg/media"
)
func SendWebRTC(h264 chan[]byte, offer webrtc.SessionDescription) {
peerConnection, err := webrtc.NewPeerConnection(webrtc.Configuration{
ICEServers: []webrtc.ICEServer{
{
URLs: []string{"stun:stun.l.google.com:19302"},
},
},
})
if err != nil {
panic(err)
}
// Create a video track
videoTrack, err := webrtc.NewTrackLocalStaticSample(webrtc.RTPCodecCapability{MimeType: "video/h264"}, "video", "pion")
if err != nil {
panic(err)
}
sender, err := peerConnection.AddTrack(videoTrack)
log.Printf("sender %s", sender)
if err != nil {
panic(err)
}
iceConnectedCtx, iceConnectedCtxCancel := context.WithCancel(context.Background())
go func() {
// Wait for connection established
<-iceConnectedCtx.Done()
log.Println("done")
for {
select {
case frame := <-h264:
log.Println("passing frame")
if ivfErr := videoTrack.WriteSample(media.Sample{Data: frame, Duration: time.Second}); ivfErr != nil {
panic(ivfErr)
}
}
}
}()
// 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())
if connectionState == webrtc.ICEConnectionStateConnected {
iceConnectedCtxCancel()
}
})
// Set the remote SessionDescription
if err = peerConnection.SetRemoteDescription(offer); err != nil {
panic(err)
}
// Create answer
answer, err := peerConnection.CreateAnswer(nil)
if err != nil {
panic(err)
}
// Create channel that is blocked until ICE Gathering is complete
gatherComplete := webrtc.GatheringCompletePromise(peerConnection)
// Sets the LocalDescription, and starts our UDP listeners
if err = peerConnection.SetLocalDescription(answer); err != nil {
panic(err)
}
// Block until ICE Gathering is complete, disabling trickle ICE
// we do this because we only can exchange one signaling message
// in a production application you should exchange ICE Candidates via OnICECandidate
<-gatherComplete
// Output the answer in base64 so we can paste it in browser
fmt.Println(Encode(*peerConnection.LocalDescription()))
}
// Encode encodes the input in base64
// It can optionally zip the input before encoding
func Encode(obj interface{}) string {
b, err := json.Marshal(obj)
if err != nil {
panic(err)
}
return base64.StdEncoding.EncodeToString(b)
}
func Decode(in string, obj interface{}) {
b, err := base64.StdEncoding.DecodeString(in)
if err != nil {
panic(err)
}
err = json.Unmarshal(b, obj)
if err != nil {
panic(err)
}
}
func MustReadStdin() string {
r := bufio.NewReader(os.Stdin)
var in string
for {
var err error
in, err = r.ReadString('\n')
if err != io.EOF {
if err != nil {
panic(err)
}
}
in = strings.TrimSpace(in)
if len(in) > 0 {
break
}
}
fmt.Println("")
return in
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment