fix: refactor signaler; fix logic for local watcher
This commit is contained in:
+100
-79
@@ -27,14 +27,41 @@ const (
|
||||
h264FrameDuration = time.Millisecond * 33
|
||||
)
|
||||
|
||||
func withAuth[T any](token string, v *T) *connect.Request[T] {
|
||||
req := connect.NewRequest[T](v)
|
||||
req.Header().Add("authorization", "Bearer "+token)
|
||||
return req
|
||||
}
|
||||
|
||||
func main() { //nolint
|
||||
ctx := context.Background()
|
||||
client := servicepb.NewSignalerServiceClient(&http.Client{}, "http://localhost:8080/")
|
||||
httpClient := &http.Client{}
|
||||
client := servicepb.NewSignalerServiceClient(httpClient, "http://localhost:8080/")
|
||||
authToken, err := client.CreateAuthToken(ctx, connect.NewRequest(&pb.CreateAuthTokenRequest{
|
||||
Type: &pb.CreateAuthTokenRequest_Camera_{
|
||||
Camera: &pb.CreateAuthTokenRequest_Camera{
|
||||
Id: "movie",
|
||||
},
|
||||
},
|
||||
}))
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to get auth token: %v", err)
|
||||
}
|
||||
token := authToken.Msg.GetToken()
|
||||
|
||||
// Assert that we have an audio or video file
|
||||
_, err := os.Stat(videoFileName)
|
||||
_, err = os.Stat(videoFileName)
|
||||
haveVideoFile := !os.IsNotExist(err)
|
||||
|
||||
iceConnectedCtx, iceConnectedCtxCancel := context.WithCancel(context.Background())
|
||||
|
||||
// Create a new RTCPeerConnection
|
||||
|
||||
// Wait for a session request
|
||||
session, err := client.PopSession(ctx, withAuth(token, &pb.PopSessionRequest{}))
|
||||
if err != nil {
|
||||
log.Fatalf("error creating session: %v", err)
|
||||
}
|
||||
peerConnection, err := webrtc.NewPeerConnection(webrtc.Configuration{
|
||||
ICEServers: []webrtc.ICEServer{
|
||||
{
|
||||
@@ -51,8 +78,6 @@ func main() { //nolint
|
||||
}
|
||||
}()
|
||||
|
||||
iceConnectedCtx, iceConnectedCtxCancel := context.WithCancel(context.Background())
|
||||
|
||||
if haveVideoFile {
|
||||
// Create a video track
|
||||
videoTrack, videoTrackErr := webrtc.NewTrackLocalStaticSample(webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeH264}, "video", "pion")
|
||||
@@ -139,90 +164,86 @@ func main() { //nolint
|
||||
}
|
||||
})
|
||||
|
||||
var iceCandidates []*pb.IceCandidate
|
||||
peerConnection.OnICECandidate(func(i *webrtc.ICECandidate) {
|
||||
if i == nil {
|
||||
return
|
||||
}
|
||||
c := i.ToJSON()
|
||||
iceCandidates = append(iceCandidates, &pb.IceCandidate{
|
||||
Candidate: c.Candidate,
|
||||
SdpMid: c.SDPMid,
|
||||
SdpLineIndex: proto.Int32(int32(*c.SDPMLineIndex)),
|
||||
UsernameFragment: proto.String(*c.UsernameFragment),
|
||||
})
|
||||
client.CreateIceMessage(ctx, withAuth(token, &pb.CreateIceMessageRequest{
|
||||
SessionIdentifier: session.Msg.GetId(),
|
||||
IceMessage: &pb.IceMessage{
|
||||
Type: &pb.IceMessage_Candidate{
|
||||
Candidate: &pb.IceCandidate{
|
||||
Candidate: c.Candidate,
|
||||
SdpMid: c.SDPMid,
|
||||
SdpLineIndex: proto.Int32(int32(*c.SDPMLineIndex)),
|
||||
UsernameFragment: proto.String(*c.UsernameFragment),
|
||||
},
|
||||
},
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
||||
// Wait for a session request
|
||||
var session *pb.Session
|
||||
for session == nil {
|
||||
resp, err := client.ListSessions(ctx, connect.NewRequest(&pb.ListSessionsRequest{}))
|
||||
if err != nil {
|
||||
log.Fatalf("error creating session: %v", err)
|
||||
}
|
||||
if len(resp.Msg.Sessions) > 0 {
|
||||
session = resp.Msg.Sessions[0]
|
||||
}
|
||||
time.Sleep(time.Millisecond * 500)
|
||||
}
|
||||
|
||||
// Add ICE candidates from remote
|
||||
for _, candidate := range session.GetClientIceCandidates() {
|
||||
var sdpMLine *uint16
|
||||
if candidate.SdpLineIndex != nil {
|
||||
t := uint16(candidate.GetSdpLineIndex())
|
||||
sdpMLine = &t
|
||||
go func() {
|
||||
for {
|
||||
msg, err := client.PopIceMessage(ctx, withAuth(token, &pb.PopIceMessageRequest{
|
||||
SessionIdentifier: session.Msg.GetId(),
|
||||
}))
|
||||
if err != nil {
|
||||
log.Fatalf("failed to pop ice message: %v", err)
|
||||
}
|
||||
switch msg.Msg.Type.(type) {
|
||||
case *pb.IceMessage_Candidate:
|
||||
candidate := msg.Msg.GetCandidate()
|
||||
var sdpMLine *uint16
|
||||
if candidate.SdpLineIndex != nil {
|
||||
t := uint16(candidate.GetSdpLineIndex())
|
||||
sdpMLine = &t
|
||||
}
|
||||
if err := peerConnection.AddICECandidate(webrtc.ICECandidateInit{
|
||||
Candidate: candidate.GetCandidate(),
|
||||
SDPMid: candidate.SdpMid,
|
||||
SDPMLineIndex: sdpMLine,
|
||||
}); err != nil {
|
||||
log.Fatalf("Failed to add ice candidate: %v", err)
|
||||
}
|
||||
case *pb.IceMessage_Session:
|
||||
session := msg.Msg.GetSession()
|
||||
|
||||
offer := webrtc.SessionDescription{
|
||||
Type: webrtc.SDPType(session.SdpType),
|
||||
SDP: session.Sdp,
|
||||
}
|
||||
if err := peerConnection.SetLocalDescription(offer); err != nil {
|
||||
log.Fatalf("Failed to set location description: %v", err)
|
||||
}
|
||||
|
||||
// Send back an answer
|
||||
answer, err := peerConnection.CreateAnswer(nil)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create an answer: %v", err)
|
||||
}
|
||||
if err := peerConnection.SetRemoteDescription(answer); err != nil {
|
||||
log.Fatalf("Failed to set remote description: %v", err)
|
||||
}
|
||||
|
||||
_, err = client.CreateIceMessage(ctx, withAuth(token, &pb.CreateIceMessageRequest{
|
||||
IceMessage: &pb.IceMessage{
|
||||
Type: &pb.IceMessage_Session{
|
||||
Session: &pb.IceSessionDescription{
|
||||
SdpType: int64(answer.Type),
|
||||
Sdp: answer.SDP,
|
||||
},
|
||||
},
|
||||
},
|
||||
}))
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to send answer: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
peerConnection.AddICECandidate(webrtc.ICECandidateInit{
|
||||
Candidate: candidate.GetCandidate(),
|
||||
SDPMid: candidate.SdpMid,
|
||||
SDPMLineIndex: sdpMLine,
|
||||
})
|
||||
}
|
||||
|
||||
cameraOffer, err := peerConnection.CreateOffer(nil)
|
||||
if err != nil {
|
||||
log.Fatalf("error creating session: %v", err)
|
||||
}
|
||||
|
||||
// Set the remote SessionDescription
|
||||
if err = peerConnection.SetRemoteDescription(cameraOffer); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Create channel that is blocked until ICE Gathering is complete
|
||||
gatherComplete := webrtc.GatheringCompletePromise(peerConnection)
|
||||
// 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
|
||||
log.Printf("Waiting to gather ICE")
|
||||
<-gatherComplete
|
||||
log.Printf("Done gathering ICE")
|
||||
|
||||
session.CameraIceCandidates = iceCandidates
|
||||
session.CameraOffer = &pb.IceSessionDescription{
|
||||
SdpType: int64(cameraOffer.Type),
|
||||
Sdp: cameraOffer.SDP,
|
||||
}
|
||||
|
||||
// Send it back
|
||||
resp, err := client.UpdateSession(ctx, connect.NewRequest(&pb.UpdateSessionRequest{
|
||||
Session: session,
|
||||
WaitForUpdate: true,
|
||||
}))
|
||||
if err != nil {
|
||||
log.Fatalf("error creating session: %v", err)
|
||||
}
|
||||
|
||||
answer := webrtc.SessionDescription{
|
||||
Type: webrtc.SDPType(resp.Msg.ClientAnswer.SdpType),
|
||||
SDP: resp.Msg.ClientAnswer.Sdp,
|
||||
}
|
||||
|
||||
// Sets the LocalDescription, and starts our UDP listeners
|
||||
if err = peerConnection.SetLocalDescription(answer); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Block forever
|
||||
select {}
|
||||
|
||||
Reference in New Issue
Block a user