Created
December 23, 2020 15:47
-
-
Save testingbot/209178762864b6f61ee40673e7e3e732 to your computer and use it in GitHub Desktop.
pion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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