-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathconn_media.go
140 lines (111 loc) · 3.27 KB
/
conn_media.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package peer
import (
"fmt"
"github.com/muka/peerjs-go/enums"
"github.com/muka/peerjs-go/models"
"github.com/muka/peerjs-go/util"
"github.com/pion/webrtc/v3"
)
//MediaChannelIDPrefix the media channel connection id prefix
const MediaChannelIDPrefix = "mc_"
//NewMediaConnection create new MediaConnection
func NewMediaConnection(id string, peer *Peer, opts ConnectionOptions) (*MediaConnection, error) {
m := &MediaConnection{
BaseConnection: newBaseConnection(enums.ConnectionTypeMedia, peer, opts),
}
m.peerID = id
m.id = opts.ConnectionID
if m.id == "" {
m.id = fmt.Sprintf("%s%s", MediaChannelIDPrefix, util.RandomToken())
}
m.localStream = opts.Stream
m.negotiator = NewNegotiator(m, opts)
var err error
if m.localStream != nil {
opts.Originator = true
err = m.negotiator.StartConnection(opts)
}
return m, err
}
// MediaConnection track a connection with a remote Peer
type MediaConnection struct {
BaseConnection
Open bool
remoteStream *MediaStream
localStream *MediaStream
}
// GetLocalStream returns the local stream
func (m *MediaConnection) GetLocalStream() *MediaStream {
return m.localStream
}
// GetRemoteStream returns the remote stream
func (m *MediaConnection) GetRemoteStream() *MediaStream {
return m.remoteStream
}
// AddStream adds a stream to the MediaConnection
func (m *MediaConnection) AddStream(tr *webrtc.TrackRemote) {
m.log.Debugf("Receiving stream: %v", tr)
m.remoteStream = NewMediaStreamWithTrack([]MediaStreamTrack{tr})
m.Emit(enums.ConnectionEventTypeStream, tr)
}
func (m *MediaConnection) HandleMessage(message *models.Message) error {
mtype := message.GetType()
payload := message.GetPayload()
switch message.GetType() {
case enums.ServerMessageTypeAnswer:
// Forward to negotiator
m.negotiator.handleSDP(message.GetType(), *payload.SDP)
m.Open = true
break
case enums.ServerMessageTypeCandidate:
m.negotiator.HandleCandidate(payload.Candidate)
break
default:
m.log.Warnf("Unrecognized message type:%s from peer:%s", mtype, m.peerID)
break
}
return nil
}
//Answer open the media connection with the remote peer
func (m *MediaConnection) Answer(tl webrtc.TrackLocal, options *AnswerOption) {
if m.localStream != nil {
m.log.Warn("Local stream already exists on this MediaConnection. Are you answering a call twice?")
return
}
stream := NewMediaStreamWithTrack([]MediaStreamTrack{tl})
m.localStream = stream
if options != nil && options.SDPTransform != nil {
m.BaseConnection.opts.SDPTransform = options.SDPTransform
}
connOpts := m.GetOptions()
connOpts.Stream = stream
m.negotiator.StartConnection(connOpts)
// Retrieve lost messages stored because PeerConnection not set up.
messages := m.GetProvider().GetMessages(m.GetID())
for _, message := range messages {
m.HandleMessage(&message)
}
m.Open = true
}
//Close allows user to close connection
func (m *MediaConnection) Close() error {
if m.negotiator != nil {
m.negotiator.Cleanup()
m.negotiator = nil
}
m.localStream = nil
m.remoteStream = nil
if m.GetProvider() != nil {
m.GetProvider().RemoveConnection(m)
m.BaseConnection.Provider = nil
}
if m.BaseConnection.opts.Stream != nil {
m.BaseConnection.opts.Stream = nil
}
if !m.Open {
return nil
}
m.Open = false
m.Emit(enums.ConnectionEventTypeClose, nil)
return nil
}