mirror of
https://github.com/pion/webrtc.git
synced 2025-10-05 15:16:52 +08:00
Remove RTC prefix from all names
Let's pull off the bandaid! * Reduces studdering: webrtc.RTCTrack -> webrtc.Track * Makes it easier to find types by editor autocomplete * Makes code read more fluently (less repetition) Since we're breaking the API in 2.0, our only chance to do this is now. Relates to #408
This commit is contained in:
@@ -74,7 +74,7 @@ Check out the **[contributing wiki](https://github.com/pions/webrtc/wiki/Contrib
|
|||||||
* [Tobias Fridén](https://github.com/tobiasfriden) *SRTP authentication verification*
|
* [Tobias Fridén](https://github.com/tobiasfriden) *SRTP authentication verification*
|
||||||
* [Yutaka Takeda](https://github.com/enobufs) *Fix ICE connection timeout*
|
* [Yutaka Takeda](https://github.com/enobufs) *Fix ICE connection timeout*
|
||||||
* [Hugo Arregui](https://github.com/hugoArregui) *Fix connection timeout*
|
* [Hugo Arregui](https://github.com/hugoArregui) *Fix connection timeout*
|
||||||
* [Rob Deutsch](https://github.com/rob-deutsch) *RTCRtpReceiver graceful shutdown*
|
* [Rob Deutsch](https://github.com/rob-deutsch) *RTPReceiver graceful shutdown*
|
||||||
* [Jin Lei](https://github.com/jinleileiking) - *SFU example use http*
|
* [Jin Lei](https://github.com/jinleileiking) - *SFU example use http*
|
||||||
|
|
||||||
### License
|
### License
|
||||||
|
8
api.go
8
api.go
@@ -77,7 +77,7 @@ func SetConnectionTimeout(connectionTimeout, keepAlive time.Duration) {
|
|||||||
|
|
||||||
// RegisterCodec on the default API.
|
// RegisterCodec on the default API.
|
||||||
// See MediaEngine for details.
|
// See MediaEngine for details.
|
||||||
func RegisterCodec(codec *RTCRtpCodec) {
|
func RegisterCodec(codec *RTPCodec) {
|
||||||
defaultAPI.mediaEngine.RegisterCodec(codec)
|
defaultAPI.mediaEngine.RegisterCodec(codec)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,8 +89,8 @@ func RegisterDefaultCodecs() {
|
|||||||
|
|
||||||
// PeerConnection API
|
// PeerConnection API
|
||||||
|
|
||||||
// NewRTCPeerConnection using the default API.
|
// NewPeerConnection using the default API.
|
||||||
// See API.NewRTCPeerConnection for details.
|
// See API.NewRTCPeerConnection for details.
|
||||||
func NewRTCPeerConnection(configuration RTCConfiguration) (*RTCPeerConnection, error) {
|
func NewPeerConnection(configuration Configuration) (*PeerConnection, error) {
|
||||||
return defaultAPI.NewRTCPeerConnection(configuration)
|
return defaultAPI.NewPeerConnection(configuration)
|
||||||
}
|
}
|
||||||
|
18
errors.go
18
errors.go
@@ -35,24 +35,24 @@ var (
|
|||||||
ErrPrivateKeyType = errors.New("private key type not supported")
|
ErrPrivateKeyType = errors.New("private key type not supported")
|
||||||
|
|
||||||
// ErrModifyingPeerIdentity indicates that an attempt to modify
|
// ErrModifyingPeerIdentity indicates that an attempt to modify
|
||||||
// PeerIdentity was made after RTCPeerConnection has been initialized.
|
// PeerIdentity was made after PeerConnection has been initialized.
|
||||||
ErrModifyingPeerIdentity = errors.New("peerIdentity cannot be modified")
|
ErrModifyingPeerIdentity = errors.New("peerIdentity cannot be modified")
|
||||||
|
|
||||||
// ErrModifyingCertificates indicates that an attempt to modify
|
// ErrModifyingCertificates indicates that an attempt to modify
|
||||||
// Certificates was made after RTCPeerConnection has been initialized.
|
// Certificates was made after PeerConnection has been initialized.
|
||||||
ErrModifyingCertificates = errors.New("certificates cannot be modified")
|
ErrModifyingCertificates = errors.New("certificates cannot be modified")
|
||||||
|
|
||||||
// ErrModifyingBundlePolicy indicates that an attempt to modify
|
// ErrModifyingBundlePolicy indicates that an attempt to modify
|
||||||
// BundlePolicy was made after RTCPeerConnection has been initialized.
|
// BundlePolicy was made after PeerConnection has been initialized.
|
||||||
ErrModifyingBundlePolicy = errors.New("bundle policy cannot be modified")
|
ErrModifyingBundlePolicy = errors.New("bundle policy cannot be modified")
|
||||||
|
|
||||||
// ErrModifyingRtcpMuxPolicy indicates that an attempt to modify
|
// ErrModifyingRTCPMuxPolicy indicates that an attempt to modify
|
||||||
// RtcpMuxPolicy was made after RTCPeerConnection has been initialized.
|
// RTCPMuxPolicy was made after PeerConnection has been initialized.
|
||||||
ErrModifyingRtcpMuxPolicy = errors.New("rtcp mux policy cannot be modified")
|
ErrModifyingRTCPMuxPolicy = errors.New("rtcp mux policy cannot be modified")
|
||||||
|
|
||||||
// ErrModifyingIceCandidatePoolSize indicates that an attempt to modify
|
// ErrModifyingICECandidatePoolSize indicates that an attempt to modify
|
||||||
// IceCandidatePoolSize was made after RTCPeerConnection has been initialized.
|
// ICECandidatePoolSize was made after PeerConnection has been initialized.
|
||||||
ErrModifyingIceCandidatePoolSize = errors.New("ice candidate pool size cannot be modified")
|
ErrModifyingICECandidatePoolSize = errors.New("ice candidate pool size cannot be modified")
|
||||||
|
|
||||||
// ErrStringSizeLimit indicates that the character size limit of string is
|
// ErrStringSizeLimit indicates that the character size limit of string is
|
||||||
// exceeded. The limit is hardcoded to 65535 according to specifications.
|
// exceeded. The limit is hardcoded to 65535 according to specifications.
|
||||||
|
@@ -18,8 +18,8 @@ func main() {
|
|||||||
// Everything below is the pion-WebRTC API! Thanks for using it ❤️.
|
// Everything below is the pion-WebRTC API! Thanks for using it ❤️.
|
||||||
|
|
||||||
// Prepare the configuration
|
// Prepare the configuration
|
||||||
config := webrtc.RTCConfiguration{
|
config := webrtc.Configuration{
|
||||||
IceServers: []webrtc.RTCIceServer{
|
ICEServers: []webrtc.ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{"stun:stun.l.google.com:19302"},
|
URLs: []string{"stun:stun.l.google.com:19302"},
|
||||||
},
|
},
|
||||||
@@ -27,7 +27,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new RTCPeerConnection
|
// Create a new RTCPeerConnection
|
||||||
peerConnection, err := webrtc.NewRTCPeerConnection(config)
|
peerConnection, err := webrtc.NewPeerConnection(config)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Set the handler for ICE connection state
|
// Set the handler for ICE connection state
|
||||||
@@ -37,7 +37,7 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Register data channel creation handling
|
// Register data channel creation handling
|
||||||
peerConnection.OnDataChannel(func(d *webrtc.RTCDataChannel) {
|
peerConnection.OnDataChannel(func(d *webrtc.DataChannel) {
|
||||||
fmt.Printf("New DataChannel %s %d\n", d.Label, d.ID)
|
fmt.Printf("New DataChannel %s %d\n", d.Label, d.ID)
|
||||||
|
|
||||||
// Register channel opening handling
|
// Register channel opening handling
|
||||||
@@ -83,7 +83,7 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Wait for the offer to be pasted
|
// Wait for the offer to be pasted
|
||||||
offer := webrtc.RTCSessionDescription{}
|
offer := webrtc.SessionDescription{}
|
||||||
util.Decode(util.MustReadStdin(), &offer)
|
util.Decode(util.MustReadStdin(), &offer)
|
||||||
|
|
||||||
// Set the remote SessionDescription
|
// Set the remote SessionDescription
|
||||||
|
@@ -14,8 +14,8 @@ func main() {
|
|||||||
// Everything below is the pion-WebRTC API! Thanks for using it ❤️.
|
// Everything below is the pion-WebRTC API! Thanks for using it ❤️.
|
||||||
|
|
||||||
// Prepare the configuration
|
// Prepare the configuration
|
||||||
config := webrtc.RTCConfiguration{
|
config := webrtc.Configuration{
|
||||||
IceServers: []webrtc.RTCIceServer{
|
ICEServers: []webrtc.ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{"stun:stun.l.google.com:19302"},
|
URLs: []string{"stun:stun.l.google.com:19302"},
|
||||||
},
|
},
|
||||||
@@ -23,7 +23,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new RTCPeerConnection
|
// Create a new RTCPeerConnection
|
||||||
peerConnection, err := webrtc.NewRTCPeerConnection(config)
|
peerConnection, err := webrtc.NewPeerConnection(config)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Create a datachannel with label 'data'
|
// Create a datachannel with label 'data'
|
||||||
@@ -73,7 +73,7 @@ func main() {
|
|||||||
fmt.Println(util.Encode(offer))
|
fmt.Println(util.Encode(offer))
|
||||||
|
|
||||||
// Wait for the answer to be pasted
|
// Wait for the answer to be pasted
|
||||||
answer := webrtc.RTCSessionDescription{}
|
answer := webrtc.SessionDescription{}
|
||||||
util.Decode(util.MustReadStdin(), &answer)
|
util.Decode(util.MustReadStdin(), &answer)
|
||||||
|
|
||||||
// Apply the answer as the remote description
|
// Apply the answer as the remote description
|
||||||
|
@@ -21,8 +21,8 @@ func main() {
|
|||||||
// Everything below is the pion-WebRTC API! Thanks for using it ❤️.
|
// Everything below is the pion-WebRTC API! Thanks for using it ❤️.
|
||||||
|
|
||||||
// Prepare the configuration
|
// Prepare the configuration
|
||||||
config := webrtc.RTCConfiguration{
|
config := webrtc.Configuration{
|
||||||
IceServers: []webrtc.RTCIceServer{
|
ICEServers: []webrtc.ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{"stun:stun.l.google.com:19302"},
|
URLs: []string{"stun:stun.l.google.com:19302"},
|
||||||
},
|
},
|
||||||
@@ -30,7 +30,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new RTCPeerConnection
|
// Create a new RTCPeerConnection
|
||||||
peerConnection, err := webrtc.NewRTCPeerConnection(config)
|
peerConnection, err := webrtc.NewPeerConnection(config)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Create a datachannel with label 'data'
|
// Create a datachannel with label 'data'
|
||||||
@@ -70,7 +70,7 @@ func main() {
|
|||||||
fmt.Println(util.Encode(offer))
|
fmt.Println(util.Encode(offer))
|
||||||
|
|
||||||
// Wait for the answer to be pasted
|
// Wait for the answer to be pasted
|
||||||
answer := webrtc.RTCSessionDescription{}
|
answer := webrtc.SessionDescription{}
|
||||||
util.Decode(util.MustReadStdin(), answer)
|
util.Decode(util.MustReadStdin(), answer)
|
||||||
|
|
||||||
// Apply the answer as the remote description
|
// Apply the answer as the remote description
|
||||||
|
@@ -21,8 +21,8 @@ func main() {
|
|||||||
// Everything below is the pion-WebRTC API! Thanks for using it ❤️.
|
// Everything below is the pion-WebRTC API! Thanks for using it ❤️.
|
||||||
|
|
||||||
// Prepare the configuration
|
// Prepare the configuration
|
||||||
config := webrtc.RTCConfiguration{
|
config := webrtc.Configuration{
|
||||||
IceServers: []webrtc.RTCIceServer{
|
ICEServers: []webrtc.ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{"stun:stun.l.google.com:19302"},
|
URLs: []string{"stun:stun.l.google.com:19302"},
|
||||||
},
|
},
|
||||||
@@ -30,7 +30,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new RTCPeerConnection
|
// Create a new RTCPeerConnection
|
||||||
peerConnection, err := webrtc.NewRTCPeerConnection(config)
|
peerConnection, err := webrtc.NewPeerConnection(config)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Set the handler for ICE connection state
|
// Set the handler for ICE connection state
|
||||||
@@ -40,7 +40,7 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Register data channel creation handling
|
// Register data channel creation handling
|
||||||
peerConnection.OnDataChannel(func(d *webrtc.RTCDataChannel) {
|
peerConnection.OnDataChannel(func(d *webrtc.DataChannel) {
|
||||||
fmt.Printf("New DataChannel %s %d\n", d.Label, d.ID)
|
fmt.Printf("New DataChannel %s %d\n", d.Label, d.ID)
|
||||||
|
|
||||||
// Register channel opening handling
|
// Register channel opening handling
|
||||||
@@ -60,7 +60,7 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Wait for the offer to be pasted
|
// Wait for the offer to be pasted
|
||||||
offer := webrtc.RTCSessionDescription{}
|
offer := webrtc.SessionDescription{}
|
||||||
util.Decode(util.MustReadStdin(), offer)
|
util.Decode(util.MustReadStdin(), offer)
|
||||||
|
|
||||||
// Set the remote SessionDescription
|
// Set the remote SessionDescription
|
||||||
|
@@ -14,8 +14,8 @@ func main() {
|
|||||||
// Everything below is the pion-WebRTC API! Thanks for using it ❤️.
|
// Everything below is the pion-WebRTC API! Thanks for using it ❤️.
|
||||||
|
|
||||||
// Prepare the configuration
|
// Prepare the configuration
|
||||||
config := webrtc.RTCConfiguration{
|
config := webrtc.Configuration{
|
||||||
IceServers: []webrtc.RTCIceServer{
|
ICEServers: []webrtc.ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{"stun:stun.l.google.com:19302"},
|
URLs: []string{"stun:stun.l.google.com:19302"},
|
||||||
},
|
},
|
||||||
@@ -23,7 +23,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new RTCPeerConnection
|
// Create a new RTCPeerConnection
|
||||||
peerConnection, err := webrtc.NewRTCPeerConnection(config)
|
peerConnection, err := webrtc.NewPeerConnection(config)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Set the handler for ICE connection state
|
// Set the handler for ICE connection state
|
||||||
@@ -33,7 +33,7 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Register data channel creation handling
|
// Register data channel creation handling
|
||||||
peerConnection.OnDataChannel(func(d *webrtc.RTCDataChannel) {
|
peerConnection.OnDataChannel(func(d *webrtc.DataChannel) {
|
||||||
fmt.Printf("New DataChannel %s %d\n", d.Label, d.ID)
|
fmt.Printf("New DataChannel %s %d\n", d.Label, d.ID)
|
||||||
|
|
||||||
// Register channel opening handling
|
// Register channel opening handling
|
||||||
@@ -63,7 +63,7 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Wait for the offer to be pasted
|
// Wait for the offer to be pasted
|
||||||
offer := webrtc.RTCSessionDescription{}
|
offer := webrtc.SessionDescription{}
|
||||||
util.Decode(util.MustReadStdin(), &offer)
|
util.Decode(util.MustReadStdin(), &offer)
|
||||||
|
|
||||||
// Set the remote SessionDescription
|
// Set the remote SessionDescription
|
||||||
|
@@ -22,8 +22,8 @@ func gstreamerReceiveMain() {
|
|||||||
webrtc.RegisterDefaultCodecs()
|
webrtc.RegisterDefaultCodecs()
|
||||||
|
|
||||||
// Prepare the configuration
|
// Prepare the configuration
|
||||||
config := webrtc.RTCConfiguration{
|
config := webrtc.Configuration{
|
||||||
IceServers: []webrtc.RTCIceServer{
|
ICEServers: []webrtc.ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{"stun:stun.l.google.com:19302"},
|
URLs: []string{"stun:stun.l.google.com:19302"},
|
||||||
},
|
},
|
||||||
@@ -31,12 +31,12 @@ func gstreamerReceiveMain() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new RTCPeerConnection
|
// Create a new RTCPeerConnection
|
||||||
peerConnection, err := webrtc.NewRTCPeerConnection(config)
|
peerConnection, err := webrtc.NewPeerConnection(config)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Set a handler for when a new remote track starts, this handler creates a gstreamer pipeline
|
// Set a handler for when a new remote track starts, this handler creates a gstreamer pipeline
|
||||||
// for the given codec
|
// for the given codec
|
||||||
peerConnection.OnTrack(func(track *webrtc.RTCTrack) {
|
peerConnection.OnTrack(func(track *webrtc.Track) {
|
||||||
// Send a PLI on an interval so that the publisher is pushing a keyframe every rtcpPLIInterval
|
// 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
|
// 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() {
|
go func() {
|
||||||
@@ -66,7 +66,7 @@ func gstreamerReceiveMain() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Wait for the offer to be pasted
|
// Wait for the offer to be pasted
|
||||||
offer := webrtc.RTCSessionDescription{}
|
offer := webrtc.SessionDescription{}
|
||||||
util.Decode(util.MustReadStdin(), &offer)
|
util.Decode(util.MustReadStdin(), &offer)
|
||||||
|
|
||||||
// Set the remote SessionDescription
|
// Set the remote SessionDescription
|
||||||
|
@@ -17,8 +17,8 @@ func main() {
|
|||||||
webrtc.RegisterDefaultCodecs()
|
webrtc.RegisterDefaultCodecs()
|
||||||
|
|
||||||
// Prepare the configuration
|
// Prepare the configuration
|
||||||
config := webrtc.RTCConfiguration{
|
config := webrtc.Configuration{
|
||||||
IceServers: []webrtc.RTCIceServer{
|
ICEServers: []webrtc.ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{"stun:stun.l.google.com:19302"},
|
URLs: []string{"stun:stun.l.google.com:19302"},
|
||||||
},
|
},
|
||||||
@@ -26,7 +26,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new RTCPeerConnection
|
// Create a new RTCPeerConnection
|
||||||
peerConnection, err := webrtc.NewRTCPeerConnection(config)
|
peerConnection, err := webrtc.NewPeerConnection(config)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Set the handler for ICE connection state
|
// Set the handler for ICE connection state
|
||||||
@@ -36,13 +36,13 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Create a audio track
|
// Create a audio track
|
||||||
opusTrack, err := peerConnection.NewRTCSampleTrack(webrtc.DefaultPayloadTypeOpus, "audio", "pion1")
|
opusTrack, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeOpus, "audio", "pion1")
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
_, err = peerConnection.AddTrack(opusTrack)
|
_, err = peerConnection.AddTrack(opusTrack)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Create a video track
|
// Create a video track
|
||||||
vp8Track, err := peerConnection.NewRTCSampleTrack(webrtc.DefaultPayloadTypeVP8, "video", "pion2")
|
vp8Track, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeVP8, "video", "pion2")
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
_, err = peerConnection.AddTrack(vp8Track)
|
_, err = peerConnection.AddTrack(vp8Track)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
@@ -59,7 +59,7 @@ func main() {
|
|||||||
fmt.Println(util.Encode(offer))
|
fmt.Println(util.Encode(offer))
|
||||||
|
|
||||||
// Wait for the answer to be pasted
|
// Wait for the answer to be pasted
|
||||||
answer := webrtc.RTCSessionDescription{}
|
answer := webrtc.SessionDescription{}
|
||||||
util.Decode(util.MustReadStdin(), &answer)
|
util.Decode(util.MustReadStdin(), &answer)
|
||||||
|
|
||||||
// Set the remote SessionDescription
|
// Set the remote SessionDescription
|
||||||
|
@@ -22,8 +22,8 @@ func main() {
|
|||||||
webrtc.RegisterDefaultCodecs()
|
webrtc.RegisterDefaultCodecs()
|
||||||
|
|
||||||
// Prepare the configuration
|
// Prepare the configuration
|
||||||
config := webrtc.RTCConfiguration{
|
config := webrtc.Configuration{
|
||||||
IceServers: []webrtc.RTCIceServer{
|
ICEServers: []webrtc.ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{"stun:stun.l.google.com:19302"},
|
URLs: []string{"stun:stun.l.google.com:19302"},
|
||||||
},
|
},
|
||||||
@@ -31,7 +31,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new RTCPeerConnection
|
// Create a new RTCPeerConnection
|
||||||
peerConnection, err := webrtc.NewRTCPeerConnection(config)
|
peerConnection, err := webrtc.NewPeerConnection(config)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Set the handler for ICE connection state
|
// Set the handler for ICE connection state
|
||||||
@@ -41,19 +41,19 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Create a audio track
|
// Create a audio track
|
||||||
opusTrack, err := peerConnection.NewRTCSampleTrack(webrtc.DefaultPayloadTypeOpus, "audio", "pion1")
|
opusTrack, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeOpus, "audio", "pion1")
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
_, err = peerConnection.AddTrack(opusTrack)
|
_, err = peerConnection.AddTrack(opusTrack)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Create a video track
|
// Create a video track
|
||||||
vp8Track, err := peerConnection.NewRTCSampleTrack(webrtc.DefaultPayloadTypeVP8, "video", "pion2")
|
vp8Track, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeVP8, "video", "pion2")
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
_, err = peerConnection.AddTrack(vp8Track)
|
_, err = peerConnection.AddTrack(vp8Track)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Wait for the offer to be pasted
|
// Wait for the offer to be pasted
|
||||||
offer := webrtc.RTCSessionDescription{}
|
offer := webrtc.SessionDescription{}
|
||||||
util.Decode(util.MustReadStdin(), &offer)
|
util.Decode(util.MustReadStdin(), &offer)
|
||||||
|
|
||||||
// Set the remote SessionDescription
|
// Set the remote SessionDescription
|
||||||
|
@@ -40,8 +40,8 @@ func main() {
|
|||||||
webrtc.RegisterDefaultCodecs()
|
webrtc.RegisterDefaultCodecs()
|
||||||
|
|
||||||
// Prepare the configuration
|
// Prepare the configuration
|
||||||
config := webrtc.RTCConfiguration{
|
config := webrtc.Configuration{
|
||||||
IceServers: []webrtc.RTCIceServer{
|
ICEServers: []webrtc.ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{"stun:stun.l.google.com:19302"},
|
URLs: []string{"stun:stun.l.google.com:19302"},
|
||||||
},
|
},
|
||||||
@@ -49,14 +49,14 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new RTCPeerConnection
|
// Create a new RTCPeerConnection
|
||||||
peerConnection, err := webrtc.NewRTCPeerConnection(config)
|
peerConnection, err := webrtc.NewPeerConnection(config)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
peerConnection.OnICEConnectionStateChange(func(connectionState ice.ConnectionState) {
|
peerConnection.OnICEConnectionStateChange(func(connectionState ice.ConnectionState) {
|
||||||
fmt.Printf("Connection State has changed %s \n", connectionState.String())
|
fmt.Printf("Connection State has changed %s \n", connectionState.String())
|
||||||
})
|
})
|
||||||
|
|
||||||
peerConnection.OnTrack(func(track *webrtc.RTCTrack) {
|
peerConnection.OnTrack(func(track *webrtc.Track) {
|
||||||
if track.Codec.Name == webrtc.Opus {
|
if track.Codec.Name == webrtc.Opus {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -98,8 +98,8 @@ func main() {
|
|||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
if msg.Jsep != nil {
|
if msg.Jsep != nil {
|
||||||
err = peerConnection.SetRemoteDescription(webrtc.RTCSessionDescription{
|
err = peerConnection.SetRemoteDescription(webrtc.SessionDescription{
|
||||||
Type: webrtc.RTCSdpTypeOffer,
|
Type: webrtc.SDPTypeOffer,
|
||||||
Sdp: msg.Jsep["sdp"].(string),
|
Sdp: msg.Jsep["sdp"].(string),
|
||||||
})
|
})
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
@@ -40,8 +40,8 @@ func main() {
|
|||||||
webrtc.RegisterDefaultCodecs()
|
webrtc.RegisterDefaultCodecs()
|
||||||
|
|
||||||
// Prepare the configuration
|
// Prepare the configuration
|
||||||
config := webrtc.RTCConfiguration{
|
config := webrtc.Configuration{
|
||||||
IceServers: []webrtc.RTCIceServer{
|
ICEServers: []webrtc.ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{"stun:stun.l.google.com:19302"},
|
URLs: []string{"stun:stun.l.google.com:19302"},
|
||||||
},
|
},
|
||||||
@@ -49,7 +49,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new RTCPeerConnection
|
// Create a new RTCPeerConnection
|
||||||
peerConnection, err := webrtc.NewRTCPeerConnection(config)
|
peerConnection, err := webrtc.NewPeerConnection(config)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
peerConnection.OnICEConnectionStateChange(func(connectionState ice.ConnectionState) {
|
peerConnection.OnICEConnectionStateChange(func(connectionState ice.ConnectionState) {
|
||||||
@@ -57,13 +57,13 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Create a audio track
|
// Create a audio track
|
||||||
opusTrack, err := peerConnection.NewRTCSampleTrack(webrtc.DefaultPayloadTypeOpus, "audio", "pion1")
|
opusTrack, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeOpus, "audio", "pion1")
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
_, err = peerConnection.AddTrack(opusTrack)
|
_, err = peerConnection.AddTrack(opusTrack)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Create a video track
|
// Create a video track
|
||||||
vp8Track, err := peerConnection.NewRTCSampleTrack(webrtc.DefaultPayloadTypeVP8, "video", "pion2")
|
vp8Track, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeVP8, "video", "pion2")
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
_, err = peerConnection.AddTrack(vp8Track)
|
_, err = peerConnection.AddTrack(vp8Track)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
@@ -106,8 +106,8 @@ func main() {
|
|||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
if msg.Jsep != nil {
|
if msg.Jsep != nil {
|
||||||
err = peerConnection.SetRemoteDescription(webrtc.RTCSessionDescription{
|
err = peerConnection.SetRemoteDescription(webrtc.SessionDescription{
|
||||||
Type: webrtc.RTCSdpTypeAnswer,
|
Type: webrtc.SDPTypeAnswer,
|
||||||
Sdp: msg.Jsep["sdp"].(string),
|
Sdp: msg.Jsep["sdp"].(string),
|
||||||
})
|
})
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
@@ -25,21 +25,21 @@ func main() {
|
|||||||
api := webrtc.NewAPI()
|
api := webrtc.NewAPI()
|
||||||
|
|
||||||
// Prepare ICE gathering options
|
// Prepare ICE gathering options
|
||||||
iceOptions := webrtc.RTCIceGatherOptions{
|
iceOptions := webrtc.ICEGatherOptions{
|
||||||
ICEServers: []webrtc.RTCIceServer{
|
ICEServers: []webrtc.ICEServer{
|
||||||
{URLs: []string{"stun:stun.l.google.com:19302"}},
|
{URLs: []string{"stun:stun.l.google.com:19302"}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the ICE gatherer
|
// Create the ICE gatherer
|
||||||
gatherer, err := api.NewRTCIceGatherer(iceOptions)
|
gatherer, err := api.NewICEGatherer(iceOptions)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Construct the ICE transport
|
// Construct the ICE transport
|
||||||
ice := api.NewRTCIceTransport(gatherer)
|
ice := api.NewICETransport(gatherer)
|
||||||
|
|
||||||
// Construct the Quic transport
|
// Construct the Quic transport
|
||||||
qt, err := api.NewRTCQuicTransport(ice, nil)
|
qt, err := api.NewQUICTransport(ice, nil)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Handle incoming streams
|
// Handle incoming streams
|
||||||
@@ -76,9 +76,9 @@ func main() {
|
|||||||
remoteSignal := Signal{}
|
remoteSignal := Signal{}
|
||||||
util.Decode(util.MustReadStdin(), &remoteSignal)
|
util.Decode(util.MustReadStdin(), &remoteSignal)
|
||||||
|
|
||||||
iceRole := webrtc.RTCIceRoleControlled
|
iceRole := webrtc.ICERoleControlled
|
||||||
if *isOffer {
|
if *isOffer {
|
||||||
iceRole = webrtc.RTCIceRoleControlling
|
iceRole = webrtc.ICERoleControlling
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ice.SetRemoteCandidates(remoteSignal.ICECandidates)
|
err = ice.SetRemoteCandidates(remoteSignal.ICECandidates)
|
||||||
@@ -112,9 +112,9 @@ func main() {
|
|||||||
// This is not part of the ORTC spec. You are free
|
// This is not part of the ORTC spec. You are free
|
||||||
// to exchange this information any way you want.
|
// to exchange this information any way you want.
|
||||||
type Signal struct {
|
type Signal struct {
|
||||||
ICECandidates []webrtc.RTCIceCandidate `json:"iceCandidates"`
|
ICECandidates []webrtc.ICECandidate `json:"iceCandidates"`
|
||||||
ICEParameters webrtc.RTCIceParameters `json:"iceParameters"`
|
ICEParameters webrtc.ICEParameters `json:"iceParameters"`
|
||||||
QuicParameters webrtc.RTCQuicParameters `json:"quicParameters"`
|
QuicParameters webrtc.QUICParameters `json:"quicParameters"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadLoop reads from the stream
|
// ReadLoop reads from the stream
|
||||||
|
@@ -17,8 +17,8 @@ func main() {
|
|||||||
// Everything below is the pion-WebRTC (ORTC) API! Thanks for using it ❤️.
|
// Everything below is the pion-WebRTC (ORTC) API! Thanks for using it ❤️.
|
||||||
|
|
||||||
// Prepare ICE gathering options
|
// Prepare ICE gathering options
|
||||||
iceOptions := webrtc.RTCIceGatherOptions{
|
iceOptions := webrtc.ICEGatherOptions{
|
||||||
ICEServers: []webrtc.RTCIceServer{
|
ICEServers: []webrtc.ICEServer{
|
||||||
{URLs: []string{"stun:stun.l.google.com:19302"}},
|
{URLs: []string{"stun:stun.l.google.com:19302"}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -27,21 +27,21 @@ func main() {
|
|||||||
api := webrtc.NewAPI()
|
api := webrtc.NewAPI()
|
||||||
|
|
||||||
// Create the ICE gatherer
|
// Create the ICE gatherer
|
||||||
gatherer, err := api.NewRTCIceGatherer(iceOptions)
|
gatherer, err := api.NewICEGatherer(iceOptions)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Construct the ICE transport
|
// Construct the ICE transport
|
||||||
ice := api.NewRTCIceTransport(gatherer)
|
ice := api.NewICETransport(gatherer)
|
||||||
|
|
||||||
// Construct the DTLS transport
|
// Construct the DTLS transport
|
||||||
dtls, err := api.NewRTCDtlsTransport(ice, nil)
|
dtls, err := api.NewDTLSTransport(ice, nil)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Construct the SCTP transport
|
// Construct the SCTP transport
|
||||||
sctp := api.NewRTCSctpTransport(dtls)
|
sctp := api.NewSCTPTransport(dtls)
|
||||||
|
|
||||||
// Handle incoming data channels
|
// Handle incoming data channels
|
||||||
sctp.OnDataChannel(func(channel *webrtc.RTCDataChannel) {
|
sctp.OnDataChannel(func(channel *webrtc.DataChannel) {
|
||||||
fmt.Printf("New DataChannel %s %d\n", channel.Label, channel.ID)
|
fmt.Printf("New DataChannel %s %d\n", channel.Label, channel.ID)
|
||||||
|
|
||||||
// Register the handlers
|
// Register the handlers
|
||||||
@@ -66,7 +66,7 @@ func main() {
|
|||||||
signal := Signal{
|
signal := Signal{
|
||||||
ICECandidates: iceCandidates,
|
ICECandidates: iceCandidates,
|
||||||
ICEParameters: iceParams,
|
ICEParameters: iceParams,
|
||||||
DtlsParameters: dtlsParams,
|
DTLSParameters: dtlsParams,
|
||||||
SCTPCapabilities: sctpCapabilities,
|
SCTPCapabilities: sctpCapabilities,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,9 +75,9 @@ func main() {
|
|||||||
remoteSignal := Signal{}
|
remoteSignal := Signal{}
|
||||||
util.Decode(util.MustReadStdin(), &remoteSignal)
|
util.Decode(util.MustReadStdin(), &remoteSignal)
|
||||||
|
|
||||||
iceRole := webrtc.RTCIceRoleControlled
|
iceRole := webrtc.ICERoleControlled
|
||||||
if *isOffer {
|
if *isOffer {
|
||||||
iceRole = webrtc.RTCIceRoleControlling
|
iceRole = webrtc.ICERoleControlling
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ice.SetRemoteCandidates(remoteSignal.ICECandidates)
|
err = ice.SetRemoteCandidates(remoteSignal.ICECandidates)
|
||||||
@@ -88,7 +88,7 @@ func main() {
|
|||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Start the DTLS transport
|
// Start the DTLS transport
|
||||||
err = dtls.Start(remoteSignal.DtlsParameters)
|
err = dtls.Start(remoteSignal.DTLSParameters)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Start the SCTP transport
|
// Start the SCTP transport
|
||||||
@@ -97,12 +97,12 @@ func main() {
|
|||||||
|
|
||||||
// Construct the data channel as the offerer
|
// Construct the data channel as the offerer
|
||||||
if *isOffer {
|
if *isOffer {
|
||||||
dcParams := &webrtc.RTCDataChannelParameters{
|
dcParams := &webrtc.DataChannelParameters{
|
||||||
Label: "Foo",
|
Label: "Foo",
|
||||||
ID: 1,
|
ID: 1,
|
||||||
}
|
}
|
||||||
var channel *webrtc.RTCDataChannel
|
var channel *webrtc.DataChannel
|
||||||
channel, err = api.NewRTCDataChannel(sctp, dcParams)
|
channel, err = api.NewDataChannel(sctp, dcParams)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Register the handlers
|
// Register the handlers
|
||||||
@@ -118,13 +118,13 @@ func main() {
|
|||||||
// This is not part of the ORTC spec. You are free
|
// This is not part of the ORTC spec. You are free
|
||||||
// to exchange this information any way you want.
|
// to exchange this information any way you want.
|
||||||
type Signal struct {
|
type Signal struct {
|
||||||
ICECandidates []webrtc.RTCIceCandidate `json:"iceCandidates"`
|
ICECandidates []webrtc.ICECandidate `json:"iceCandidates"`
|
||||||
ICEParameters webrtc.RTCIceParameters `json:"iceParameters"`
|
ICEParameters webrtc.ICEParameters `json:"iceParameters"`
|
||||||
DtlsParameters webrtc.RTCDtlsParameters `json:"dtlsParameters"`
|
DTLSParameters webrtc.DTLSParameters `json:"dtlsParameters"`
|
||||||
SCTPCapabilities webrtc.RTCSctpCapabilities `json:"sctpCapabilities"`
|
SCTPCapabilities webrtc.SCTPCapabilities `json:"sctpCapabilities"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleOnOpen(channel *webrtc.RTCDataChannel) func() {
|
func handleOnOpen(channel *webrtc.DataChannel) func() {
|
||||||
return func() {
|
return func() {
|
||||||
fmt.Printf("Data channel '%s'-'%d' open. Random messages will now be sent to any connected DataChannels every 5 seconds\n", channel.Label, channel.ID)
|
fmt.Printf("Data channel '%s'-'%d' open. Random messages will now be sent to any connected DataChannels every 5 seconds\n", channel.Label, channel.ID)
|
||||||
|
|
||||||
@@ -138,7 +138,7 @@ func handleOnOpen(channel *webrtc.RTCDataChannel) func() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMessage(channel *webrtc.RTCDataChannel) func(datachannel.Payload) {
|
func handleMessage(channel *webrtc.DataChannel) func(datachannel.Payload) {
|
||||||
return func(payload datachannel.Payload) {
|
return func(payload datachannel.Payload) {
|
||||||
switch p := payload.(type) {
|
switch p := payload.(type) {
|
||||||
case *datachannel.PayloadString:
|
case *datachannel.PayloadString:
|
||||||
|
@@ -20,8 +20,8 @@ func main() {
|
|||||||
// Everything below is the pion-WebRTC API! Thanks for using it ❤️.
|
// Everything below is the pion-WebRTC API! Thanks for using it ❤️.
|
||||||
|
|
||||||
// Prepare the configuration
|
// Prepare the configuration
|
||||||
config := webrtc.RTCConfiguration{
|
config := webrtc.Configuration{
|
||||||
IceServers: []webrtc.RTCIceServer{
|
ICEServers: []webrtc.ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{"stun:stun.l.google.com:19302"},
|
URLs: []string{"stun:stun.l.google.com:19302"},
|
||||||
},
|
},
|
||||||
@@ -29,7 +29,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new RTCPeerConnection
|
// Create a new RTCPeerConnection
|
||||||
peerConnection, err := webrtc.NewRTCPeerConnection(config)
|
peerConnection, err := webrtc.NewPeerConnection(config)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Set the handler for ICE connection state
|
// Set the handler for ICE connection state
|
||||||
@@ -39,7 +39,7 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Register data channel creation handling
|
// Register data channel creation handling
|
||||||
peerConnection.OnDataChannel(func(d *webrtc.RTCDataChannel) {
|
peerConnection.OnDataChannel(func(d *webrtc.DataChannel) {
|
||||||
fmt.Printf("New DataChannel %s %d\n", d.Label, d.ID)
|
fmt.Printf("New DataChannel %s %d\n", d.Label, d.ID)
|
||||||
|
|
||||||
// Register channel opening handling
|
// Register channel opening handling
|
||||||
@@ -93,12 +93,12 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// mustSignalViaHTTP exchange the SDP offer and answer using an HTTP server.
|
// mustSignalViaHTTP exchange the SDP offer and answer using an HTTP server.
|
||||||
func mustSignalViaHTTP(address string) (offerOut chan webrtc.RTCSessionDescription, answerIn chan webrtc.RTCSessionDescription) {
|
func mustSignalViaHTTP(address string) (offerOut chan webrtc.SessionDescription, answerIn chan webrtc.SessionDescription) {
|
||||||
offerOut = make(chan webrtc.RTCSessionDescription)
|
offerOut = make(chan webrtc.SessionDescription)
|
||||||
answerIn = make(chan webrtc.RTCSessionDescription)
|
answerIn = make(chan webrtc.SessionDescription)
|
||||||
|
|
||||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
var offer webrtc.RTCSessionDescription
|
var offer webrtc.SessionDescription
|
||||||
err := json.NewDecoder(r.Body).Decode(&offer)
|
err := json.NewDecoder(r.Body).Decode(&offer)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
|
@@ -21,8 +21,8 @@ func main() {
|
|||||||
// Everything below is the pion-WebRTC API! Thanks for using it ❤️.
|
// Everything below is the pion-WebRTC API! Thanks for using it ❤️.
|
||||||
|
|
||||||
// Prepare the configuration
|
// Prepare the configuration
|
||||||
config := webrtc.RTCConfiguration{
|
config := webrtc.Configuration{
|
||||||
IceServers: []webrtc.RTCIceServer{
|
ICEServers: []webrtc.ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{"stun:stun.l.google.com:19302"},
|
URLs: []string{"stun:stun.l.google.com:19302"},
|
||||||
},
|
},
|
||||||
@@ -30,7 +30,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new RTCPeerConnection
|
// Create a new RTCPeerConnection
|
||||||
peerConnection, err := webrtc.NewRTCPeerConnection(config)
|
peerConnection, err := webrtc.NewPeerConnection(config)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Create a datachannel with label 'data'
|
// Create a datachannel with label 'data'
|
||||||
@@ -88,7 +88,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// mustSignalViaHTTP exchange the SDP offer and answer using an HTTP Post request.
|
// mustSignalViaHTTP exchange the SDP offer and answer using an HTTP Post request.
|
||||||
func mustSignalViaHTTP(offer webrtc.RTCSessionDescription, address string) webrtc.RTCSessionDescription {
|
func mustSignalViaHTTP(offer webrtc.SessionDescription, address string) webrtc.SessionDescription {
|
||||||
b := new(bytes.Buffer)
|
b := new(bytes.Buffer)
|
||||||
err := json.NewEncoder(b).Encode(offer)
|
err := json.NewEncoder(b).Encode(offer)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
@@ -97,7 +97,7 @@ func mustSignalViaHTTP(offer webrtc.RTCSessionDescription, address string) webrt
|
|||||||
util.Check(err)
|
util.Check(err)
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
var answer webrtc.RTCSessionDescription
|
var answer webrtc.SessionDescription
|
||||||
err = json.NewDecoder(resp.Body).Decode(&answer)
|
err = json.NewDecoder(resp.Body).Decode(&answer)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
|
@@ -16,12 +16,12 @@ func main() {
|
|||||||
|
|
||||||
// Setup the codecs you want to use.
|
// Setup the codecs you want to use.
|
||||||
// We'll use a VP8 codec but you can also define your own
|
// We'll use a VP8 codec but you can also define your own
|
||||||
webrtc.RegisterCodec(webrtc.NewRTCRtpOpusCodec(webrtc.DefaultPayloadTypeOpus, 48000, 2))
|
webrtc.RegisterCodec(webrtc.NewRTPOpusCodec(webrtc.DefaultPayloadTypeOpus, 48000, 2))
|
||||||
webrtc.RegisterCodec(webrtc.NewRTCRtpVP8Codec(webrtc.DefaultPayloadTypeVP8, 90000))
|
webrtc.RegisterCodec(webrtc.NewRTPVP8Codec(webrtc.DefaultPayloadTypeVP8, 90000))
|
||||||
|
|
||||||
// Prepare the configuration
|
// Prepare the configuration
|
||||||
config := webrtc.RTCConfiguration{
|
config := webrtc.Configuration{
|
||||||
IceServers: []webrtc.RTCIceServer{
|
ICEServers: []webrtc.ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{"stun:stun.l.google.com:19302"},
|
URLs: []string{"stun:stun.l.google.com:19302"},
|
||||||
},
|
},
|
||||||
@@ -29,13 +29,13 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new RTCPeerConnection
|
// Create a new RTCPeerConnection
|
||||||
peerConnection, err := webrtc.NewRTCPeerConnection(config)
|
peerConnection, err := webrtc.NewPeerConnection(config)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Set a handler for when a new remote track starts, this handler saves buffers to disk as
|
// Set a handler for when a new remote track starts, this handler saves buffers to disk as
|
||||||
// an ivf file, since we could have multiple video tracks we provide a counter.
|
// an ivf file, since we could have multiple video tracks we provide a counter.
|
||||||
// In your application this is where you would handle/process video
|
// In your application this is where you would handle/process video
|
||||||
peerConnection.OnTrack(func(track *webrtc.RTCTrack) {
|
peerConnection.OnTrack(func(track *webrtc.Track) {
|
||||||
// Send a PLI on an interval so that the publisher is pushing a keyframe every rtcpPLIInterval
|
// 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
|
// 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() {
|
go func() {
|
||||||
@@ -66,7 +66,7 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Wait for the offer to be pasted
|
// Wait for the offer to be pasted
|
||||||
offer := webrtc.RTCSessionDescription{}
|
offer := webrtc.SessionDescription{}
|
||||||
util.Decode(util.MustReadStdin(), &offer)
|
util.Decode(util.MustReadStdin(), &offer)
|
||||||
|
|
||||||
// Set the remote SessionDescription
|
// Set the remote SessionDescription
|
||||||
|
@@ -16,8 +16,8 @@ import (
|
|||||||
"github.com/pions/webrtc/examples/util"
|
"github.com/pions/webrtc/examples/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var peerConnectionConfig = webrtc.RTCConfiguration{
|
var peerConnectionConfig = webrtc.Configuration{
|
||||||
IceServers: []webrtc.RTCIceServer{
|
ICEServers: []webrtc.ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{"stun:stun.l.google.com:19302"},
|
URLs: []string{"stun:stun.l.google.com:19302"},
|
||||||
},
|
},
|
||||||
@@ -57,17 +57,17 @@ func main() {
|
|||||||
util.Check(err)
|
util.Check(err)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
offer := webrtc.RTCSessionDescription{}
|
offer := webrtc.SessionDescription{}
|
||||||
util.Decode(mustReadHTTP(sdp), &offer)
|
util.Decode(mustReadHTTP(sdp), &offer)
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
|
|
||||||
/* Everything below is the pion-WebRTC API, thanks for using it! */
|
/* Everything below is the pion-WebRTC API, thanks for using it! */
|
||||||
|
|
||||||
// Only support VP8, this makes our proxying code simpler
|
// Only support VP8, this makes our proxying code simpler
|
||||||
webrtc.RegisterCodec(webrtc.NewRTCRtpVP8Codec(webrtc.DefaultPayloadTypeVP8, 90000))
|
webrtc.RegisterCodec(webrtc.NewRTPVP8Codec(webrtc.DefaultPayloadTypeVP8, 90000))
|
||||||
|
|
||||||
// Create a new RTCPeerConnection
|
// Create a new RTCPeerConnection
|
||||||
peerConnection, err := webrtc.NewRTCPeerConnection(peerConnectionConfig)
|
peerConnection, err := webrtc.NewPeerConnection(peerConnectionConfig)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
inboundSSRC := make(chan uint32)
|
inboundSSRC := make(chan uint32)
|
||||||
@@ -77,7 +77,7 @@ func main() {
|
|||||||
var outboundRTPLock sync.RWMutex
|
var outboundRTPLock sync.RWMutex
|
||||||
// Set a handler for when a new remote track starts, this just distributes all our packets
|
// Set a handler for when a new remote track starts, this just distributes all our packets
|
||||||
// to connected peers
|
// to connected peers
|
||||||
peerConnection.OnTrack(func(track *webrtc.RTCTrack) {
|
peerConnection.OnTrack(func(track *webrtc.Track) {
|
||||||
// Send a PLI on an interval so that the publisher is pushing a keyframe every rtcpPLIInterval
|
// Send a PLI on an interval so that the publisher is pushing a keyframe every rtcpPLIInterval
|
||||||
// This can be less wasteful by processing incoming RTCP events, then we would emit a NACK/PLI when a viewer requests it
|
// This can be less wasteful by processing incoming RTCP events, then we would emit a NACK/PLI when a viewer requests it
|
||||||
go func() {
|
go func() {
|
||||||
@@ -128,11 +128,11 @@ func main() {
|
|||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
fmt.Println("Curl an base64 SDP to start sendonly peer connection")
|
fmt.Println("Curl an base64 SDP to start sendonly peer connection")
|
||||||
|
|
||||||
recvOnlyOffer := webrtc.RTCSessionDescription{}
|
recvOnlyOffer := webrtc.SessionDescription{}
|
||||||
util.Decode(mustReadHTTP(sdp), &recvOnlyOffer)
|
util.Decode(mustReadHTTP(sdp), &recvOnlyOffer)
|
||||||
|
|
||||||
// Create a new RTCPeerConnection
|
// Create a new PeerConnection
|
||||||
peerConnection, err := webrtc.NewRTCPeerConnection(peerConnectionConfig)
|
peerConnection, err := webrtc.NewPeerConnection(peerConnectionConfig)
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
|
|
||||||
// Create a single VP8 Track to send videa
|
// Create a single VP8 Track to send videa
|
||||||
|
@@ -23,7 +23,7 @@ func init() {
|
|||||||
// Pipeline is a wrapper for a GStreamer Pipeline
|
// Pipeline is a wrapper for a GStreamer Pipeline
|
||||||
type Pipeline struct {
|
type Pipeline struct {
|
||||||
Pipeline *C.GstElement
|
Pipeline *C.GstElement
|
||||||
in chan<- media.RTCSample
|
in chan<- media.Sample
|
||||||
// stop acts as a signal that this pipeline is stopped
|
// stop acts as a signal that this pipeline is stopped
|
||||||
// any pending sends to Pipeline.in should be cancelled
|
// any pending sends to Pipeline.in should be cancelled
|
||||||
stop chan interface{}
|
stop chan interface{}
|
||||||
@@ -35,7 +35,7 @@ var pipelines = make(map[int]*Pipeline)
|
|||||||
var pipelinesLock sync.Mutex
|
var pipelinesLock sync.Mutex
|
||||||
|
|
||||||
// CreatePipeline creates a GStreamer Pipeline
|
// CreatePipeline creates a GStreamer Pipeline
|
||||||
func CreatePipeline(codecName string, in chan<- media.RTCSample, pipelineSrc string) *Pipeline {
|
func CreatePipeline(codecName string, in chan<- media.Sample, pipelineSrc string) *Pipeline {
|
||||||
pipelineStr := "appsink name=appsink"
|
pipelineStr := "appsink name=appsink"
|
||||||
switch codecName {
|
switch codecName {
|
||||||
case webrtc.VP8:
|
case webrtc.VP8:
|
||||||
@@ -106,7 +106,7 @@ func goHandlePipelineBuffer(buffer unsafe.Pointer, bufferLen C.int, duration C.i
|
|||||||
// We need to be able to cancel this function even f pipeline.in isn't being serviced
|
// We need to be able to cancel this function even f pipeline.in isn't being serviced
|
||||||
// When pipeline.stop is closed the sending of data will be cancelled.
|
// When pipeline.stop is closed the sending of data will be cancelled.
|
||||||
select {
|
select {
|
||||||
case pipeline.in <- media.RTCSample{Data: C.GoBytes(buffer, bufferLen), Samples: samples}:
|
case pipeline.in <- media.Sample{Data: C.GoBytes(buffer, bufferLen), Samples: samples}:
|
||||||
case <-pipeline.stop:
|
case <-pipeline.stop:
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
108
mediaengine.go
108
mediaengine.go
@@ -17,13 +17,13 @@ const (
|
|||||||
DefaultPayloadTypeH264 = 100
|
DefaultPayloadTypeH264 = 100
|
||||||
)
|
)
|
||||||
|
|
||||||
// MediaEngine defines the codecs supported by a RTCPeerConnection
|
// MediaEngine defines the codecs supported by a PeerConnection
|
||||||
type MediaEngine struct {
|
type MediaEngine struct {
|
||||||
codecs []*RTCRtpCodec
|
codecs []*RTPCodec
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterCodec registers a codec to a media engine
|
// RegisterCodec registers a codec to a media engine
|
||||||
func (m *MediaEngine) RegisterCodec(codec *RTCRtpCodec) uint8 {
|
func (m *MediaEngine) RegisterCodec(codec *RTPCodec) uint8 {
|
||||||
// TODO: generate PayloadType if not set
|
// TODO: generate PayloadType if not set
|
||||||
m.codecs = append(m.codecs, codec)
|
m.codecs = append(m.codecs, codec)
|
||||||
return codec.PayloadType
|
return codec.PayloadType
|
||||||
@@ -31,14 +31,14 @@ func (m *MediaEngine) RegisterCodec(codec *RTCRtpCodec) uint8 {
|
|||||||
|
|
||||||
// RegisterDefaultCodecs is a helper that registers the default codecs supported by pions-webrtc
|
// RegisterDefaultCodecs is a helper that registers the default codecs supported by pions-webrtc
|
||||||
func (m *MediaEngine) RegisterDefaultCodecs() {
|
func (m *MediaEngine) RegisterDefaultCodecs() {
|
||||||
m.RegisterCodec(NewRTCRtpOpusCodec(DefaultPayloadTypeOpus, 48000, 2))
|
m.RegisterCodec(NewRTPOpusCodec(DefaultPayloadTypeOpus, 48000, 2))
|
||||||
m.RegisterCodec(NewRTCRtpG722Codec(DefaultPayloadTypeG722, 8000))
|
m.RegisterCodec(NewRTPG722Codec(DefaultPayloadTypeG722, 8000))
|
||||||
m.RegisterCodec(NewRTCRtpVP8Codec(DefaultPayloadTypeVP8, 90000))
|
m.RegisterCodec(NewRTPVP8Codec(DefaultPayloadTypeVP8, 90000))
|
||||||
m.RegisterCodec(NewRTCRtpH264Codec(DefaultPayloadTypeH264, 90000))
|
m.RegisterCodec(NewRTPH264Codec(DefaultPayloadTypeH264, 90000))
|
||||||
m.RegisterCodec(NewRTCRtpVP9Codec(DefaultPayloadTypeVP9, 90000))
|
m.RegisterCodec(NewRTPVP9Codec(DefaultPayloadTypeVP9, 90000))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MediaEngine) getCodec(payloadType uint8) (*RTCRtpCodec, error) {
|
func (m *MediaEngine) getCodec(payloadType uint8) (*RTPCodec, error) {
|
||||||
for _, codec := range m.codecs {
|
for _, codec := range m.codecs {
|
||||||
if codec.PayloadType == payloadType {
|
if codec.PayloadType == payloadType {
|
||||||
return codec, nil
|
return codec, nil
|
||||||
@@ -47,7 +47,7 @@ func (m *MediaEngine) getCodec(payloadType uint8) (*RTCRtpCodec, error) {
|
|||||||
return nil, ErrCodecNotFound
|
return nil, ErrCodecNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MediaEngine) getCodecSDP(sdpCodec sdp.Codec) (*RTCRtpCodec, error) {
|
func (m *MediaEngine) getCodecSDP(sdpCodec sdp.Codec) (*RTPCodec, error) {
|
||||||
for _, codec := range m.codecs {
|
for _, codec := range m.codecs {
|
||||||
if codec.Name == sdpCodec.Name &&
|
if codec.Name == sdpCodec.Name &&
|
||||||
codec.ClockRate == sdpCodec.ClockRate &&
|
codec.ClockRate == sdpCodec.ClockRate &&
|
||||||
@@ -60,8 +60,8 @@ func (m *MediaEngine) getCodecSDP(sdpCodec sdp.Codec) (*RTCRtpCodec, error) {
|
|||||||
return nil, ErrCodecNotFound
|
return nil, ErrCodecNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MediaEngine) getCodecsByKind(kind RTCRtpCodecType) []*RTCRtpCodec {
|
func (m *MediaEngine) getCodecsByKind(kind RTPCodecType) []*RTPCodec {
|
||||||
var codecs []*RTCRtpCodec
|
var codecs []*RTPCodec
|
||||||
for _, codec := range m.codecs {
|
for _, codec := range m.codecs {
|
||||||
if codec.Type == kind {
|
if codec.Type == kind {
|
||||||
codecs = append(codecs, codec)
|
codecs = append(codecs, codec)
|
||||||
@@ -79,9 +79,9 @@ const (
|
|||||||
H264 = "H264"
|
H264 = "H264"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewRTCRtpG722Codec is a helper to create a G722 codec
|
// NewRTPG722Codec is a helper to create a G722 codec
|
||||||
func NewRTCRtpG722Codec(payloadType uint8, clockrate uint32) *RTCRtpCodec {
|
func NewRTPG722Codec(payloadType uint8, clockrate uint32) *RTPCodec {
|
||||||
c := NewRTCRtpCodec(RTCRtpCodecTypeAudio,
|
c := NewRTPCodec(RTPCodecTypeAudio,
|
||||||
G722,
|
G722,
|
||||||
clockrate,
|
clockrate,
|
||||||
0,
|
0,
|
||||||
@@ -91,9 +91,9 @@ func NewRTCRtpG722Codec(payloadType uint8, clockrate uint32) *RTCRtpCodec {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRTCRtpOpusCodec is a helper to create an Opus codec
|
// NewRTPOpusCodec is a helper to create an Opus codec
|
||||||
func NewRTCRtpOpusCodec(payloadType uint8, clockrate uint32, channels uint16) *RTCRtpCodec {
|
func NewRTPOpusCodec(payloadType uint8, clockrate uint32, channels uint16) *RTPCodec {
|
||||||
c := NewRTCRtpCodec(RTCRtpCodecTypeAudio,
|
c := NewRTPCodec(RTPCodecTypeAudio,
|
||||||
Opus,
|
Opus,
|
||||||
clockrate,
|
clockrate,
|
||||||
channels,
|
channels,
|
||||||
@@ -103,9 +103,9 @@ func NewRTCRtpOpusCodec(payloadType uint8, clockrate uint32, channels uint16) *R
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRTCRtpVP8Codec is a helper to create an VP8 codec
|
// NewRTPVP8Codec is a helper to create an VP8 codec
|
||||||
func NewRTCRtpVP8Codec(payloadType uint8, clockrate uint32) *RTCRtpCodec {
|
func NewRTPVP8Codec(payloadType uint8, clockrate uint32) *RTPCodec {
|
||||||
c := NewRTCRtpCodec(RTCRtpCodecTypeVideo,
|
c := NewRTPCodec(RTPCodecTypeVideo,
|
||||||
VP8,
|
VP8,
|
||||||
clockrate,
|
clockrate,
|
||||||
0,
|
0,
|
||||||
@@ -115,9 +115,9 @@ func NewRTCRtpVP8Codec(payloadType uint8, clockrate uint32) *RTCRtpCodec {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRTCRtpVP9Codec is a helper to create an VP9 codec
|
// NewRTPVP9Codec is a helper to create an VP9 codec
|
||||||
func NewRTCRtpVP9Codec(payloadType uint8, clockrate uint32) *RTCRtpCodec {
|
func NewRTPVP9Codec(payloadType uint8, clockrate uint32) *RTPCodec {
|
||||||
c := NewRTCRtpCodec(RTCRtpCodecTypeVideo,
|
c := NewRTPCodec(RTPCodecTypeVideo,
|
||||||
VP9,
|
VP9,
|
||||||
clockrate,
|
clockrate,
|
||||||
0,
|
0,
|
||||||
@@ -127,9 +127,9 @@ func NewRTCRtpVP9Codec(payloadType uint8, clockrate uint32) *RTCRtpCodec {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRTCRtpH264Codec is a helper to create an H264 codec
|
// NewRTPH264Codec is a helper to create an H264 codec
|
||||||
func NewRTCRtpH264Codec(payloadType uint8, clockrate uint32) *RTCRtpCodec {
|
func NewRTPH264Codec(payloadType uint8, clockrate uint32) *RTPCodec {
|
||||||
c := NewRTCRtpCodec(RTCRtpCodecTypeVideo,
|
c := NewRTPCodec(RTPCodecTypeVideo,
|
||||||
H264,
|
H264,
|
||||||
clockrate,
|
clockrate,
|
||||||
0,
|
0,
|
||||||
@@ -139,50 +139,50 @@ func NewRTCRtpH264Codec(payloadType uint8, clockrate uint32) *RTCRtpCodec {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTCRtpCodecType determines the type of a codec
|
// RTPCodecType determines the type of a codec
|
||||||
type RTCRtpCodecType int
|
type RTPCodecType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
||||||
// RTCRtpCodecTypeAudio indicates this is an audio codec
|
// RTPCodecTypeAudio indicates this is an audio codec
|
||||||
RTCRtpCodecTypeAudio RTCRtpCodecType = iota + 1
|
RTPCodecTypeAudio RTPCodecType = iota + 1
|
||||||
|
|
||||||
// RTCRtpCodecTypeVideo indicates this is a video codec
|
// RTPCodecTypeVideo indicates this is a video codec
|
||||||
RTCRtpCodecTypeVideo
|
RTPCodecTypeVideo
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t RTCRtpCodecType) String() string {
|
func (t RTPCodecType) String() string {
|
||||||
switch t {
|
switch t {
|
||||||
case RTCRtpCodecTypeAudio:
|
case RTPCodecTypeAudio:
|
||||||
return "audio"
|
return "audio"
|
||||||
case RTCRtpCodecTypeVideo:
|
case RTPCodecTypeVideo:
|
||||||
return "video"
|
return "video"
|
||||||
default:
|
default:
|
||||||
return ErrUnknownType.Error()
|
return ErrUnknownType.Error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTCRtpCodec represents a codec supported by the PeerConnection
|
// RTPCodec represents a codec supported by the PeerConnection
|
||||||
type RTCRtpCodec struct {
|
type RTPCodec struct {
|
||||||
RTCRtpCodecCapability
|
RTPCodecCapability
|
||||||
Type RTCRtpCodecType
|
Type RTPCodecType
|
||||||
Name string
|
Name string
|
||||||
PayloadType uint8
|
PayloadType uint8
|
||||||
Payloader rtp.Payloader
|
Payloader rtp.Payloader
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRTCRtpCodec is used to define a new codec
|
// NewRTPCodec is used to define a new codec
|
||||||
func NewRTCRtpCodec(
|
func NewRTPCodec(
|
||||||
codecType RTCRtpCodecType,
|
codecType RTPCodecType,
|
||||||
name string,
|
name string,
|
||||||
clockrate uint32,
|
clockrate uint32,
|
||||||
channels uint16,
|
channels uint16,
|
||||||
fmtp string,
|
fmtp string,
|
||||||
payloadType uint8,
|
payloadType uint8,
|
||||||
payloader rtp.Payloader,
|
payloader rtp.Payloader,
|
||||||
) *RTCRtpCodec {
|
) *RTPCodec {
|
||||||
return &RTCRtpCodec{
|
return &RTPCodec{
|
||||||
RTCRtpCodecCapability: RTCRtpCodecCapability{
|
RTPCodecCapability: RTPCodecCapability{
|
||||||
MimeType: codecType.String() + "/" + name,
|
MimeType: codecType.String() + "/" + name,
|
||||||
ClockRate: clockrate,
|
ClockRate: clockrate,
|
||||||
Channels: channels,
|
Channels: channels,
|
||||||
@@ -195,21 +195,21 @@ func NewRTCRtpCodec(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTCRtpCodecCapability provides information about codec capabilities.
|
// RTPCodecCapability provides information about codec capabilities.
|
||||||
type RTCRtpCodecCapability struct {
|
type RTPCodecCapability struct {
|
||||||
MimeType string
|
MimeType string
|
||||||
ClockRate uint32
|
ClockRate uint32
|
||||||
Channels uint16
|
Channels uint16
|
||||||
SdpFmtpLine string
|
SdpFmtpLine string
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTCRtpHeaderExtensionCapability is used to define a RFC5285 RTP header extension supported by the codec.
|
// RTPHeaderExtensionCapability is used to define a RFC5285 RTP header extension supported by the codec.
|
||||||
type RTCRtpHeaderExtensionCapability struct {
|
type RTPHeaderExtensionCapability struct {
|
||||||
URI string
|
URI string
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTCRtpCapabilities represents the capabilities of a transceiver
|
// RTPCapabilities represents the capabilities of a transceiver
|
||||||
type RTCRtpCapabilities struct {
|
type RTPCapabilities struct {
|
||||||
Codecs []RTCRtpCodecCapability
|
Codecs []RTPCodecCapability
|
||||||
HeaderExtensions []RTCRtpHeaderExtensionCapability
|
HeaderExtensions []RTPHeaderExtensionCapability
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
package media
|
package media
|
||||||
|
|
||||||
// RTCSample contains media, and the amount of samples in it
|
// Sample contains media, and the amount of samples in it
|
||||||
type RTCSample struct {
|
type Sample struct {
|
||||||
Data []byte
|
Data []byte
|
||||||
Samples uint32
|
Samples uint32
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// SampleBuilder contains all packets
|
// SampleBuilder contains all packets
|
||||||
// maxLate determines how long we should wait until we get a valid RTCSample
|
// maxLate determines how long we should wait until we get a valid Sample
|
||||||
// The larger the value the less packet loss you will see, but higher latency
|
// The larger the value the less packet loss you will see, but higher latency
|
||||||
type SampleBuilder struct {
|
type SampleBuilder struct {
|
||||||
maxLate uint16
|
maxLate uint16
|
||||||
@@ -41,7 +41,7 @@ func (s *SampleBuilder) Push(p *rtp.Packet) {
|
|||||||
|
|
||||||
// We have a valid collection of RTP Packets
|
// We have a valid collection of RTP Packets
|
||||||
// walk forwards building a sample if everything looks good clear and update buffer+values
|
// walk forwards building a sample if everything looks good clear and update buffer+values
|
||||||
func (s *SampleBuilder) buildSample(firstBuffer uint16) *media.RTCSample {
|
func (s *SampleBuilder) buildSample(firstBuffer uint16) *media.Sample {
|
||||||
data := []byte{}
|
data := []byte{}
|
||||||
|
|
||||||
for i := firstBuffer; s.buffer[i] != nil; i++ {
|
for i := firstBuffer; s.buffer[i] != nil; i++ {
|
||||||
@@ -59,7 +59,7 @@ func (s *SampleBuilder) buildSample(firstBuffer uint16) *media.RTCSample {
|
|||||||
for j := firstBuffer; j < i; j++ {
|
for j := firstBuffer; j < i; j++ {
|
||||||
s.buffer[j] = nil
|
s.buffer[j] = nil
|
||||||
}
|
}
|
||||||
return &media.RTCSample{Data: data, Samples: samples}
|
return &media.Sample{Data: data, Samples: samples}
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := s.depacketizer.Unmarshal(s.buffer[i])
|
p, err := s.depacketizer.Unmarshal(s.buffer[i])
|
||||||
@@ -82,7 +82,7 @@ func seqnumDistance(x, y uint16) uint16 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pop scans buffer for valid samples, returns nil when no valid samples have been found
|
// Pop scans buffer for valid samples, returns nil when no valid samples have been found
|
||||||
func (s *SampleBuilder) Pop() *media.RTCSample {
|
func (s *SampleBuilder) Pop() *media.Sample {
|
||||||
var i uint16
|
var i uint16
|
||||||
if !s.isContiguous {
|
if !s.isContiguous {
|
||||||
i = s.lastPush - s.maxLate
|
i = s.lastPush - s.maxLate
|
||||||
|
@@ -11,7 +11,7 @@ import (
|
|||||||
type sampleBuilderTest struct {
|
type sampleBuilderTest struct {
|
||||||
message string
|
message string
|
||||||
packets []*rtp.Packet
|
packets []*rtp.Packet
|
||||||
samples []*media.RTCSample
|
samples []*media.Sample
|
||||||
maxLate uint16
|
maxLate uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ var testCases = []sampleBuilderTest{
|
|||||||
packets: []*rtp.Packet{
|
packets: []*rtp.Packet{
|
||||||
{Header: rtp.Header{SequenceNumber: 5000, Timestamp: 5}, Payload: []byte{0x01}},
|
{Header: rtp.Header{SequenceNumber: 5000, Timestamp: 5}, Payload: []byte{0x01}},
|
||||||
},
|
},
|
||||||
samples: []*media.RTCSample{},
|
samples: []*media.Sample{},
|
||||||
maxLate: 50,
|
maxLate: 50,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -38,7 +38,7 @@ var testCases = []sampleBuilderTest{
|
|||||||
{Header: rtp.Header{SequenceNumber: 5001, Timestamp: 6}, Payload: []byte{0x02}},
|
{Header: rtp.Header{SequenceNumber: 5001, Timestamp: 6}, Payload: []byte{0x02}},
|
||||||
{Header: rtp.Header{SequenceNumber: 5002, Timestamp: 7}, Payload: []byte{0x03}},
|
{Header: rtp.Header{SequenceNumber: 5002, Timestamp: 7}, Payload: []byte{0x03}},
|
||||||
},
|
},
|
||||||
samples: []*media.RTCSample{
|
samples: []*media.Sample{
|
||||||
{Data: []byte{0x02}, Samples: 1},
|
{Data: []byte{0x02}, Samples: 1},
|
||||||
},
|
},
|
||||||
maxLate: 50,
|
maxLate: 50,
|
||||||
@@ -51,7 +51,7 @@ var testCases = []sampleBuilderTest{
|
|||||||
{Header: rtp.Header{SequenceNumber: 5002, Timestamp: 6}, Payload: []byte{0x03}},
|
{Header: rtp.Header{SequenceNumber: 5002, Timestamp: 6}, Payload: []byte{0x03}},
|
||||||
{Header: rtp.Header{SequenceNumber: 5003, Timestamp: 7}, Payload: []byte{0x04}},
|
{Header: rtp.Header{SequenceNumber: 5003, Timestamp: 7}, Payload: []byte{0x04}},
|
||||||
},
|
},
|
||||||
samples: []*media.RTCSample{
|
samples: []*media.Sample{
|
||||||
{Data: []byte{0x02, 0x03}, Samples: 1},
|
{Data: []byte{0x02, 0x03}, Samples: 1},
|
||||||
},
|
},
|
||||||
maxLate: 50,
|
maxLate: 50,
|
||||||
@@ -63,7 +63,7 @@ var testCases = []sampleBuilderTest{
|
|||||||
{Header: rtp.Header{SequenceNumber: 5007, Timestamp: 6}, Payload: []byte{0x02}},
|
{Header: rtp.Header{SequenceNumber: 5007, Timestamp: 6}, Payload: []byte{0x02}},
|
||||||
{Header: rtp.Header{SequenceNumber: 5008, Timestamp: 7}, Payload: []byte{0x03}},
|
{Header: rtp.Header{SequenceNumber: 5008, Timestamp: 7}, Payload: []byte{0x03}},
|
||||||
},
|
},
|
||||||
samples: []*media.RTCSample{},
|
samples: []*media.Sample{},
|
||||||
maxLate: 50,
|
maxLate: 50,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -76,7 +76,7 @@ var testCases = []sampleBuilderTest{
|
|||||||
{Header: rtp.Header{SequenceNumber: 5004, Timestamp: 5}, Payload: []byte{0x05}},
|
{Header: rtp.Header{SequenceNumber: 5004, Timestamp: 5}, Payload: []byte{0x05}},
|
||||||
{Header: rtp.Header{SequenceNumber: 5005, Timestamp: 6}, Payload: []byte{0x06}},
|
{Header: rtp.Header{SequenceNumber: 5005, Timestamp: 6}, Payload: []byte{0x06}},
|
||||||
},
|
},
|
||||||
samples: []*media.RTCSample{
|
samples: []*media.Sample{
|
||||||
{Data: []byte{0x02}, Samples: 1},
|
{Data: []byte{0x02}, Samples: 1},
|
||||||
{Data: []byte{0x03}, Samples: 1},
|
{Data: []byte{0x03}, Samples: 1},
|
||||||
{Data: []byte{0x04}, Samples: 1},
|
{Data: []byte{0x04}, Samples: 1},
|
||||||
@@ -91,7 +91,7 @@ func TestSampleBuilder(t *testing.T) {
|
|||||||
|
|
||||||
for _, t := range testCases {
|
for _, t := range testCases {
|
||||||
s := New(t.maxLate, &fakeDepacketizer{})
|
s := New(t.maxLate, &fakeDepacketizer{})
|
||||||
samples := []*media.RTCSample{}
|
samples := []*media.Sample{}
|
||||||
|
|
||||||
for _, p := range t.packets {
|
for _, p := range t.packets {
|
||||||
s.Push(p)
|
s.Push(p)
|
||||||
@@ -112,10 +112,10 @@ func TestSampleBuilderMaxLate(t *testing.T) {
|
|||||||
s.Push(&rtp.Packet{Header: rtp.Header{SequenceNumber: 0, Timestamp: 1}, Payload: []byte{0x01}})
|
s.Push(&rtp.Packet{Header: rtp.Header{SequenceNumber: 0, Timestamp: 1}, Payload: []byte{0x01}})
|
||||||
s.Push(&rtp.Packet{Header: rtp.Header{SequenceNumber: 1, Timestamp: 2}, Payload: []byte{0x01}})
|
s.Push(&rtp.Packet{Header: rtp.Header{SequenceNumber: 1, Timestamp: 2}, Payload: []byte{0x01}})
|
||||||
s.Push(&rtp.Packet{Header: rtp.Header{SequenceNumber: 2, Timestamp: 3}, Payload: []byte{0x01}})
|
s.Push(&rtp.Packet{Header: rtp.Header{SequenceNumber: 2, Timestamp: 3}, Payload: []byte{0x01}})
|
||||||
assert.Equal(s.Pop(), &media.RTCSample{Data: []byte{0x01}, Samples: 1}, "Failed to build samples before gap")
|
assert.Equal(s.Pop(), &media.Sample{Data: []byte{0x01}, Samples: 1}, "Failed to build samples before gap")
|
||||||
|
|
||||||
s.Push(&rtp.Packet{Header: rtp.Header{SequenceNumber: 5000, Timestamp: 500}, Payload: []byte{0x02}})
|
s.Push(&rtp.Packet{Header: rtp.Header{SequenceNumber: 5000, Timestamp: 500}, Payload: []byte{0x02}})
|
||||||
s.Push(&rtp.Packet{Header: rtp.Header{SequenceNumber: 5001, Timestamp: 501}, Payload: []byte{0x02}})
|
s.Push(&rtp.Packet{Header: rtp.Header{SequenceNumber: 5001, Timestamp: 501}, Payload: []byte{0x02}})
|
||||||
s.Push(&rtp.Packet{Header: rtp.Header{SequenceNumber: 5002, Timestamp: 502}, Payload: []byte{0x02}})
|
s.Push(&rtp.Packet{Header: rtp.Header{SequenceNumber: 5002, Timestamp: 502}, Payload: []byte{0x02}})
|
||||||
assert.Equal(s.Pop(), &media.RTCSample{Data: []byte{0x02}, Samples: 1}, "Failed to build samples after large gap")
|
assert.Equal(s.Pop(), &media.Sample{Data: []byte{0x02}, Samples: 1}, "Failed to build samples after large gap")
|
||||||
}
|
}
|
||||||
|
@@ -29,7 +29,7 @@ type Config struct {
|
|||||||
|
|
||||||
// StartBase is used to start the TransportBase. Most implementations
|
// StartBase is used to start the TransportBase. Most implementations
|
||||||
// should instead use the methods on quic.Transport or
|
// should instead use the methods on quic.Transport or
|
||||||
// webrtc.RTCQuicTransport to setup a Quic connection.
|
// webrtc.QUICTransport to setup a Quic connection.
|
||||||
func (b *TransportBase) StartBase(conn net.Conn, config *Config) error {
|
func (b *TransportBase) StartBase(conn net.Conn, config *Config) error {
|
||||||
cfg := config.clone()
|
cfg := config.clone()
|
||||||
cfg.SkipVerify = true // Using self signed certificates; WebRTC will check the fingerprint
|
cfg.SkipVerify = true // Using self signed certificates; WebRTC will check the fingerprint
|
||||||
|
@@ -1,57 +1,57 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCBundlePolicy affects which media tracks are negotiated if the remote
|
// BundlePolicy affects which media tracks are negotiated if the remote
|
||||||
// endpoint is not bundle-aware, and what ICE candidates are gathered. If the
|
// endpoint is not bundle-aware, and what ICE candidates are gathered. If the
|
||||||
// remote endpoint is bundle-aware, all media tracks and data channels are
|
// remote endpoint is bundle-aware, all media tracks and data channels are
|
||||||
// bundled onto the same transport.
|
// bundled onto the same transport.
|
||||||
type RTCBundlePolicy int
|
type BundlePolicy int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCBundlePolicyBalanced indicates to gather ICE candidates for each
|
// BundlePolicyBalanced indicates to gather ICE candidates for each
|
||||||
// media type in use (audio, video, and data). If the remote endpoint is
|
// media type in use (audio, video, and data). If the remote endpoint is
|
||||||
// not bundle-aware, negotiate only one audio and video track on separate
|
// not bundle-aware, negotiate only one audio and video track on separate
|
||||||
// transports.
|
// transports.
|
||||||
RTCBundlePolicyBalanced RTCBundlePolicy = iota + 1
|
BundlePolicyBalanced BundlePolicy = iota + 1
|
||||||
|
|
||||||
// RTCBundlePolicyMaxCompat indicates to gather ICE candidates for each
|
// BundlePolicyMaxCompat indicates to gather ICE candidates for each
|
||||||
// track. If the remote endpoint is not bundle-aware, negotiate all media
|
// track. If the remote endpoint is not bundle-aware, negotiate all media
|
||||||
// tracks on separate transports.
|
// tracks on separate transports.
|
||||||
RTCBundlePolicyMaxCompat
|
BundlePolicyMaxCompat
|
||||||
|
|
||||||
// RTCBundlePolicyMaxBundle indicates to gather ICE candidates for only
|
// BundlePolicyMaxBundle indicates to gather ICE candidates for only
|
||||||
// one track. If the remote endpoint is not bundle-aware, negotiate only
|
// one track. If the remote endpoint is not bundle-aware, negotiate only
|
||||||
// one media track.
|
// one media track.
|
||||||
RTCBundlePolicyMaxBundle
|
BundlePolicyMaxBundle
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is done this way because of a linter.
|
// This is done this way because of a linter.
|
||||||
const (
|
const (
|
||||||
rtcBundlePolicyBalancedStr = "balanced"
|
bundlePolicyBalancedStr = "balanced"
|
||||||
rtcBundlePolicyMaxCompatStr = "max-compat"
|
bundlePolicyMaxCompatStr = "max-compat"
|
||||||
rtcBundlePolicyMaxBundleStr = "max-bundle"
|
bundlePolicyMaxBundleStr = "max-bundle"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRTCBundlePolicy(raw string) RTCBundlePolicy {
|
func newBundlePolicy(raw string) BundlePolicy {
|
||||||
switch raw {
|
switch raw {
|
||||||
case rtcBundlePolicyBalancedStr:
|
case bundlePolicyBalancedStr:
|
||||||
return RTCBundlePolicyBalanced
|
return BundlePolicyBalanced
|
||||||
case rtcBundlePolicyMaxCompatStr:
|
case bundlePolicyMaxCompatStr:
|
||||||
return RTCBundlePolicyMaxCompat
|
return BundlePolicyMaxCompat
|
||||||
case rtcBundlePolicyMaxBundleStr:
|
case bundlePolicyMaxBundleStr:
|
||||||
return RTCBundlePolicyMaxBundle
|
return BundlePolicyMaxBundle
|
||||||
default:
|
default:
|
||||||
return RTCBundlePolicy(Unknown)
|
return BundlePolicy(Unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t RTCBundlePolicy) String() string {
|
func (t BundlePolicy) String() string {
|
||||||
switch t {
|
switch t {
|
||||||
case RTCBundlePolicyBalanced:
|
case BundlePolicyBalanced:
|
||||||
return rtcBundlePolicyBalancedStr
|
return bundlePolicyBalancedStr
|
||||||
case RTCBundlePolicyMaxCompat:
|
case BundlePolicyMaxCompat:
|
||||||
return rtcBundlePolicyMaxCompatStr
|
return bundlePolicyMaxCompatStr
|
||||||
case RTCBundlePolicyMaxBundle:
|
case BundlePolicyMaxBundle:
|
||||||
return rtcBundlePolicyMaxBundleStr
|
return bundlePolicyMaxBundleStr
|
||||||
default:
|
default:
|
||||||
return ErrUnknownType.Error()
|
return ErrUnknownType.Error()
|
||||||
}
|
}
|
||||||
|
@@ -6,35 +6,35 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewRTCBundlePolicy(t *testing.T) {
|
func TestNewBundlePolicy(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
policyString string
|
policyString string
|
||||||
expectedPolicy RTCBundlePolicy
|
expectedPolicy BundlePolicy
|
||||||
}{
|
}{
|
||||||
{unknownStr, RTCBundlePolicy(Unknown)},
|
{unknownStr, BundlePolicy(Unknown)},
|
||||||
{"balanced", RTCBundlePolicyBalanced},
|
{"balanced", BundlePolicyBalanced},
|
||||||
{"max-compat", RTCBundlePolicyMaxCompat},
|
{"max-compat", BundlePolicyMaxCompat},
|
||||||
{"max-bundle", RTCBundlePolicyMaxBundle},
|
{"max-bundle", BundlePolicyMaxBundle},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
testCase.expectedPolicy,
|
testCase.expectedPolicy,
|
||||||
newRTCBundlePolicy(testCase.policyString),
|
newBundlePolicy(testCase.policyString),
|
||||||
"testCase: %d %v", i, testCase,
|
"testCase: %d %v", i, testCase,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCBundlePolicy_String(t *testing.T) {
|
func TestBundlePolicy_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
policy RTCBundlePolicy
|
policy BundlePolicy
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCBundlePolicy(Unknown), unknownStr},
|
{BundlePolicy(Unknown), unknownStr},
|
||||||
{RTCBundlePolicyBalanced, "balanced"},
|
{BundlePolicyBalanced, "balanced"},
|
||||||
{RTCBundlePolicyMaxCompat, "max-compat"},
|
{BundlePolicyMaxCompat, "max-compat"},
|
||||||
{RTCBundlePolicyMaxBundle, "max-bundle"},
|
{BundlePolicyMaxBundle, "max-bundle"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@@ -16,17 +16,17 @@ import (
|
|||||||
"github.com/pions/webrtc/pkg/rtcerr"
|
"github.com/pions/webrtc/pkg/rtcerr"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RTCCertificate represents a x509Cert used to authenticate WebRTC communications.
|
// Certificate represents a x509Cert used to authenticate WebRTC communications.
|
||||||
type RTCCertificate struct {
|
type Certificate struct {
|
||||||
privateKey crypto.PrivateKey
|
privateKey crypto.PrivateKey
|
||||||
x509Cert *x509.Certificate
|
x509Cert *x509.Certificate
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRTCCertificate generates a new x509 compliant RTCCertificate to be used
|
// NewCertificate generates a new x509 compliant Certificate to be used
|
||||||
// by DTLS for encrypting data sent over the wire. This method differs from
|
// by DTLS for encrypting data sent over the wire. This method differs from
|
||||||
// GenerateCertificate by allowing to specify a template x509.Certificate to
|
// GenerateCertificate by allowing to specify a template x509.Certificate to
|
||||||
// be used in order to define certificate parameters.
|
// be used in order to define certificate parameters.
|
||||||
func NewRTCCertificate(key crypto.PrivateKey, tpl x509.Certificate) (*RTCCertificate, error) {
|
func NewCertificate(key crypto.PrivateKey, tpl x509.Certificate) (*Certificate, error) {
|
||||||
var err error
|
var err error
|
||||||
var certDER []byte
|
var certDER []byte
|
||||||
switch sk := key.(type) {
|
switch sk := key.(type) {
|
||||||
@@ -53,12 +53,12 @@ func NewRTCCertificate(key crypto.PrivateKey, tpl x509.Certificate) (*RTCCertifi
|
|||||||
return nil, &rtcerr.UnknownError{Err: err}
|
return nil, &rtcerr.UnknownError{Err: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &RTCCertificate{privateKey: key, x509Cert: cert}, nil
|
return &Certificate{privateKey: key, x509Cert: cert}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equals determines if two certificates are identical by comparing both the
|
// Equals determines if two certificates are identical by comparing both the
|
||||||
// secretKeys and x509Certificates.
|
// secretKeys and x509Certificates.
|
||||||
func (c RTCCertificate) Equals(o RTCCertificate) bool {
|
func (c Certificate) Equals(o Certificate) bool {
|
||||||
switch cSK := c.privateKey.(type) {
|
switch cSK := c.privateKey.(type) {
|
||||||
case *rsa.PrivateKey:
|
case *rsa.PrivateKey:
|
||||||
if oSK, ok := o.privateKey.(*rsa.PrivateKey); ok {
|
if oSK, ok := o.privateKey.(*rsa.PrivateKey); ok {
|
||||||
@@ -82,7 +82,7 @@ func (c RTCCertificate) Equals(o RTCCertificate) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Expires returns the timestamp after which this certificate is no longer valid.
|
// Expires returns the timestamp after which this certificate is no longer valid.
|
||||||
func (c RTCCertificate) Expires() time.Time {
|
func (c Certificate) Expires() time.Time {
|
||||||
if c.x509Cert == nil {
|
if c.x509Cert == nil {
|
||||||
return time.Time{}
|
return time.Time{}
|
||||||
}
|
}
|
||||||
@@ -93,8 +93,8 @@ var fingerprintAlgorithms = []dtls.HashAlgorithm{dtls.HashAlgorithmSHA256}
|
|||||||
|
|
||||||
// GetFingerprints returns the list of certificate fingerprints, one of which
|
// GetFingerprints returns the list of certificate fingerprints, one of which
|
||||||
// is computed with the digest algorithm used in the certificate signature.
|
// is computed with the digest algorithm used in the certificate signature.
|
||||||
func (c RTCCertificate) GetFingerprints() []RTCDtlsFingerprint {
|
func (c Certificate) GetFingerprints() []DTLSFingerprint {
|
||||||
res := make([]RTCDtlsFingerprint, len(fingerprintAlgorithms))
|
res := make([]DTLSFingerprint, len(fingerprintAlgorithms))
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
for _, algo := range fingerprintAlgorithms {
|
for _, algo := range fingerprintAlgorithms {
|
||||||
@@ -103,7 +103,7 @@ func (c RTCCertificate) GetFingerprints() []RTCDtlsFingerprint {
|
|||||||
fmt.Printf("Failed to create fingerprint: %v\n", err)
|
fmt.Printf("Failed to create fingerprint: %v\n", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
res[i] = RTCDtlsFingerprint{
|
res[i] = DTLSFingerprint{
|
||||||
Algorithm: algo.String(),
|
Algorithm: algo.String(),
|
||||||
Value: value,
|
Value: value,
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ func (c RTCCertificate) GetFingerprints() []RTCDtlsFingerprint {
|
|||||||
|
|
||||||
// GenerateCertificate causes the creation of an X.509 certificate and
|
// GenerateCertificate causes the creation of an X.509 certificate and
|
||||||
// corresponding private key.
|
// corresponding private key.
|
||||||
func GenerateCertificate(secretKey crypto.PrivateKey) (*RTCCertificate, error) {
|
func GenerateCertificate(secretKey crypto.PrivateKey) (*Certificate, error) {
|
||||||
origin := make([]byte, 16)
|
origin := make([]byte, 16)
|
||||||
/* #nosec */
|
/* #nosec */
|
||||||
if _, err := rand.Read(origin); err != nil {
|
if _, err := rand.Read(origin); err != nil {
|
||||||
@@ -131,7 +131,7 @@ func GenerateCertificate(secretKey crypto.PrivateKey) (*RTCCertificate, error) {
|
|||||||
return nil, &rtcerr.UnknownError{Err: err}
|
return nil, &rtcerr.UnknownError{Err: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewRTCCertificate(secretKey, x509.Certificate{
|
return NewCertificate(secretKey, x509.Certificate{
|
||||||
ExtKeyUsage: []x509.ExtKeyUsage{
|
ExtKeyUsage: []x509.ExtKeyUsage{
|
||||||
x509.ExtKeyUsageClientAuth,
|
x509.ExtKeyUsageClientAuth,
|
||||||
x509.ExtKeyUsageServerAuth,
|
x509.ExtKeyUsageServerAuth,
|
||||||
|
@@ -4,51 +4,51 @@ import (
|
|||||||
"github.com/pions/webrtc/pkg/ice"
|
"github.com/pions/webrtc/pkg/ice"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RTCConfiguration defines a set of parameters to configure how the
|
// Configuration defines a set of parameters to configure how the
|
||||||
// peer-to-peer communication via RTCPeerConnection is established or
|
// peer-to-peer communication via PeerConnection is established or
|
||||||
// re-established.
|
// re-established.
|
||||||
type RTCConfiguration struct {
|
type Configuration struct {
|
||||||
// IceServers defines a slice describing servers available to be used by
|
// ICEServers defines a slice describing servers available to be used by
|
||||||
// ICE, such as STUN and TURN servers.
|
// ICE, such as STUN and TURN servers.
|
||||||
IceServers []RTCIceServer
|
ICEServers []ICEServer
|
||||||
|
|
||||||
// IceTransportPolicy indicates which candidates the IceAgent is allowed
|
// ICETransportPolicy indicates which candidates the ICEAgent is allowed
|
||||||
// to use.
|
// to use.
|
||||||
IceTransportPolicy RTCIceTransportPolicy
|
ICETransportPolicy ICETransportPolicy
|
||||||
|
|
||||||
// BundlePolicy indicates which media-bundling policy to use when gathering
|
// BundlePolicy indicates which media-bundling policy to use when gathering
|
||||||
// ICE candidates.
|
// ICE candidates.
|
||||||
BundlePolicy RTCBundlePolicy
|
BundlePolicy BundlePolicy
|
||||||
|
|
||||||
// RtcpMuxPolicy indicates which rtcp-mux policy to use when gathering ICE
|
// RTCPMuxPolicy indicates which rtcp-mux policy to use when gathering ICE
|
||||||
// candidates.
|
// candidates.
|
||||||
RtcpMuxPolicy RTCRtcpMuxPolicy
|
RTCPMuxPolicy RTCPMuxPolicy
|
||||||
|
|
||||||
// PeerIdentity sets the target peer identity for the RTCPeerConnection.
|
// PeerIdentity sets the target peer identity for the PeerConnection.
|
||||||
// The RTCPeerConnection will not establish a connection to a remote peer
|
// The PeerConnection will not establish a connection to a remote peer
|
||||||
// unless it can be successfully authenticated with the provided name.
|
// unless it can be successfully authenticated with the provided name.
|
||||||
PeerIdentity string
|
PeerIdentity string
|
||||||
|
|
||||||
// Certificates describes a set of certificates that the RTCPeerConnection
|
// Certificates describes a set of certificates that the PeerConnection
|
||||||
// uses to authenticate. Valid values for this parameter are created
|
// uses to authenticate. Valid values for this parameter are created
|
||||||
// through calls to the GenerateCertificate function. Although any given
|
// through calls to the GenerateCertificate function. Although any given
|
||||||
// DTLS connection will use only one certificate, this attribute allows the
|
// DTLS connection will use only one certificate, this attribute allows the
|
||||||
// caller to provide multiple certificates that support different
|
// caller to provide multiple certificates that support different
|
||||||
// algorithms. The final certificate will be selected based on the DTLS
|
// algorithms. The final certificate will be selected based on the DTLS
|
||||||
// handshake, which establishes which certificates are allowed. The
|
// handshake, which establishes which certificates are allowed. The
|
||||||
// RTCPeerConnection implementation selects which of the certificates is
|
// PeerConnection implementation selects which of the certificates is
|
||||||
// used for a given connection; how certificates are selected is outside
|
// used for a given connection; how certificates are selected is outside
|
||||||
// the scope of this specification. If this value is absent, then a default
|
// the scope of this specification. If this value is absent, then a default
|
||||||
// set of certificates is generated for each RTCPeerConnection instance.
|
// set of certificates is generated for each PeerConnection instance.
|
||||||
Certificates []RTCCertificate
|
Certificates []Certificate
|
||||||
|
|
||||||
// IceCandidatePoolSize describes the size of the prefetched ICE pool.
|
// ICECandidatePoolSize describes the size of the prefetched ICE pool.
|
||||||
IceCandidatePoolSize uint8
|
ICECandidatePoolSize uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c RTCConfiguration) getIceServers() (*[]*ice.URL, error) {
|
func (c Configuration) getICEServers() (*[]*ice.URL, error) {
|
||||||
var iceServers []*ice.URL
|
var iceServers []*ice.URL
|
||||||
for _, server := range c.IceServers {
|
for _, server := range c.ICEServers {
|
||||||
for _, rawURL := range server.URLs {
|
for _, rawURL := range server.URLs {
|
||||||
url, err := ice.ParseURL(rawURL)
|
url, err := ice.ParseURL(rawURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -6,33 +6,33 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRTCConfiguration_getIceServers(t *testing.T) {
|
func TestConfiguration_getICEServers(t *testing.T) {
|
||||||
t.Run("Success", func(t *testing.T) {
|
t.Run("Success", func(t *testing.T) {
|
||||||
expectedServerStr := "stun:stun.l.google.com:19302"
|
expectedServerStr := "stun:stun.l.google.com:19302"
|
||||||
cfg := RTCConfiguration{
|
cfg := Configuration{
|
||||||
IceServers: []RTCIceServer{
|
ICEServers: []ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{expectedServerStr},
|
URLs: []string{expectedServerStr},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedURLs, err := cfg.getIceServers()
|
parsedURLs, err := cfg.getICEServers()
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, expectedServerStr, (*parsedURLs)[0].String())
|
assert.Equal(t, expectedServerStr, (*parsedURLs)[0].String())
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Failure", func(t *testing.T) {
|
t.Run("Failure", func(t *testing.T) {
|
||||||
expectedServerStr := "stun.l.google.com:19302"
|
expectedServerStr := "stun.l.google.com:19302"
|
||||||
cfg := RTCConfiguration{
|
cfg := Configuration{
|
||||||
IceServers: []RTCIceServer{
|
ICEServers: []ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{expectedServerStr},
|
URLs: []string{expectedServerStr},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := cfg.getIceServers()
|
_, err := cfg.getICEServers()
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -13,18 +13,18 @@ import (
|
|||||||
|
|
||||||
const dataChannelBufferSize = 16384 // Lowest common denominator among browsers
|
const dataChannelBufferSize = 16384 // Lowest common denominator among browsers
|
||||||
|
|
||||||
// RTCDataChannel represents a WebRTC DataChannel
|
// DataChannel represents a WebRTC DataChannel
|
||||||
// The RTCDataChannel interface represents a network channel
|
// The DataChannel interface represents a network channel
|
||||||
// which can be used for bidirectional peer-to-peer transfers of arbitrary data
|
// which can be used for bidirectional peer-to-peer transfers of arbitrary data
|
||||||
type RTCDataChannel struct {
|
type DataChannel struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
|
||||||
// Label represents a label that can be used to distinguish this
|
// Label represents a label that can be used to distinguish this
|
||||||
// RTCDataChannel object from other RTCDataChannel objects. Scripts are
|
// DataChannel object from other DataChannel objects. Scripts are
|
||||||
// allowed to create multiple RTCDataChannel objects with the same label.
|
// allowed to create multiple DataChannel objects with the same label.
|
||||||
Label string
|
Label string
|
||||||
|
|
||||||
// Ordered represents if the RTCDataChannel is ordered, and false if
|
// Ordered represents if the DataChannel is ordered, and false if
|
||||||
// out-of-order delivery is allowed.
|
// out-of-order delivery is allowed.
|
||||||
Ordered bool
|
Ordered bool
|
||||||
|
|
||||||
@@ -37,14 +37,14 @@ type RTCDataChannel struct {
|
|||||||
MaxRetransmits *uint16
|
MaxRetransmits *uint16
|
||||||
|
|
||||||
// Protocol represents the name of the sub-protocol used with this
|
// Protocol represents the name of the sub-protocol used with this
|
||||||
// RTCDataChannel.
|
// DataChannel.
|
||||||
Protocol string
|
Protocol string
|
||||||
|
|
||||||
// Negotiated represents whether this RTCDataChannel was negotiated by the
|
// Negotiated represents whether this DataChannel was negotiated by the
|
||||||
// application (true), or not (false).
|
// application (true), or not (false).
|
||||||
Negotiated bool
|
Negotiated bool
|
||||||
|
|
||||||
// ID represents the ID for this RTCDataChannel. The value is initially
|
// ID represents the ID for this DataChannel. The value is initially
|
||||||
// null, which is what will be returned if the ID was not provided at
|
// null, which is what will be returned if the ID was not provided at
|
||||||
// channel creation time, and the DTLS role of the SCTP transport has not
|
// channel creation time, and the DTLS role of the SCTP transport has not
|
||||||
// yet been negotiated. Otherwise, it will return the ID that was either
|
// yet been negotiated. Otherwise, it will return the ID that was either
|
||||||
@@ -52,12 +52,12 @@ type RTCDataChannel struct {
|
|||||||
// value, it will not change.
|
// value, it will not change.
|
||||||
ID *uint16
|
ID *uint16
|
||||||
|
|
||||||
// Priority represents the priority for this RTCDataChannel. The priority is
|
// Priority represents the priority for this DataChannel. The priority is
|
||||||
// assigned at channel creation time.
|
// assigned at channel creation time.
|
||||||
Priority RTCPriorityType
|
Priority PriorityType
|
||||||
|
|
||||||
// ReadyState represents the state of the RTCDataChannel object.
|
// ReadyState represents the state of the DataChannel object.
|
||||||
ReadyState RTCDataChannelState
|
ReadyState DataChannelState
|
||||||
|
|
||||||
// BufferedAmount represents the number of bytes of application data
|
// BufferedAmount represents the number of bytes of application data
|
||||||
// (UTF-8 text and binary data) that have been queued using send(). Even
|
// (UTF-8 text and binary data) that have been queued using send(). Even
|
||||||
@@ -75,13 +75,13 @@ type RTCDataChannel struct {
|
|||||||
// bufferedAmount is considered to be low. When the bufferedAmount decreases
|
// bufferedAmount is considered to be low. When the bufferedAmount decreases
|
||||||
// from above this threshold to equal or below it, the bufferedamountlow
|
// from above this threshold to equal or below it, the bufferedamountlow
|
||||||
// event fires. BufferedAmountLowThreshold is initially zero on each new
|
// event fires. BufferedAmountLowThreshold is initially zero on each new
|
||||||
// RTCDataChannel, but the application may change its value at any time.
|
// DataChannel, but the application may change its value at any time.
|
||||||
BufferedAmountLowThreshold uint64
|
BufferedAmountLowThreshold uint64
|
||||||
|
|
||||||
// The binaryType represents attribute MUST, on getting, return the value to
|
// The binaryType represents attribute MUST, on getting, return the value to
|
||||||
// which it was last set. On setting, if the new value is either the string
|
// which it was last set. On setting, if the new value is either the string
|
||||||
// "blob" or the string "arraybuffer", then set the IDL attribute to this
|
// "blob" or the string "arraybuffer", then set the IDL attribute to this
|
||||||
// new value. Otherwise, throw a SyntaxError. When an RTCDataChannel object
|
// new value. Otherwise, throw a SyntaxError. When an DataChannel object
|
||||||
// is created, the binaryType attribute MUST be initialized to the string
|
// is created, the binaryType attribute MUST be initialized to the string
|
||||||
// "blob". This attribute controls how binary data is exposed to scripts.
|
// "blob". This attribute controls how binary data is exposed to scripts.
|
||||||
// binaryType string
|
// binaryType string
|
||||||
@@ -95,18 +95,18 @@ type RTCDataChannel struct {
|
|||||||
onOpenHandler func()
|
onOpenHandler func()
|
||||||
onCloseHandler func()
|
onCloseHandler func()
|
||||||
|
|
||||||
sctpTransport *RTCSctpTransport
|
sctpTransport *SCTPTransport
|
||||||
dataChannel *datachannel.DataChannel
|
dataChannel *datachannel.DataChannel
|
||||||
|
|
||||||
// A reference to the associated api object used by this datachannel
|
// A reference to the associated api object used by this datachannel
|
||||||
api *API
|
api *API
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRTCDataChannel creates a new RTCDataChannel.
|
// NewDataChannel creates a new DataChannel.
|
||||||
// This constructor is part of the ORTC API. It is not
|
// This constructor is part of the ORTC API. It is not
|
||||||
// meant to be used together with the basic WebRTC API.
|
// meant to be used together with the basic WebRTC API.
|
||||||
func (api *API) NewRTCDataChannel(transport *RTCSctpTransport, params *RTCDataChannelParameters) (*RTCDataChannel, error) {
|
func (api *API) NewDataChannel(transport *SCTPTransport, params *DataChannelParameters) (*DataChannel, error) {
|
||||||
d, err := api.newRTCDataChannel(params)
|
d, err := api.newDataChannel(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -119,18 +119,18 @@ func (api *API) NewRTCDataChannel(transport *RTCSctpTransport, params *RTCDataCh
|
|||||||
return d, nil
|
return d, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// newRTCDataChannel is an internal constructor for the data channel used to
|
// newDataChannel is an internal constructor for the data channel used to
|
||||||
// create the RTCDataChannel object before the networking is set up.
|
// create the DataChannel object before the networking is set up.
|
||||||
func (api *API) newRTCDataChannel(params *RTCDataChannelParameters) (*RTCDataChannel, error) {
|
func (api *API) newDataChannel(params *DataChannelParameters) (*DataChannel, error) {
|
||||||
// https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #5)
|
// https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #5)
|
||||||
if len(params.Label) > 65535 {
|
if len(params.Label) > 65535 {
|
||||||
return nil, &rtcerr.TypeError{Err: ErrStringSizeLimit}
|
return nil, &rtcerr.TypeError{Err: ErrStringSizeLimit}
|
||||||
}
|
}
|
||||||
|
|
||||||
d := &RTCDataChannel{
|
d := &DataChannel{
|
||||||
Label: params.Label,
|
Label: params.Label,
|
||||||
ID: ¶ms.ID,
|
ID: ¶ms.ID,
|
||||||
ReadyState: RTCDataChannelStateConnecting,
|
ReadyState: DataChannelStateConnecting,
|
||||||
api: api,
|
api: api,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +138,7 @@ func (api *API) newRTCDataChannel(params *RTCDataChannelParameters) (*RTCDataCha
|
|||||||
}
|
}
|
||||||
|
|
||||||
// open opens the datachannel over the sctp transport
|
// open opens the datachannel over the sctp transport
|
||||||
func (d *RTCDataChannel) open(sctpTransport *RTCSctpTransport) error {
|
func (d *DataChannel) open(sctpTransport *SCTPTransport) error {
|
||||||
d.mu.RLock()
|
d.mu.RLock()
|
||||||
d.sctpTransport = sctpTransport
|
d.sctpTransport = sctpTransport
|
||||||
|
|
||||||
@@ -160,14 +160,14 @@ func (d *RTCDataChannel) open(sctpTransport *RTCSctpTransport) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
d.ReadyState = RTCDataChannelStateOpen
|
d.ReadyState = DataChannelStateOpen
|
||||||
d.mu.RUnlock()
|
d.mu.RUnlock()
|
||||||
|
|
||||||
d.handleOpen(dc)
|
d.handleOpen(dc)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *RTCDataChannel) ensureSCTP() error {
|
func (d *DataChannel) ensureSCTP() error {
|
||||||
if d.sctpTransport == nil ||
|
if d.sctpTransport == nil ||
|
||||||
d.sctpTransport.association == nil {
|
d.sctpTransport.association == nil {
|
||||||
return errors.New("SCTP not establisched")
|
return errors.New("SCTP not establisched")
|
||||||
@@ -175,8 +175,8 @@ func (d *RTCDataChannel) ensureSCTP() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transport returns the RTCSctpTransport instance the RTCDataChannel is sending over.
|
// Transport returns the SCTPTransport instance the DataChannel is sending over.
|
||||||
func (d *RTCDataChannel) Transport() *RTCSctpTransport {
|
func (d *DataChannel) Transport() *SCTPTransport {
|
||||||
d.mu.RLock()
|
d.mu.RLock()
|
||||||
defer d.mu.RUnlock()
|
defer d.mu.RUnlock()
|
||||||
|
|
||||||
@@ -185,13 +185,13 @@ func (d *RTCDataChannel) Transport() *RTCSctpTransport {
|
|||||||
|
|
||||||
// OnOpen sets an event handler which is invoked when
|
// OnOpen sets an event handler which is invoked when
|
||||||
// the underlying data transport has been established (or re-established).
|
// the underlying data transport has been established (or re-established).
|
||||||
func (d *RTCDataChannel) OnOpen(f func()) {
|
func (d *DataChannel) OnOpen(f func()) {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
d.onOpenHandler = f
|
d.onOpenHandler = f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *RTCDataChannel) onOpen() (done chan struct{}) {
|
func (d *DataChannel) onOpen() (done chan struct{}) {
|
||||||
d.mu.RLock()
|
d.mu.RLock()
|
||||||
hdlr := d.onOpenHandler
|
hdlr := d.onOpenHandler
|
||||||
d.mu.RUnlock()
|
d.mu.RUnlock()
|
||||||
@@ -212,13 +212,13 @@ func (d *RTCDataChannel) onOpen() (done chan struct{}) {
|
|||||||
|
|
||||||
// OnClose sets an event handler which is invoked when
|
// OnClose sets an event handler which is invoked when
|
||||||
// the underlying data transport has been closed.
|
// the underlying data transport has been closed.
|
||||||
func (d *RTCDataChannel) OnClose(f func()) {
|
func (d *DataChannel) OnClose(f func()) {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
d.onCloseHandler = f
|
d.onCloseHandler = f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *RTCDataChannel) onClose() (done chan struct{}) {
|
func (d *DataChannel) onClose() (done chan struct{}) {
|
||||||
d.mu.RLock()
|
d.mu.RLock()
|
||||||
hdlr := d.onCloseHandler
|
hdlr := d.onCloseHandler
|
||||||
d.mu.RUnlock()
|
d.mu.RUnlock()
|
||||||
@@ -243,13 +243,13 @@ func (d *RTCDataChannel) onClose() (done chan struct{}) {
|
|||||||
// in size. Check out the detach API if you want to use larger
|
// in size. Check out the detach API if you want to use larger
|
||||||
// message sizes. Note that browser support for larger messages
|
// message sizes. Note that browser support for larger messages
|
||||||
// is also limited.
|
// is also limited.
|
||||||
func (d *RTCDataChannel) OnMessage(f func(p sugar.Payload)) {
|
func (d *DataChannel) OnMessage(f func(p sugar.Payload)) {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
d.onMessageHandler = f
|
d.onMessageHandler = f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *RTCDataChannel) onMessage(p sugar.Payload) {
|
func (d *DataChannel) onMessage(p sugar.Payload) {
|
||||||
d.mu.RLock()
|
d.mu.RLock()
|
||||||
hdlr := d.onMessageHandler
|
hdlr := d.onMessageHandler
|
||||||
d.mu.RUnlock()
|
d.mu.RUnlock()
|
||||||
@@ -264,11 +264,11 @@ func (d *RTCDataChannel) onMessage(p sugar.Payload) {
|
|||||||
// arrival over the sctp transport from a remote peer.
|
// arrival over the sctp transport from a remote peer.
|
||||||
//
|
//
|
||||||
// Deprecated: use OnMessage instead.
|
// Deprecated: use OnMessage instead.
|
||||||
func (d *RTCDataChannel) Onmessage(f func(p sugar.Payload)) {
|
func (d *DataChannel) Onmessage(f func(p sugar.Payload)) {
|
||||||
d.OnMessage(f)
|
d.OnMessage(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *RTCDataChannel) handleOpen(dc *datachannel.DataChannel) {
|
func (d *DataChannel) handleOpen(dc *datachannel.DataChannel) {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
d.dataChannel = dc
|
d.dataChannel = dc
|
||||||
d.mu.Unlock()
|
d.mu.Unlock()
|
||||||
@@ -283,7 +283,7 @@ func (d *RTCDataChannel) handleOpen(dc *datachannel.DataChannel) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *RTCDataChannel) readLoop() {
|
func (d *DataChannel) readLoop() {
|
||||||
for {
|
for {
|
||||||
buffer := make([]byte, dataChannelBufferSize)
|
buffer := make([]byte, dataChannelBufferSize)
|
||||||
n, isString, err := d.dataChannel.ReadDataChannel(buffer)
|
n, isString, err := d.dataChannel.ReadDataChannel(buffer)
|
||||||
@@ -293,7 +293,7 @@ func (d *RTCDataChannel) readLoop() {
|
|||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
d.ReadyState = RTCDataChannelStateClosed
|
d.ReadyState = DataChannelStateClosed
|
||||||
d.mu.Unlock()
|
d.mu.Unlock()
|
||||||
if err != io.EOF {
|
if err != io.EOF {
|
||||||
// TODO: Throw OnError
|
// TODO: Throw OnError
|
||||||
@@ -312,7 +312,7 @@ func (d *RTCDataChannel) readLoop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send sends the passed message to the DataChannel peer
|
// Send sends the passed message to the DataChannel peer
|
||||||
func (d *RTCDataChannel) Send(payload sugar.Payload) error {
|
func (d *DataChannel) Send(payload sugar.Payload) error {
|
||||||
err := d.ensureOpen()
|
err := d.ensureOpen()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -339,10 +339,10 @@ func (d *RTCDataChannel) Send(payload sugar.Payload) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *RTCDataChannel) ensureOpen() error {
|
func (d *DataChannel) ensureOpen() error {
|
||||||
d.mu.RLock()
|
d.mu.RLock()
|
||||||
defer d.mu.RUnlock()
|
defer d.mu.RUnlock()
|
||||||
if d.ReadyState != RTCDataChannelStateOpen {
|
if d.ReadyState != DataChannelStateOpen {
|
||||||
return &rtcerr.InvalidStateError{Err: ErrDataChannelNotOpen}
|
return &rtcerr.InvalidStateError{Err: ErrDataChannelNotOpen}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -356,7 +356,7 @@ func (d *RTCDataChannel) ensureOpen() error {
|
|||||||
// Please reffer to the data-channels-detach example and the
|
// Please reffer to the data-channels-detach example and the
|
||||||
// pions/datachannel documentation for the correct way to handle the
|
// pions/datachannel documentation for the correct way to handle the
|
||||||
// resulting DataChannel object.
|
// resulting DataChannel object.
|
||||||
func (d *RTCDataChannel) Detach() (*datachannel.DataChannel, error) {
|
func (d *DataChannel) Detach() (*datachannel.DataChannel, error) {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
|
|
||||||
@@ -371,18 +371,18 @@ func (d *RTCDataChannel) Detach() (*datachannel.DataChannel, error) {
|
|||||||
return d.dataChannel, nil
|
return d.dataChannel, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close Closes the RTCDataChannel. It may be called regardless of whether
|
// Close Closes the DataChannel. It may be called regardless of whether
|
||||||
// the RTCDataChannel object was created by this peer or the remote peer.
|
// the DataChannel object was created by this peer or the remote peer.
|
||||||
func (d *RTCDataChannel) Close() error {
|
func (d *DataChannel) Close() error {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
|
|
||||||
if d.ReadyState == RTCDataChannelStateClosing ||
|
if d.ReadyState == DataChannelStateClosing ||
|
||||||
d.ReadyState == RTCDataChannelStateClosed {
|
d.ReadyState == DataChannelStateClosed {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
d.ReadyState = RTCDataChannelStateClosing
|
d.ReadyState = DataChannelStateClosing
|
||||||
|
|
||||||
return d.dataChannel.Close()
|
return d.dataChannel.Close()
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,7 @@ import (
|
|||||||
"github.com/pions/webrtc/pkg/datachannel"
|
"github.com/pions/webrtc/pkg/datachannel"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRTCDataChannel_ORTCE2E(t *testing.T) {
|
func TestDataChannel_ORTCE2E(t *testing.T) {
|
||||||
// Limit runtime in case of deadlocks
|
// Limit runtime in case of deadlocks
|
||||||
lim := test.TimeOut(time.Second * 20)
|
lim := test.TimeOut(time.Second * 20)
|
||||||
defer lim.Stop()
|
defer lim.Stop()
|
||||||
@@ -24,7 +24,7 @@ func TestRTCDataChannel_ORTCE2E(t *testing.T) {
|
|||||||
awaitSetup := make(chan struct{})
|
awaitSetup := make(chan struct{})
|
||||||
awaitString := make(chan struct{})
|
awaitString := make(chan struct{})
|
||||||
awaitBinary := make(chan struct{})
|
awaitBinary := make(chan struct{})
|
||||||
stackB.sctp.OnDataChannel(func(d *RTCDataChannel) {
|
stackB.sctp.OnDataChannel(func(d *DataChannel) {
|
||||||
close(awaitSetup)
|
close(awaitSetup)
|
||||||
d.OnMessage(func(payload datachannel.Payload) {
|
d.OnMessage(func(payload datachannel.Payload) {
|
||||||
switch payload.(type) {
|
switch payload.(type) {
|
||||||
@@ -41,11 +41,11 @@ func TestRTCDataChannel_ORTCE2E(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
dcParams := &RTCDataChannelParameters{
|
dcParams := &DataChannelParameters{
|
||||||
Label: "Foo",
|
Label: "Foo",
|
||||||
ID: 1,
|
ID: 1,
|
||||||
}
|
}
|
||||||
channelA, err := stackA.api.NewRTCDataChannel(stackA.sctp, dcParams)
|
channelA, err := stackA.api.NewDataChannel(stackA.sctp, dcParams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -76,16 +76,16 @@ func TestRTCDataChannel_ORTCE2E(t *testing.T) {
|
|||||||
|
|
||||||
type testORTCStack struct {
|
type testORTCStack struct {
|
||||||
api *API
|
api *API
|
||||||
gatherer *RTCIceGatherer
|
gatherer *ICEGatherer
|
||||||
ice *RTCIceTransport
|
ice *ICETransport
|
||||||
dtls *RTCDtlsTransport
|
dtls *DTLSTransport
|
||||||
sctp *RTCSctpTransport
|
sctp *SCTPTransport
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *testORTCStack) setSignal(sig *testORTCSignal, isOffer bool) error {
|
func (s *testORTCStack) setSignal(sig *testORTCSignal, isOffer bool) error {
|
||||||
iceRole := RTCIceRoleControlled
|
iceRole := ICERoleControlled
|
||||||
if isOffer {
|
if isOffer {
|
||||||
iceRole = RTCIceRoleControlling
|
iceRole = ICERoleControlling
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.ice.SetRemoteCandidates(sig.ICECandidates)
|
err := s.ice.SetRemoteCandidates(sig.ICECandidates)
|
||||||
@@ -100,7 +100,7 @@ func (s *testORTCStack) setSignal(sig *testORTCSignal, isOffer bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start the DTLS transport
|
// Start the DTLS transport
|
||||||
err = s.dtls.Start(sig.DtlsParameters)
|
err = s.dtls.Start(sig.DTLSParameters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,7 @@ func (s *testORTCStack) getSignal() (*testORTCSignal, error) {
|
|||||||
return &testORTCSignal{
|
return &testORTCSignal{
|
||||||
ICECandidates: iceCandidates,
|
ICECandidates: iceCandidates,
|
||||||
ICEParameters: iceParams,
|
ICEParameters: iceParams,
|
||||||
DtlsParameters: dtlsParams,
|
DTLSParameters: dtlsParams,
|
||||||
SCTPCapabilities: sctpCapabilities,
|
SCTPCapabilities: sctpCapabilities,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@@ -158,10 +158,10 @@ func (s *testORTCStack) close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type testORTCSignal struct {
|
type testORTCSignal struct {
|
||||||
ICECandidates []RTCIceCandidate `json:"iceCandidates"`
|
ICECandidates []ICECandidate `json:"iceCandidates"`
|
||||||
ICEParameters RTCIceParameters `json:"iceParameters"`
|
ICEParameters ICEParameters `json:"iceParameters"`
|
||||||
DtlsParameters RTCDtlsParameters `json:"dtlsParameters"`
|
DTLSParameters DTLSParameters `json:"dtlsParameters"`
|
||||||
SCTPCapabilities RTCSctpCapabilities `json:"sctpCapabilities"`
|
SCTPCapabilities SCTPCapabilities `json:"sctpCapabilities"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func newORTCPair() (stackA *testORTCStack, stackB *testORTCStack, err error) {
|
func newORTCPair() (stackA *testORTCStack, stackB *testORTCStack, err error) {
|
||||||
@@ -183,22 +183,22 @@ func newORTCStack() (*testORTCStack, error) {
|
|||||||
api := NewAPI()
|
api := NewAPI()
|
||||||
|
|
||||||
// Create the ICE gatherer
|
// Create the ICE gatherer
|
||||||
gatherer, err := api.NewRTCIceGatherer(RTCIceGatherOptions{})
|
gatherer, err := api.NewICEGatherer(ICEGatherOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct the ICE transport
|
// Construct the ICE transport
|
||||||
ice := api.NewRTCIceTransport(gatherer)
|
ice := api.NewICETransport(gatherer)
|
||||||
|
|
||||||
// Construct the DTLS transport
|
// Construct the DTLS transport
|
||||||
dtls, err := api.NewRTCDtlsTransport(ice, nil)
|
dtls, err := api.NewDTLSTransport(ice, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct the SCTP transport
|
// Construct the SCTP transport
|
||||||
sctp := api.NewRTCSctpTransport(dtls)
|
sctp := api.NewSCTPTransport(dtls)
|
||||||
|
|
||||||
return &testORTCStack{
|
return &testORTCStack{
|
||||||
api: api,
|
api: api,
|
||||||
|
@@ -18,19 +18,19 @@ func TestGenerateDataChannelID(t *testing.T) {
|
|||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
client bool
|
client bool
|
||||||
c *RTCPeerConnection
|
c *PeerConnection
|
||||||
result uint16
|
result uint16
|
||||||
}{
|
}{
|
||||||
{true, &RTCPeerConnection{sctpTransport: api.NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{}, api: api}, 0},
|
{true, &PeerConnection{sctpTransport: api.NewSCTPTransport(nil), dataChannels: map[uint16]*DataChannel{}, api: api}, 0},
|
||||||
{true, &RTCPeerConnection{sctpTransport: api.NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{1: nil}, api: api}, 0},
|
{true, &PeerConnection{sctpTransport: api.NewSCTPTransport(nil), dataChannels: map[uint16]*DataChannel{1: nil}, api: api}, 0},
|
||||||
{true, &RTCPeerConnection{sctpTransport: api.NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{0: nil}, api: api}, 2},
|
{true, &PeerConnection{sctpTransport: api.NewSCTPTransport(nil), dataChannels: map[uint16]*DataChannel{0: nil}, api: api}, 2},
|
||||||
{true, &RTCPeerConnection{sctpTransport: api.NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{0: nil, 2: nil}, api: api}, 4},
|
{true, &PeerConnection{sctpTransport: api.NewSCTPTransport(nil), dataChannels: map[uint16]*DataChannel{0: nil, 2: nil}, api: api}, 4},
|
||||||
{true, &RTCPeerConnection{sctpTransport: api.NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{0: nil, 4: nil}, api: api}, 2},
|
{true, &PeerConnection{sctpTransport: api.NewSCTPTransport(nil), dataChannels: map[uint16]*DataChannel{0: nil, 4: nil}, api: api}, 2},
|
||||||
{false, &RTCPeerConnection{sctpTransport: api.NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{}, api: api}, 1},
|
{false, &PeerConnection{sctpTransport: api.NewSCTPTransport(nil), dataChannels: map[uint16]*DataChannel{}, api: api}, 1},
|
||||||
{false, &RTCPeerConnection{sctpTransport: api.NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{0: nil}, api: api}, 1},
|
{false, &PeerConnection{sctpTransport: api.NewSCTPTransport(nil), dataChannels: map[uint16]*DataChannel{0: nil}, api: api}, 1},
|
||||||
{false, &RTCPeerConnection{sctpTransport: api.NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{1: nil}, api: api}, 3},
|
{false, &PeerConnection{sctpTransport: api.NewSCTPTransport(nil), dataChannels: map[uint16]*DataChannel{1: nil}, api: api}, 3},
|
||||||
{false, &RTCPeerConnection{sctpTransport: api.NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{1: nil, 3: nil}, api: api}, 5},
|
{false, &PeerConnection{sctpTransport: api.NewSCTPTransport(nil), dataChannels: map[uint16]*DataChannel{1: nil, 3: nil}, api: api}, 5},
|
||||||
{false, &RTCPeerConnection{sctpTransport: api.NewRTCSctpTransport(nil), dataChannels: map[uint16]*RTCDataChannel{1: nil, 5: nil}, api: api}, 3},
|
{false, &PeerConnection{sctpTransport: api.NewSCTPTransport(nil), dataChannels: map[uint16]*DataChannel{1: nil, 5: nil}, api: api}, 3},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
@@ -45,7 +45,7 @@ func TestGenerateDataChannelID(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCDataChannel_Send(t *testing.T) {
|
func TestDataChannel_Send(t *testing.T) {
|
||||||
report := test.CheckRoutines(t)
|
report := test.CheckRoutines(t)
|
||||||
defer report()
|
defer report()
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ func TestRTCDataChannel_Send(t *testing.T) {
|
|||||||
done <- true
|
done <- true
|
||||||
})
|
})
|
||||||
|
|
||||||
answerPC.OnDataChannel(func(d *RTCDataChannel) {
|
answerPC.OnDataChannel(func(d *DataChannel) {
|
||||||
d.OnMessage(func(payload sugar.Payload) {
|
d.OnMessage(func(payload sugar.Payload) {
|
||||||
e := d.Send(sugar.PayloadBinary{Data: []byte("Pong")})
|
e := d.Send(sugar.PayloadBinary{Data: []byte("Pong")})
|
||||||
if e != nil {
|
if e != nil {
|
||||||
@@ -104,7 +104,7 @@ func TestRTCDataChannel_Send(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCDataChannel_EventHandlers(t *testing.T) {
|
func TestDataChannel_EventHandlers(t *testing.T) {
|
||||||
to := test.TimeOut(time.Second * 20)
|
to := test.TimeOut(time.Second * 20)
|
||||||
defer to.Stop()
|
defer to.Stop()
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ func TestRTCDataChannel_EventHandlers(t *testing.T) {
|
|||||||
defer report()
|
defer report()
|
||||||
|
|
||||||
api := NewAPI()
|
api := NewAPI()
|
||||||
dc := &RTCDataChannel{api: api}
|
dc := &DataChannel{api: api}
|
||||||
|
|
||||||
onOpenCalled := make(chan bool)
|
onOpenCalled := make(chan bool)
|
||||||
onMessageCalled := make(chan bool)
|
onMessageCalled := make(chan bool)
|
||||||
@@ -153,12 +153,12 @@ func TestRTCDataChannel_EventHandlers(t *testing.T) {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCDataChannel_MessagesAreOrdered(t *testing.T) {
|
func TestDataChannel_MessagesAreOrdered(t *testing.T) {
|
||||||
report := test.CheckRoutines(t)
|
report := test.CheckRoutines(t)
|
||||||
defer report()
|
defer report()
|
||||||
|
|
||||||
api := NewAPI()
|
api := NewAPI()
|
||||||
dc := &RTCDataChannel{api: api}
|
dc := &DataChannel{api: api}
|
||||||
|
|
||||||
max := 512
|
max := 512
|
||||||
out := make(chan int)
|
out := make(chan int)
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCDataChannelInit can be used to configure properties of the underlying
|
// DataChannelInit can be used to configure properties of the underlying
|
||||||
// channel such as data reliability.
|
// channel such as data reliability.
|
||||||
type RTCDataChannelInit struct {
|
type DataChannelInit struct {
|
||||||
// Ordered indicates if data is allowed to be delivered out of order. The
|
// Ordered indicates if data is allowed to be delivered out of order. The
|
||||||
// default value of true, guarantees that data will be delivered in order.
|
// default value of true, guarantees that data will be delivered in order.
|
||||||
Ordered *bool
|
Ordered *bool
|
||||||
@@ -23,8 +23,8 @@ type RTCDataChannelInit struct {
|
|||||||
// Negotiated describes if the data channel is created by the local peer or
|
// Negotiated describes if the data channel is created by the local peer or
|
||||||
// the remote peer. The default value of false tells the user agent to
|
// the remote peer. The default value of false tells the user agent to
|
||||||
// announce the channel in-band and instruct the other peer to dispatch a
|
// announce the channel in-band and instruct the other peer to dispatch a
|
||||||
// corresponding RTCDataChannel. If set to true, it is up to the application
|
// corresponding DataChannel. If set to true, it is up to the application
|
||||||
// to negotiate the channel and create an RTCDataChannel with the same id
|
// to negotiate the channel and create an DataChannel with the same id
|
||||||
// at the other peer.
|
// at the other peer.
|
||||||
Negotiated *bool
|
Negotiated *bool
|
||||||
|
|
||||||
@@ -32,5 +32,5 @@ type RTCDataChannelInit struct {
|
|||||||
ID *uint16
|
ID *uint16
|
||||||
|
|
||||||
// Priority describes the priority of this channel.
|
// Priority describes the priority of this channel.
|
||||||
Priority *RTCPriorityType
|
Priority *PriorityType
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCDataChannelParameters describes the configuration of the RTCDataChannel.
|
// DataChannelParameters describes the configuration of the DataChannel.
|
||||||
type RTCDataChannelParameters struct {
|
type DataChannelParameters struct {
|
||||||
Label string `json:"label"`
|
Label string `json:"label"`
|
||||||
ID uint16 `json:"id"`
|
ID uint16 `json:"id"`
|
||||||
}
|
}
|
||||||
|
@@ -1,60 +1,60 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCDataChannelState indicates the state of a data channel.
|
// DataChannelState indicates the state of a data channel.
|
||||||
type RTCDataChannelState int
|
type DataChannelState int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCDataChannelStateConnecting indicates that the data channel is being
|
// DataChannelStateConnecting indicates that the data channel is being
|
||||||
// established. This is the initial state of RTCDataChannel, whether created
|
// established. This is the initial state of DataChannel, whether created
|
||||||
// with CreateDataChannel, or dispatched as a part of an RTCDataChannelEvent.
|
// with CreateDataChannel, or dispatched as a part of an DataChannelEvent.
|
||||||
RTCDataChannelStateConnecting RTCDataChannelState = iota + 1
|
DataChannelStateConnecting DataChannelState = iota + 1
|
||||||
|
|
||||||
// RTCDataChannelStateOpen indicates that the underlying data transport is
|
// DataChannelStateOpen indicates that the underlying data transport is
|
||||||
// established and communication is possible.
|
// established and communication is possible.
|
||||||
RTCDataChannelStateOpen
|
DataChannelStateOpen
|
||||||
|
|
||||||
// RTCDataChannelStateClosing indicates that the procedure to close down the
|
// DataChannelStateClosing indicates that the procedure to close down the
|
||||||
// underlying data transport has started.
|
// underlying data transport has started.
|
||||||
RTCDataChannelStateClosing
|
DataChannelStateClosing
|
||||||
|
|
||||||
// RTCDataChannelStateClosed indicates that the underlying data transport
|
// DataChannelStateClosed indicates that the underlying data transport
|
||||||
// has been closed or could not be established.
|
// has been closed or could not be established.
|
||||||
RTCDataChannelStateClosed
|
DataChannelStateClosed
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is done this way because of a linter.
|
// This is done this way because of a linter.
|
||||||
const (
|
const (
|
||||||
rtcDataChannelStateConnectingStr = "connecting"
|
dataChannelStateConnectingStr = "connecting"
|
||||||
rtcDataChannelStateOpenStr = "open"
|
dataChannelStateOpenStr = "open"
|
||||||
rtcDataChannelStateClosingStr = "closing"
|
dataChannelStateClosingStr = "closing"
|
||||||
rtcDataChannelStateClosedStr = "closed"
|
dataChannelStateClosedStr = "closed"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRTCDataChannelState(raw string) RTCDataChannelState {
|
func newDataChannelState(raw string) DataChannelState {
|
||||||
switch raw {
|
switch raw {
|
||||||
case rtcDataChannelStateConnectingStr:
|
case dataChannelStateConnectingStr:
|
||||||
return RTCDataChannelStateConnecting
|
return DataChannelStateConnecting
|
||||||
case rtcDataChannelStateOpenStr:
|
case dataChannelStateOpenStr:
|
||||||
return RTCDataChannelStateOpen
|
return DataChannelStateOpen
|
||||||
case rtcDataChannelStateClosingStr:
|
case dataChannelStateClosingStr:
|
||||||
return RTCDataChannelStateClosing
|
return DataChannelStateClosing
|
||||||
case rtcDataChannelStateClosedStr:
|
case dataChannelStateClosedStr:
|
||||||
return RTCDataChannelStateClosed
|
return DataChannelStateClosed
|
||||||
default:
|
default:
|
||||||
return RTCDataChannelState(Unknown)
|
return DataChannelState(Unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t RTCDataChannelState) String() string {
|
func (t DataChannelState) String() string {
|
||||||
switch t {
|
switch t {
|
||||||
case RTCDataChannelStateConnecting:
|
case DataChannelStateConnecting:
|
||||||
return rtcDataChannelStateConnectingStr
|
return dataChannelStateConnectingStr
|
||||||
case RTCDataChannelStateOpen:
|
case DataChannelStateOpen:
|
||||||
return rtcDataChannelStateOpenStr
|
return dataChannelStateOpenStr
|
||||||
case RTCDataChannelStateClosing:
|
case DataChannelStateClosing:
|
||||||
return rtcDataChannelStateClosingStr
|
return dataChannelStateClosingStr
|
||||||
case RTCDataChannelStateClosed:
|
case DataChannelStateClosed:
|
||||||
return rtcDataChannelStateClosedStr
|
return dataChannelStateClosedStr
|
||||||
default:
|
default:
|
||||||
return ErrUnknownType.Error()
|
return ErrUnknownType.Error()
|
||||||
}
|
}
|
||||||
|
@@ -6,37 +6,37 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewRTCDataChannelState(t *testing.T) {
|
func TestNewDataChannelState(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
stateString string
|
stateString string
|
||||||
expectedState RTCDataChannelState
|
expectedState DataChannelState
|
||||||
}{
|
}{
|
||||||
{unknownStr, RTCDataChannelState(Unknown)},
|
{unknownStr, DataChannelState(Unknown)},
|
||||||
{"connecting", RTCDataChannelStateConnecting},
|
{"connecting", DataChannelStateConnecting},
|
||||||
{"open", RTCDataChannelStateOpen},
|
{"open", DataChannelStateOpen},
|
||||||
{"closing", RTCDataChannelStateClosing},
|
{"closing", DataChannelStateClosing},
|
||||||
{"closed", RTCDataChannelStateClosed},
|
{"closed", DataChannelStateClosed},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
testCase.expectedState,
|
testCase.expectedState,
|
||||||
newRTCDataChannelState(testCase.stateString),
|
newDataChannelState(testCase.stateString),
|
||||||
"testCase: %d %v", i, testCase,
|
"testCase: %d %v", i, testCase,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCDataChannelState_String(t *testing.T) {
|
func TestDataChannelState_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
state RTCDataChannelState
|
state DataChannelState
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCDataChannelState(Unknown), unknownStr},
|
{DataChannelState(Unknown), unknownStr},
|
||||||
{RTCDataChannelStateConnecting, "connecting"},
|
{DataChannelStateConnecting, "connecting"},
|
||||||
{RTCDataChannelStateOpen, "open"},
|
{DataChannelStateOpen, "open"},
|
||||||
{RTCDataChannelStateClosing, "closing"},
|
{DataChannelStateClosing, "closing"},
|
||||||
{RTCDataChannelStateClosed, "closed"},
|
{DataChannelStateClosed, "closed"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCDtlsFingerprint specifies the hash function algorithm and certificate
|
// DTLSFingerprint specifies the hash function algorithm and certificate
|
||||||
// fingerprint as described in https://tools.ietf.org/html/rfc4572.
|
// fingerprint as described in https://tools.ietf.org/html/rfc4572.
|
||||||
type RTCDtlsFingerprint struct {
|
type DTLSFingerprint struct {
|
||||||
// Algorithm specifies one of the the hash function algorithms defined in
|
// Algorithm specifies one of the the hash function algorithms defined in
|
||||||
// the 'Hash function Textual Names' registry.
|
// the 'Hash function Textual Names' registry.
|
||||||
Algorithm string `json:"algorithm"`
|
Algorithm string `json:"algorithm"`
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCDtlsParameters holds information relating to DTLS configuration.
|
// DTLSParameters holds information relating to DTLS configuration.
|
||||||
type RTCDtlsParameters struct {
|
type DTLSParameters struct {
|
||||||
Role RTCDtlsRole `json:"role"`
|
Role DTLSRole `json:"role"`
|
||||||
Fingerprints []RTCDtlsFingerprint `json:"fingerprints"`
|
Fingerprints []DTLSFingerprint `json:"fingerprints"`
|
||||||
}
|
}
|
||||||
|
@@ -1,28 +1,28 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCDtlsRole indicates the role of the DTLS transport.
|
// DTLSRole indicates the role of the DTLS transport.
|
||||||
type RTCDtlsRole byte
|
type DTLSRole byte
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCDtlsRoleAuto defines the DLTS role is determined based on
|
// DTLSRoleAuto defines the DLTS role is determined based on
|
||||||
// the resolved ICE role: the ICE controlled role acts as the DTLS
|
// the resolved ICE role: the ICE controlled role acts as the DTLS
|
||||||
// client and the ICE controlling role acts as the DTLS server.
|
// client and the ICE controlling role acts as the DTLS server.
|
||||||
RTCDtlsRoleAuto RTCDtlsRole = iota + 1
|
DTLSRoleAuto DTLSRole = iota + 1
|
||||||
|
|
||||||
// RTCDtlsRoleClient defines the DTLS client role.
|
// DTLSRoleClient defines the DTLS client role.
|
||||||
RTCDtlsRoleClient
|
DTLSRoleClient
|
||||||
|
|
||||||
// RTCDtlsRoleServer defines the DTLS server role.
|
// DTLSRoleServer defines the DTLS server role.
|
||||||
RTCDtlsRoleServer
|
DTLSRoleServer
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r RTCDtlsRole) String() string {
|
func (r DTLSRole) String() string {
|
||||||
switch r {
|
switch r {
|
||||||
case RTCDtlsRoleAuto:
|
case DTLSRoleAuto:
|
||||||
return "auto"
|
return "auto"
|
||||||
case RTCDtlsRoleClient:
|
case DTLSRoleClient:
|
||||||
return "client"
|
return "client"
|
||||||
case RTCDtlsRoleServer:
|
case DTLSRoleServer:
|
||||||
return "server"
|
return "server"
|
||||||
default:
|
default:
|
||||||
return unknownStr
|
return unknownStr
|
||||||
|
@@ -6,15 +6,15 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRTCDtlsRole_String(t *testing.T) {
|
func TestDTLSRole_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
role RTCDtlsRole
|
role DTLSRole
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCDtlsRole(Unknown), unknownStr},
|
{DTLSRole(Unknown), unknownStr},
|
||||||
{RTCDtlsRoleAuto, "auto"},
|
{DTLSRoleAuto, "auto"},
|
||||||
{RTCDtlsRoleClient, "client"},
|
{DTLSRoleClient, "client"},
|
||||||
{RTCDtlsRoleServer, "server"},
|
{DTLSRoleServer, "server"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@@ -17,17 +17,17 @@ import (
|
|||||||
"github.com/pions/webrtc/pkg/rtcerr"
|
"github.com/pions/webrtc/pkg/rtcerr"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RTCDtlsTransport allows an application access to information about the DTLS
|
// DTLSTransport allows an application access to information about the DTLS
|
||||||
// transport over which RTP and RTCP packets are sent and received by
|
// transport over which RTP and RTCP packets are sent and received by
|
||||||
// RTCRtpSender and RTCRtpReceiver, as well other data such as SCTP packets sent
|
// RTPSender and RTPReceiver, as well other data such as SCTP packets sent
|
||||||
// and received by data channels.
|
// and received by data channels.
|
||||||
type RTCDtlsTransport struct {
|
type DTLSTransport struct {
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
|
|
||||||
iceTransport *RTCIceTransport
|
iceTransport *ICETransport
|
||||||
certificates []RTCCertificate
|
certificates []Certificate
|
||||||
remoteParameters RTCDtlsParameters
|
remoteParameters DTLSParameters
|
||||||
// State RTCDtlsTransportState
|
// State DTLSTransportState
|
||||||
|
|
||||||
// OnStateChange func()
|
// OnStateChange func()
|
||||||
// OnError func()
|
// OnError func()
|
||||||
@@ -40,11 +40,11 @@ type RTCDtlsTransport struct {
|
|||||||
srtcpEndpoint *mux.Endpoint
|
srtcpEndpoint *mux.Endpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRTCDtlsTransport creates a new RTCDtlsTransport.
|
// NewDTLSTransport creates a new DTLSTransport.
|
||||||
// This constructor is part of the ORTC API. It is not
|
// This constructor is part of the ORTC API. It is not
|
||||||
// meant to be used together with the basic WebRTC API.
|
// meant to be used together with the basic WebRTC API.
|
||||||
func (api *API) NewRTCDtlsTransport(transport *RTCIceTransport, certificates []RTCCertificate) (*RTCDtlsTransport, error) {
|
func (api *API) NewDTLSTransport(transport *ICETransport, certificates []Certificate) (*DTLSTransport, error) {
|
||||||
t := &RTCDtlsTransport{iceTransport: transport}
|
t := &DTLSTransport{iceTransport: transport}
|
||||||
|
|
||||||
if len(certificates) > 0 {
|
if len(certificates) > 0 {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
@@ -63,28 +63,28 @@ func (api *API) NewRTCDtlsTransport(transport *RTCIceTransport, certificates []R
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
t.certificates = []RTCCertificate{*certificate}
|
t.certificates = []Certificate{*certificate}
|
||||||
}
|
}
|
||||||
|
|
||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLocalParameters returns the DTLS parameters of the local RTCDtlsTransport upon construction.
|
// GetLocalParameters returns the DTLS parameters of the local DTLSTransport upon construction.
|
||||||
func (t *RTCDtlsTransport) GetLocalParameters() RTCDtlsParameters {
|
func (t *DTLSTransport) GetLocalParameters() DTLSParameters {
|
||||||
fingerprints := []RTCDtlsFingerprint{}
|
fingerprints := []DTLSFingerprint{}
|
||||||
|
|
||||||
for _, c := range t.certificates {
|
for _, c := range t.certificates {
|
||||||
prints := c.GetFingerprints() // TODO: Should be only one?
|
prints := c.GetFingerprints() // TODO: Should be only one?
|
||||||
fingerprints = append(fingerprints, prints...)
|
fingerprints = append(fingerprints, prints...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return RTCDtlsParameters{
|
return DTLSParameters{
|
||||||
Role: RTCDtlsRoleAuto, // always returns the default role
|
Role: DTLSRoleAuto, // always returns the default role
|
||||||
Fingerprints: fingerprints,
|
Fingerprints: fingerprints,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RTCDtlsTransport) startSRTP() error {
|
func (t *DTLSTransport) startSRTP() error {
|
||||||
t.lock.Lock()
|
t.lock.Lock()
|
||||||
defer t.lock.Unlock()
|
defer t.lock.Unlock()
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ func (t *RTCDtlsTransport) startSRTP() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RTCDtlsTransport) getSRTPSession() (*srtp.SessionSRTP, error) {
|
func (t *DTLSTransport) getSRTPSession() (*srtp.SessionSRTP, error) {
|
||||||
t.lock.RLock()
|
t.lock.RLock()
|
||||||
if t.srtpSession != nil {
|
if t.srtpSession != nil {
|
||||||
t.lock.RUnlock()
|
t.lock.RUnlock()
|
||||||
@@ -133,7 +133,7 @@ func (t *RTCDtlsTransport) getSRTPSession() (*srtp.SessionSRTP, error) {
|
|||||||
return t.srtpSession, nil
|
return t.srtpSession, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RTCDtlsTransport) getSRTCPSession() (*srtp.SessionSRTCP, error) {
|
func (t *DTLSTransport) getSRTCPSession() (*srtp.SessionSRTCP, error) {
|
||||||
t.lock.RLock()
|
t.lock.RLock()
|
||||||
if t.srtcpSession != nil {
|
if t.srtcpSession != nil {
|
||||||
t.lock.RUnlock()
|
t.lock.RUnlock()
|
||||||
@@ -148,15 +148,15 @@ func (t *RTCDtlsTransport) getSRTCPSession() (*srtp.SessionSRTCP, error) {
|
|||||||
return t.srtcpSession, nil
|
return t.srtcpSession, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RTCDtlsTransport) isClient() bool {
|
func (t *DTLSTransport) isClient() bool {
|
||||||
isClient := true
|
isClient := true
|
||||||
switch t.remoteParameters.Role {
|
switch t.remoteParameters.Role {
|
||||||
case RTCDtlsRoleClient:
|
case DTLSRoleClient:
|
||||||
isClient = true
|
isClient = true
|
||||||
case RTCDtlsRoleServer:
|
case DTLSRoleServer:
|
||||||
isClient = false
|
isClient = false
|
||||||
default:
|
default:
|
||||||
if t.iceTransport.Role() == RTCIceRoleControlling {
|
if t.iceTransport.Role() == ICERoleControlling {
|
||||||
isClient = false
|
isClient = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,7 +165,7 @@ func (t *RTCDtlsTransport) isClient() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start DTLS transport negotiation with the parameters of the remote DTLS transport
|
// Start DTLS transport negotiation with the parameters of the remote DTLS transport
|
||||||
func (t *RTCDtlsTransport) Start(remoteParameters RTCDtlsParameters) error {
|
func (t *DTLSTransport) Start(remoteParameters DTLSParameters) error {
|
||||||
t.lock.Lock()
|
t.lock.Lock()
|
||||||
defer t.lock.Unlock()
|
defer t.lock.Unlock()
|
||||||
|
|
||||||
@@ -212,8 +212,8 @@ func (t *RTCDtlsTransport) Start(remoteParameters RTCDtlsParameters) error {
|
|||||||
return t.validateFingerPrint(remoteParameters, remoteCert)
|
return t.validateFingerPrint(remoteParameters, remoteCert)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop stops and closes the RTCDtlsTransport object.
|
// Stop stops and closes the DTLSTransport object.
|
||||||
func (t *RTCDtlsTransport) Stop() error {
|
func (t *DTLSTransport) Stop() error {
|
||||||
t.lock.Lock()
|
t.lock.Lock()
|
||||||
defer t.lock.Unlock()
|
defer t.lock.Unlock()
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ func (t *RTCDtlsTransport) Stop() error {
|
|||||||
return flattenErrs(closeErrs)
|
return flattenErrs(closeErrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RTCDtlsTransport) validateFingerPrint(remoteParameters RTCDtlsParameters, remoteCert *x509.Certificate) error {
|
func (t *DTLSTransport) validateFingerPrint(remoteParameters DTLSParameters, remoteCert *x509.Certificate) error {
|
||||||
for _, fp := range remoteParameters.Fingerprints {
|
for _, fp := range remoteParameters.Fingerprints {
|
||||||
hashAlgo, err := dtls.HashAlgorithmString(fp.Algorithm)
|
hashAlgo, err := dtls.HashAlgorithmString(fp.Algorithm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -260,7 +260,7 @@ func (t *RTCDtlsTransport) validateFingerPrint(remoteParameters RTCDtlsParameter
|
|||||||
return errors.New("No matching fingerprint")
|
return errors.New("No matching fingerprint")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RTCDtlsTransport) ensureICEConn() error {
|
func (t *DTLSTransport) ensureICEConn() error {
|
||||||
if t.iceTransport == nil ||
|
if t.iceTransport == nil ||
|
||||||
t.iceTransport.conn == nil ||
|
t.iceTransport.conn == nil ||
|
||||||
t.iceTransport.mux == nil {
|
t.iceTransport.mux == nil {
|
||||||
|
@@ -1,70 +1,70 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCDtlsTransportState indicates the dtsl transport establishment state.
|
// DTLSTransportState indicates the dtsl transport establishment state.
|
||||||
type RTCDtlsTransportState int
|
type DTLSTransportState int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCDtlsTransportStateNew indicates that DTLS has not started negotiating
|
// DTLSTransportStateNew indicates that DTLS has not started negotiating
|
||||||
// yet.
|
// yet.
|
||||||
RTCDtlsTransportStateNew RTCDtlsTransportState = iota + 1
|
DTLSTransportStateNew DTLSTransportState = iota + 1
|
||||||
|
|
||||||
// RTCDtlsTransportStateConnecting indicates that DTLS is in the process of
|
// DTLSTransportStateConnecting indicates that DTLS is in the process of
|
||||||
// negotiating a secure connection and verifying the remote fingerprint.
|
// negotiating a secure connection and verifying the remote fingerprint.
|
||||||
RTCDtlsTransportStateConnecting
|
DTLSTransportStateConnecting
|
||||||
|
|
||||||
// RTCDtlsTransportStateConnected indicates that DTLS has completed
|
// DTLSTransportStateConnected indicates that DTLS has completed
|
||||||
// negotiation of a secure connection and verified the remote fingerprint.
|
// negotiation of a secure connection and verified the remote fingerprint.
|
||||||
RTCDtlsTransportStateConnected
|
DTLSTransportStateConnected
|
||||||
|
|
||||||
// RTCDtlsTransportStateClosed indicates that the transport has been closed
|
// DTLSTransportStateClosed indicates that the transport has been closed
|
||||||
// intentionally as the result of receipt of a close_notify alert, or
|
// intentionally as the result of receipt of a close_notify alert, or
|
||||||
// calling close().
|
// calling close().
|
||||||
RTCDtlsTransportStateClosed
|
DTLSTransportStateClosed
|
||||||
|
|
||||||
// RTCDtlsTransportStateFailed indicates that the transport has failed as
|
// DTLSTransportStateFailed indicates that the transport has failed as
|
||||||
// the result of an error (such as receipt of an error alert or failure to
|
// the result of an error (such as receipt of an error alert or failure to
|
||||||
// validate the remote fingerprint).
|
// validate the remote fingerprint).
|
||||||
RTCDtlsTransportStateFailed
|
DTLSTransportStateFailed
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is done this way because of a linter.
|
// This is done this way because of a linter.
|
||||||
const (
|
const (
|
||||||
rtcDtlsTransportStateNewStr = "new"
|
dtlsTransportStateNewStr = "new"
|
||||||
rtcDtlsTransportStateConnectingStr = "connecting"
|
dtlsTransportStateConnectingStr = "connecting"
|
||||||
rtcDtlsTransportStateConnectedStr = "connected"
|
dtlsTransportStateConnectedStr = "connected"
|
||||||
rtcDtlsTransportStateClosedStr = "closed"
|
dtlsTransportStateClosedStr = "closed"
|
||||||
rtcDtlsTransportStateFailedStr = "failed"
|
dtlsTransportStateFailedStr = "failed"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRTCDtlsTransportState(raw string) RTCDtlsTransportState {
|
func newDTLSTransportState(raw string) DTLSTransportState {
|
||||||
switch raw {
|
switch raw {
|
||||||
case rtcDtlsTransportStateNewStr:
|
case dtlsTransportStateNewStr:
|
||||||
return RTCDtlsTransportStateNew
|
return DTLSTransportStateNew
|
||||||
case rtcDtlsTransportStateConnectingStr:
|
case dtlsTransportStateConnectingStr:
|
||||||
return RTCDtlsTransportStateConnecting
|
return DTLSTransportStateConnecting
|
||||||
case rtcDtlsTransportStateConnectedStr:
|
case dtlsTransportStateConnectedStr:
|
||||||
return RTCDtlsTransportStateConnected
|
return DTLSTransportStateConnected
|
||||||
case rtcDtlsTransportStateClosedStr:
|
case dtlsTransportStateClosedStr:
|
||||||
return RTCDtlsTransportStateClosed
|
return DTLSTransportStateClosed
|
||||||
case rtcDtlsTransportStateFailedStr:
|
case dtlsTransportStateFailedStr:
|
||||||
return RTCDtlsTransportStateFailed
|
return DTLSTransportStateFailed
|
||||||
default:
|
default:
|
||||||
return RTCDtlsTransportState(Unknown)
|
return DTLSTransportState(Unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t RTCDtlsTransportState) String() string {
|
func (t DTLSTransportState) String() string {
|
||||||
switch t {
|
switch t {
|
||||||
case RTCDtlsTransportStateNew:
|
case DTLSTransportStateNew:
|
||||||
return rtcDtlsTransportStateNewStr
|
return dtlsTransportStateNewStr
|
||||||
case RTCDtlsTransportStateConnecting:
|
case DTLSTransportStateConnecting:
|
||||||
return rtcDtlsTransportStateConnectingStr
|
return dtlsTransportStateConnectingStr
|
||||||
case RTCDtlsTransportStateConnected:
|
case DTLSTransportStateConnected:
|
||||||
return rtcDtlsTransportStateConnectedStr
|
return dtlsTransportStateConnectedStr
|
||||||
case RTCDtlsTransportStateClosed:
|
case DTLSTransportStateClosed:
|
||||||
return rtcDtlsTransportStateClosedStr
|
return dtlsTransportStateClosedStr
|
||||||
case RTCDtlsTransportStateFailed:
|
case DTLSTransportStateFailed:
|
||||||
return rtcDtlsTransportStateFailedStr
|
return dtlsTransportStateFailedStr
|
||||||
default:
|
default:
|
||||||
return ErrUnknownType.Error()
|
return ErrUnknownType.Error()
|
||||||
}
|
}
|
||||||
|
@@ -6,39 +6,39 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewRTCDtlsTransportState(t *testing.T) {
|
func TestNewDTLSTransportState(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
stateString string
|
stateString string
|
||||||
expectedState RTCDtlsTransportState
|
expectedState DTLSTransportState
|
||||||
}{
|
}{
|
||||||
{unknownStr, RTCDtlsTransportState(Unknown)},
|
{unknownStr, DTLSTransportState(Unknown)},
|
||||||
{"new", RTCDtlsTransportStateNew},
|
{"new", DTLSTransportStateNew},
|
||||||
{"connecting", RTCDtlsTransportStateConnecting},
|
{"connecting", DTLSTransportStateConnecting},
|
||||||
{"connected", RTCDtlsTransportStateConnected},
|
{"connected", DTLSTransportStateConnected},
|
||||||
{"closed", RTCDtlsTransportStateClosed},
|
{"closed", DTLSTransportStateClosed},
|
||||||
{"failed", RTCDtlsTransportStateFailed},
|
{"failed", DTLSTransportStateFailed},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
testCase.expectedState,
|
testCase.expectedState,
|
||||||
newRTCDtlsTransportState(testCase.stateString),
|
newDTLSTransportState(testCase.stateString),
|
||||||
"testCase: %d %v", i, testCase,
|
"testCase: %d %v", i, testCase,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCDtlsTransportState_String(t *testing.T) {
|
func TestDTLSTransportState_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
state RTCDtlsTransportState
|
state DTLSTransportState
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCDtlsTransportState(Unknown), unknownStr},
|
{DTLSTransportState(Unknown), unknownStr},
|
||||||
{RTCDtlsTransportStateNew, "new"},
|
{DTLSTransportStateNew, "new"},
|
||||||
{RTCDtlsTransportStateConnecting, "connecting"},
|
{DTLSTransportStateConnecting, "connecting"},
|
||||||
{RTCDtlsTransportStateConnected, "connected"},
|
{DTLSTransportStateConnected, "connected"},
|
||||||
{RTCDtlsTransportStateClosed, "closed"},
|
{DTLSTransportStateClosed, "closed"},
|
||||||
{RTCDtlsTransportStateFailed, "failed"},
|
{DTLSTransportStateFailed, "failed"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@@ -9,14 +9,14 @@ import (
|
|||||||
"github.com/pions/webrtc/pkg/ice"
|
"github.com/pions/webrtc/pkg/ice"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RTCIceCandidate represents a ice candidate
|
// ICECandidate represents a ice candidate
|
||||||
type RTCIceCandidate struct {
|
type ICECandidate struct {
|
||||||
Foundation string `json:"foundation"`
|
Foundation string `json:"foundation"`
|
||||||
Priority uint32 `json:"priority"`
|
Priority uint32 `json:"priority"`
|
||||||
IP string `json:"ip"`
|
IP string `json:"ip"`
|
||||||
Protocol RTCIceProtocol `json:"protocol"`
|
Protocol ICEProtocol `json:"protocol"`
|
||||||
Port uint16 `json:"port"`
|
Port uint16 `json:"port"`
|
||||||
Typ RTCIceCandidateType `json:"type"`
|
Typ ICECandidateType `json:"type"`
|
||||||
Component uint16 `json:"component"`
|
Component uint16 `json:"component"`
|
||||||
RelatedAddress string `json:"relatedAddress"`
|
RelatedAddress string `json:"relatedAddress"`
|
||||||
RelatedPort uint16 `json:"relatedPort"`
|
RelatedPort uint16 `json:"relatedPort"`
|
||||||
@@ -24,16 +24,16 @@ type RTCIceCandidate struct {
|
|||||||
|
|
||||||
// Conversion for package sdp
|
// Conversion for package sdp
|
||||||
|
|
||||||
func newRTCIceCandidateFromSDP(c sdp.ICECandidate) (RTCIceCandidate, error) {
|
func newICECandidateFromSDP(c sdp.ICECandidate) (ICECandidate, error) {
|
||||||
typ, err := newRTCIceCandidateType(c.Typ)
|
typ, err := newICECandidateType(c.Typ)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return RTCIceCandidate{}, err
|
return ICECandidate{}, err
|
||||||
}
|
}
|
||||||
protocol, err := newRTCIceProtocol(c.Protocol)
|
protocol, err := newICEProtocol(c.Protocol)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return RTCIceCandidate{}, err
|
return ICECandidate{}, err
|
||||||
}
|
}
|
||||||
return RTCIceCandidate{
|
return ICECandidate{
|
||||||
Foundation: c.Foundation,
|
Foundation: c.Foundation,
|
||||||
Priority: c.Priority,
|
Priority: c.Priority,
|
||||||
IP: c.IP,
|
IP: c.IP,
|
||||||
@@ -46,7 +46,7 @@ func newRTCIceCandidateFromSDP(c sdp.ICECandidate) (RTCIceCandidate, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c RTCIceCandidate) toSDP() sdp.ICECandidate {
|
func (c ICECandidate) toSDP() sdp.ICECandidate {
|
||||||
return sdp.ICECandidate{
|
return sdp.ICECandidate{
|
||||||
Foundation: c.Foundation,
|
Foundation: c.Foundation,
|
||||||
Priority: c.Priority,
|
Priority: c.Priority,
|
||||||
@@ -62,11 +62,11 @@ func (c RTCIceCandidate) toSDP() sdp.ICECandidate {
|
|||||||
|
|
||||||
// Conversion for package ice
|
// Conversion for package ice
|
||||||
|
|
||||||
func newRTCIceCandidatesFromICE(iceCandidates []*ice.Candidate) ([]RTCIceCandidate, error) {
|
func newICECandidatesFromICE(iceCandidates []*ice.Candidate) ([]ICECandidate, error) {
|
||||||
candidates := []RTCIceCandidate{}
|
candidates := []ICECandidate{}
|
||||||
|
|
||||||
for _, i := range iceCandidates {
|
for _, i := range iceCandidates {
|
||||||
c, err := newRTCIceCandidateFromICE(i)
|
c, err := newICECandidateFromICE(i)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -76,17 +76,17 @@ func newRTCIceCandidatesFromICE(iceCandidates []*ice.Candidate) ([]RTCIceCandida
|
|||||||
return candidates, nil
|
return candidates, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRTCIceCandidateFromICE(i *ice.Candidate) (RTCIceCandidate, error) {
|
func newICECandidateFromICE(i *ice.Candidate) (ICECandidate, error) {
|
||||||
typ, err := convertTypeFromICE(i.Type)
|
typ, err := convertTypeFromICE(i.Type)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return RTCIceCandidate{}, err
|
return ICECandidate{}, err
|
||||||
}
|
}
|
||||||
protocol, err := newRTCIceProtocol(i.NetworkType.NetworkShort())
|
protocol, err := newICEProtocol(i.NetworkType.NetworkShort())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return RTCIceCandidate{}, err
|
return ICECandidate{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c := RTCIceCandidate{
|
c := ICECandidate{
|
||||||
Foundation: "foundation",
|
Foundation: "foundation",
|
||||||
Priority: uint32(i.Priority()),
|
Priority: uint32(i.Priority()),
|
||||||
IP: i.IP.String(),
|
IP: i.IP.String(),
|
||||||
@@ -104,22 +104,22 @@ func newRTCIceCandidateFromICE(i *ice.Candidate) (RTCIceCandidate, error) {
|
|||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c RTCIceCandidate) toICE() (*ice.Candidate, error) {
|
func (c ICECandidate) toICE() (*ice.Candidate, error) {
|
||||||
ip := net.ParseIP(c.IP)
|
ip := net.ParseIP(c.IP)
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
return nil, errors.New("Failed to parse IP address")
|
return nil, errors.New("Failed to parse IP address")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch c.Typ {
|
switch c.Typ {
|
||||||
case RTCIceCandidateTypeHost:
|
case ICECandidateTypeHost:
|
||||||
return ice.NewCandidateHost(c.Protocol.String(), ip, int(c.Port), c.Component)
|
return ice.NewCandidateHost(c.Protocol.String(), ip, int(c.Port), c.Component)
|
||||||
case RTCIceCandidateTypeSrflx:
|
case ICECandidateTypeSrflx:
|
||||||
return ice.NewCandidateServerReflexive(c.Protocol.String(), ip, int(c.Port), c.Component,
|
return ice.NewCandidateServerReflexive(c.Protocol.String(), ip, int(c.Port), c.Component,
|
||||||
c.RelatedAddress, int(c.RelatedPort))
|
c.RelatedAddress, int(c.RelatedPort))
|
||||||
case RTCIceCandidateTypePrflx:
|
case ICECandidateTypePrflx:
|
||||||
return ice.NewCandidatePeerReflexive(c.Protocol.String(), ip, int(c.Port), c.Component,
|
return ice.NewCandidatePeerReflexive(c.Protocol.String(), ip, int(c.Port), c.Component,
|
||||||
c.RelatedAddress, int(c.RelatedPort))
|
c.RelatedAddress, int(c.RelatedPort))
|
||||||
case RTCIceCandidateTypeRelay:
|
case ICECandidateTypeRelay:
|
||||||
return ice.NewCandidateRelay(c.Protocol.String(), ip, int(c.Port), c.Component,
|
return ice.NewCandidateRelay(c.Protocol.String(), ip, int(c.Port), c.Component,
|
||||||
c.RelatedAddress, int(c.RelatedPort))
|
c.RelatedAddress, int(c.RelatedPort))
|
||||||
default:
|
default:
|
||||||
@@ -127,17 +127,17 @@ func (c RTCIceCandidate) toICE() (*ice.Candidate, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertTypeFromICE(t ice.CandidateType) (RTCIceCandidateType, error) {
|
func convertTypeFromICE(t ice.CandidateType) (ICECandidateType, error) {
|
||||||
switch t {
|
switch t {
|
||||||
case ice.CandidateTypeHost:
|
case ice.CandidateTypeHost:
|
||||||
return RTCIceCandidateTypeHost, nil
|
return ICECandidateTypeHost, nil
|
||||||
case ice.CandidateTypeServerReflexive:
|
case ice.CandidateTypeServerReflexive:
|
||||||
return RTCIceCandidateTypeSrflx, nil
|
return ICECandidateTypeSrflx, nil
|
||||||
case ice.CandidateTypePeerReflexive:
|
case ice.CandidateTypePeerReflexive:
|
||||||
return RTCIceCandidateTypePrflx, nil
|
return ICECandidateTypePrflx, nil
|
||||||
case ice.CandidateTypeRelay:
|
case ice.CandidateTypeRelay:
|
||||||
return RTCIceCandidateTypeRelay, nil
|
return ICECandidateTypeRelay, nil
|
||||||
default:
|
default:
|
||||||
return RTCIceCandidateType(t), fmt.Errorf("Unknown ICE candidate type: %s", t)
|
return ICECandidateType(t), fmt.Errorf("Unknown ICE candidate type: %s", t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,20 +9,20 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRTCIceCandidate_Convert(t *testing.T) {
|
func TestICECandidate_Convert(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
native RTCIceCandidate
|
native ICECandidate
|
||||||
ice *ice.Candidate
|
ice *ice.Candidate
|
||||||
sdp sdp.ICECandidate
|
sdp sdp.ICECandidate
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
RTCIceCandidate{
|
ICECandidate{
|
||||||
Foundation: "foundation",
|
Foundation: "foundation",
|
||||||
Priority: 128,
|
Priority: 128,
|
||||||
IP: "1.0.0.1",
|
IP: "1.0.0.1",
|
||||||
Protocol: RTCIceProtocolUDP,
|
Protocol: ICEProtocolUDP,
|
||||||
Port: 1234,
|
Port: 1234,
|
||||||
Typ: RTCIceCandidateTypeHost,
|
Typ: ICECandidateTypeHost,
|
||||||
Component: 1,
|
Component: 1,
|
||||||
}, &ice.Candidate{
|
}, &ice.Candidate{
|
||||||
IP: net.ParseIP("1.0.0.1"),
|
IP: net.ParseIP("1.0.0.1"),
|
||||||
@@ -43,13 +43,13 @@ func TestRTCIceCandidate_Convert(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
RTCIceCandidate{
|
ICECandidate{
|
||||||
Foundation: "foundation",
|
Foundation: "foundation",
|
||||||
Priority: 128,
|
Priority: 128,
|
||||||
IP: "::1",
|
IP: "::1",
|
||||||
Protocol: RTCIceProtocolUDP,
|
Protocol: ICEProtocolUDP,
|
||||||
Port: 1234,
|
Port: 1234,
|
||||||
Typ: RTCIceCandidateTypeSrflx,
|
Typ: ICECandidateTypeSrflx,
|
||||||
Component: 1,
|
Component: 1,
|
||||||
RelatedAddress: "1.0.0.1",
|
RelatedAddress: "1.0.0.1",
|
||||||
RelatedPort: 4321,
|
RelatedPort: 4321,
|
||||||
@@ -78,13 +78,13 @@ func TestRTCIceCandidate_Convert(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
RTCIceCandidate{
|
ICECandidate{
|
||||||
Foundation: "foundation",
|
Foundation: "foundation",
|
||||||
Priority: 128,
|
Priority: 128,
|
||||||
IP: "::1",
|
IP: "::1",
|
||||||
Protocol: RTCIceProtocolUDP,
|
Protocol: ICEProtocolUDP,
|
||||||
Port: 1234,
|
Port: 1234,
|
||||||
Typ: RTCIceCandidateTypePrflx,
|
Typ: ICECandidateTypePrflx,
|
||||||
Component: 1,
|
Component: 1,
|
||||||
RelatedAddress: "1.0.0.1",
|
RelatedAddress: "1.0.0.1",
|
||||||
RelatedPort: 4321,
|
RelatedPort: 4321,
|
||||||
@@ -137,8 +137,8 @@ func TestConvertTypeFromICE(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("failed coverting ice.CandidateTypeHost")
|
t.Fatal("failed coverting ice.CandidateTypeHost")
|
||||||
}
|
}
|
||||||
if ct != RTCIceCandidateTypeHost {
|
if ct != ICECandidateTypeHost {
|
||||||
t.Fatal("should be coverted to RTCIceCandidateTypeHost")
|
t.Fatal("should be coverted to ICECandidateTypeHost")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
t.Run("srflx", func(t *testing.T) {
|
t.Run("srflx", func(t *testing.T) {
|
||||||
@@ -146,8 +146,8 @@ func TestConvertTypeFromICE(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("failed coverting ice.CandidateTypeServerReflexive")
|
t.Fatal("failed coverting ice.CandidateTypeServerReflexive")
|
||||||
}
|
}
|
||||||
if ct != RTCIceCandidateTypeSrflx {
|
if ct != ICECandidateTypeSrflx {
|
||||||
t.Fatal("should be coverted to RTCIceCandidateTypeSrflx")
|
t.Fatal("should be coverted to ICECandidateTypeSrflx")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
t.Run("prflx", func(t *testing.T) {
|
t.Run("prflx", func(t *testing.T) {
|
||||||
@@ -155,8 +155,8 @@ func TestConvertTypeFromICE(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("failed coverting ice.CandidateTypePeerReflexive")
|
t.Fatal("failed coverting ice.CandidateTypePeerReflexive")
|
||||||
}
|
}
|
||||||
if ct != RTCIceCandidateTypePrflx {
|
if ct != ICECandidateTypePrflx {
|
||||||
t.Fatal("should be coverted to RTCIceCandidateTypePrflx")
|
t.Fatal("should be coverted to ICECandidateTypePrflx")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -2,70 +2,70 @@ package webrtc
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
// RTCIceCandidateType represents the type of the ICE candidate used.
|
// ICECandidateType represents the type of the ICE candidate used.
|
||||||
type RTCIceCandidateType int
|
type ICECandidateType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCIceCandidateTypeHost indicates that the candidate is of Host type as
|
// ICECandidateTypeHost indicates that the candidate is of Host type as
|
||||||
// described in https://tools.ietf.org/html/rfc8445#section-5.1.1.1. A
|
// described in https://tools.ietf.org/html/rfc8445#section-5.1.1.1. A
|
||||||
// candidate obtained by binding to a specific port from an IP address on
|
// candidate obtained by binding to a specific port from an IP address on
|
||||||
// the host. This includes IP addresses on physical interfaces and logical
|
// the host. This includes IP addresses on physical interfaces and logical
|
||||||
// ones, such as ones obtained through VPNs.
|
// ones, such as ones obtained through VPNs.
|
||||||
RTCIceCandidateTypeHost RTCIceCandidateType = iota + 1
|
ICECandidateTypeHost ICECandidateType = iota + 1
|
||||||
|
|
||||||
// RTCIceCandidateTypeSrflx indicates the the candidate is of Server
|
// ICECandidateTypeSrflx indicates the the candidate is of Server
|
||||||
// Reflexive type as described
|
// Reflexive type as described
|
||||||
// https://tools.ietf.org/html/rfc8445#section-5.1.1.2. A candidate type
|
// https://tools.ietf.org/html/rfc8445#section-5.1.1.2. A candidate type
|
||||||
// whose IP address and port are a binding allocated by a NAT for an ICE
|
// whose IP address and port are a binding allocated by a NAT for an ICE
|
||||||
// agent after it sends a packet through the NAT to a server, such as a
|
// agent after it sends a packet through the NAT to a server, such as a
|
||||||
// STUN server.
|
// STUN server.
|
||||||
RTCIceCandidateTypeSrflx
|
ICECandidateTypeSrflx
|
||||||
|
|
||||||
// RTCIceCandidateTypePrflx indicates that the candidate is of Peer
|
// ICECandidateTypePrflx indicates that the candidate is of Peer
|
||||||
// Reflexive type. A candidate type whose IP address and port are a binding
|
// Reflexive type. A candidate type whose IP address and port are a binding
|
||||||
// allocated by a NAT for an ICE agent after it sends a packet through the
|
// allocated by a NAT for an ICE agent after it sends a packet through the
|
||||||
// NAT to its peer.
|
// NAT to its peer.
|
||||||
RTCIceCandidateTypePrflx
|
ICECandidateTypePrflx
|
||||||
|
|
||||||
// RTCIceCandidateTypeRelay indicates the the candidate is of Relay type as
|
// ICECandidateTypeRelay indicates the the candidate is of Relay type as
|
||||||
// described in https://tools.ietf.org/html/rfc8445#section-5.1.1.2. A
|
// described in https://tools.ietf.org/html/rfc8445#section-5.1.1.2. A
|
||||||
// candidate type obtained from a relay server, such as a TURN server.
|
// candidate type obtained from a relay server, such as a TURN server.
|
||||||
RTCIceCandidateTypeRelay
|
ICECandidateTypeRelay
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is done this way because of a linter.
|
// This is done this way because of a linter.
|
||||||
const (
|
const (
|
||||||
rtcIceCandidateTypeHostStr = "host"
|
iceCandidateTypeHostStr = "host"
|
||||||
rtcIceCandidateTypeSrflxStr = "srflx"
|
iceCandidateTypeSrflxStr = "srflx"
|
||||||
rtcIceCandidateTypePrflxStr = "prflx"
|
iceCandidateTypePrflxStr = "prflx"
|
||||||
rtcIceCandidateTypeRelayStr = "relay"
|
iceCandidateTypeRelayStr = "relay"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRTCIceCandidateType(raw string) (RTCIceCandidateType, error) {
|
func newICECandidateType(raw string) (ICECandidateType, error) {
|
||||||
switch raw {
|
switch raw {
|
||||||
case rtcIceCandidateTypeHostStr:
|
case iceCandidateTypeHostStr:
|
||||||
return RTCIceCandidateTypeHost, nil
|
return ICECandidateTypeHost, nil
|
||||||
case rtcIceCandidateTypeSrflxStr:
|
case iceCandidateTypeSrflxStr:
|
||||||
return RTCIceCandidateTypeSrflx, nil
|
return ICECandidateTypeSrflx, nil
|
||||||
case rtcIceCandidateTypePrflxStr:
|
case iceCandidateTypePrflxStr:
|
||||||
return RTCIceCandidateTypePrflx, nil
|
return ICECandidateTypePrflx, nil
|
||||||
case rtcIceCandidateTypeRelayStr:
|
case iceCandidateTypeRelayStr:
|
||||||
return RTCIceCandidateTypeRelay, nil
|
return ICECandidateTypeRelay, nil
|
||||||
default:
|
default:
|
||||||
return RTCIceCandidateType(Unknown), fmt.Errorf("Unknown ICE candidate type: %s", raw)
|
return ICECandidateType(Unknown), fmt.Errorf("Unknown ICE candidate type: %s", raw)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t RTCIceCandidateType) String() string {
|
func (t ICECandidateType) String() string {
|
||||||
switch t {
|
switch t {
|
||||||
case RTCIceCandidateTypeHost:
|
case ICECandidateTypeHost:
|
||||||
return rtcIceCandidateTypeHostStr
|
return iceCandidateTypeHostStr
|
||||||
case RTCIceCandidateTypeSrflx:
|
case ICECandidateTypeSrflx:
|
||||||
return rtcIceCandidateTypeSrflxStr
|
return iceCandidateTypeSrflxStr
|
||||||
case RTCIceCandidateTypePrflx:
|
case ICECandidateTypePrflx:
|
||||||
return rtcIceCandidateTypePrflxStr
|
return iceCandidateTypePrflxStr
|
||||||
case RTCIceCandidateTypeRelay:
|
case ICECandidateTypeRelay:
|
||||||
return rtcIceCandidateTypeRelayStr
|
return iceCandidateTypeRelayStr
|
||||||
default:
|
default:
|
||||||
return ErrUnknownType.Error()
|
return ErrUnknownType.Error()
|
||||||
}
|
}
|
||||||
|
@@ -6,21 +6,21 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRTCIceCandidateType(t *testing.T) {
|
func TestICECandidateType(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
typeString string
|
typeString string
|
||||||
shouldFail bool
|
shouldFail bool
|
||||||
expectedType RTCIceCandidateType
|
expectedType ICECandidateType
|
||||||
}{
|
}{
|
||||||
{unknownStr, true, RTCIceCandidateType(Unknown)},
|
{unknownStr, true, ICECandidateType(Unknown)},
|
||||||
{"host", false, RTCIceCandidateTypeHost},
|
{"host", false, ICECandidateTypeHost},
|
||||||
{"srflx", false, RTCIceCandidateTypeSrflx},
|
{"srflx", false, ICECandidateTypeSrflx},
|
||||||
{"prflx", false, RTCIceCandidateTypePrflx},
|
{"prflx", false, ICECandidateTypePrflx},
|
||||||
{"relay", false, RTCIceCandidateTypeRelay},
|
{"relay", false, ICECandidateTypeRelay},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
actual, err := newRTCIceCandidateType(testCase.typeString)
|
actual, err := newICECandidateType(testCase.typeString)
|
||||||
if (err != nil) != testCase.shouldFail {
|
if (err != nil) != testCase.shouldFail {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@@ -32,16 +32,16 @@ func TestRTCIceCandidateType(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCIceCandidateType_String(t *testing.T) {
|
func TestICECandidateType_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
cType RTCIceCandidateType
|
cType ICECandidateType
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCIceCandidateType(Unknown), unknownStr},
|
{ICECandidateType(Unknown), unknownStr},
|
||||||
{RTCIceCandidateTypeHost, "host"},
|
{ICECandidateTypeHost, "host"},
|
||||||
{RTCIceCandidateTypeSrflx, "srflx"},
|
{ICECandidateTypeSrflx, "srflx"},
|
||||||
{RTCIceCandidateTypePrflx, "prflx"},
|
{ICECandidateTypePrflx, "prflx"},
|
||||||
{RTCIceCandidateTypeRelay, "relay"},
|
{ICECandidateTypeRelay, "relay"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@@ -1,46 +1,46 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCIceComponent describes if the ice transport is used for RTP
|
// ICEComponent describes if the ice transport is used for RTP
|
||||||
// (or RTCP multiplexing).
|
// (or RTCP multiplexing).
|
||||||
type RTCIceComponent int
|
type ICEComponent int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCIceComponentRtp indicates that the ICE Transport is used for RTP (or
|
// ICEComponentRTP indicates that the ICE Transport is used for RTP (or
|
||||||
// RTCP multiplexing), as defined in
|
// RTCP multiplexing), as defined in
|
||||||
// https://tools.ietf.org/html/rfc5245#section-4.1.1.1. Protocols
|
// https://tools.ietf.org/html/rfc5245#section-4.1.1.1. Protocols
|
||||||
// multiplexed with RTP (e.g. data channel) share its component ID. This
|
// multiplexed with RTP (e.g. data channel) share its component ID. This
|
||||||
// represents the component-id value 1 when encoded in candidate-attribute.
|
// represents the component-id value 1 when encoded in candidate-attribute.
|
||||||
RTCIceComponentRtp RTCIceComponent = iota + 1
|
ICEComponentRTP ICEComponent = iota + 1
|
||||||
|
|
||||||
// RTCIceComponentRtcp indicates that the ICE Transport is used for RTCP as
|
// ICEComponentRTCP indicates that the ICE Transport is used for RTCP as
|
||||||
// defined by https://tools.ietf.org/html/rfc5245#section-4.1.1.1. This
|
// defined by https://tools.ietf.org/html/rfc5245#section-4.1.1.1. This
|
||||||
// represents the component-id value 2 when encoded in candidate-attribute.
|
// represents the component-id value 2 when encoded in candidate-attribute.
|
||||||
RTCIceComponentRtcp
|
ICEComponentRTCP
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is done this way because of a linter.
|
// This is done this way because of a linter.
|
||||||
const (
|
const (
|
||||||
rtcIceComponentRtpStr = "rtp"
|
iceComponentRTPStr = "rtp"
|
||||||
rtcIceComponentRtcpStr = "rtcp"
|
iceComponentRTCPStr = "rtcp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRTCIceComponent(raw string) RTCIceComponent {
|
func newICEComponent(raw string) ICEComponent {
|
||||||
switch raw {
|
switch raw {
|
||||||
case rtcIceComponentRtpStr:
|
case iceComponentRTPStr:
|
||||||
return RTCIceComponentRtp
|
return ICEComponentRTP
|
||||||
case rtcIceComponentRtcpStr:
|
case iceComponentRTCPStr:
|
||||||
return RTCIceComponentRtcp
|
return ICEComponentRTCP
|
||||||
default:
|
default:
|
||||||
return RTCIceComponent(Unknown)
|
return ICEComponent(Unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t RTCIceComponent) String() string {
|
func (t ICEComponent) String() string {
|
||||||
switch t {
|
switch t {
|
||||||
case RTCIceComponentRtp:
|
case ICEComponentRTP:
|
||||||
return rtcIceComponentRtpStr
|
return iceComponentRTPStr
|
||||||
case RTCIceComponentRtcp:
|
case ICEComponentRTCP:
|
||||||
return rtcIceComponentRtcpStr
|
return iceComponentRTCPStr
|
||||||
default:
|
default:
|
||||||
return ErrUnknownType.Error()
|
return ErrUnknownType.Error()
|
||||||
}
|
}
|
||||||
|
@@ -6,33 +6,33 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRTCIceComponent(t *testing.T) {
|
func TestICEComponent(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
componentString string
|
componentString string
|
||||||
expectedComponent RTCIceComponent
|
expectedComponent ICEComponent
|
||||||
}{
|
}{
|
||||||
{unknownStr, RTCIceComponent(Unknown)},
|
{unknownStr, ICEComponent(Unknown)},
|
||||||
{"rtp", RTCIceComponentRtp},
|
{"rtp", ICEComponentRTP},
|
||||||
{"rtcp", RTCIceComponentRtcp},
|
{"rtcp", ICEComponentRTCP},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
newRTCIceComponent(testCase.componentString),
|
newICEComponent(testCase.componentString),
|
||||||
testCase.expectedComponent,
|
testCase.expectedComponent,
|
||||||
"testCase: %d %v", i, testCase,
|
"testCase: %d %v", i, testCase,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCIceComponent_String(t *testing.T) {
|
func TestICEComponent_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
state RTCIceComponent
|
state ICEComponent
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCIceComponent(Unknown), unknownStr},
|
{ICEComponent(Unknown), unknownStr},
|
||||||
{RTCIceComponentRtp, "rtp"},
|
{ICEComponentRTP, "rtp"},
|
||||||
{RTCIceComponentRtcp, "rtcp"},
|
{ICEComponentRTCP, "rtcp"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@@ -1,92 +1,92 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCIceConnectionState indicates signaling state of the Ice Connection.
|
// ICEConnectionState indicates signaling state of the ICE Connection.
|
||||||
type RTCIceConnectionState int
|
type ICEConnectionState int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCIceConnectionStateNew indicates that any of the RTCIceTransports are
|
// ICEConnectionStateNew indicates that any of the ICETransports are
|
||||||
// in the "new" state and none of them are in the "checking", "disconnected"
|
// in the "new" state and none of them are in the "checking", "disconnected"
|
||||||
// or "failed" state, or all RTCIceTransports are in the "closed" state, or
|
// or "failed" state, or all ICETransports are in the "closed" state, or
|
||||||
// there are no transports.
|
// there are no transports.
|
||||||
RTCIceConnectionStateNew RTCIceConnectionState = iota + 1
|
ICEConnectionStateNew ICEConnectionState = iota + 1
|
||||||
|
|
||||||
// RTCIceConnectionStateChecking indicates that any of the RTCIceTransports
|
// ICEConnectionStateChecking indicates that any of the ICETransports
|
||||||
// are in the "checking" state and none of them are in the "disconnected"
|
// are in the "checking" state and none of them are in the "disconnected"
|
||||||
// or "failed" state.
|
// or "failed" state.
|
||||||
RTCIceConnectionStateChecking
|
ICEConnectionStateChecking
|
||||||
|
|
||||||
// RTCIceConnectionStateConnected indicates that all RTCIceTransports are
|
// ICEConnectionStateConnected indicates that all ICETransports are
|
||||||
// in the "connected", "completed" or "closed" state and at least one of
|
// in the "connected", "completed" or "closed" state and at least one of
|
||||||
// them is in the "connected" state.
|
// them is in the "connected" state.
|
||||||
RTCIceConnectionStateConnected
|
ICEConnectionStateConnected
|
||||||
|
|
||||||
// RTCIceConnectionStateCompleted indicates that all RTCIceTransports are
|
// ICEConnectionStateCompleted indicates that all ICETransports are
|
||||||
// in the "completed" or "closed" state and at least one of them is in the
|
// in the "completed" or "closed" state and at least one of them is in the
|
||||||
// "completed" state.
|
// "completed" state.
|
||||||
RTCIceConnectionStateCompleted
|
ICEConnectionStateCompleted
|
||||||
|
|
||||||
// RTCIceConnectionStateDisconnected indicates that any of the
|
// ICEConnectionStateDisconnected indicates that any of the
|
||||||
// RTCIceTransports are in the "disconnected" state and none of them are
|
// ICETransports are in the "disconnected" state and none of them are
|
||||||
// in the "failed" state.
|
// in the "failed" state.
|
||||||
RTCIceConnectionStateDisconnected
|
ICEConnectionStateDisconnected
|
||||||
|
|
||||||
// RTCIceConnectionStateFailed indicates that any of the RTCIceTransports
|
// ICEConnectionStateFailed indicates that any of the ICETransports
|
||||||
// are in the "failed" state.
|
// are in the "failed" state.
|
||||||
RTCIceConnectionStateFailed
|
ICEConnectionStateFailed
|
||||||
|
|
||||||
// RTCIceConnectionStateClosed indicates that the RTCPeerConnection's
|
// ICEConnectionStateClosed indicates that the PeerConnection's
|
||||||
// isClosed is true.
|
// isClosed is true.
|
||||||
RTCIceConnectionStateClosed
|
ICEConnectionStateClosed
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is done this way because of a linter.
|
// This is done this way because of a linter.
|
||||||
const (
|
const (
|
||||||
rtcIceConnectionStateNewStr = "new"
|
iceConnectionStateNewStr = "new"
|
||||||
rtcIceConnectionStateCheckingStr = "checking"
|
iceConnectionStateCheckingStr = "checking"
|
||||||
rtcIceConnectionStateConnectedStr = "connected"
|
iceConnectionStateConnectedStr = "connected"
|
||||||
rtcIceConnectionStateCompletedStr = "completed"
|
iceConnectionStateCompletedStr = "completed"
|
||||||
rtcIceConnectionStateDisconnectedStr = "disconnected"
|
iceConnectionStateDisconnectedStr = "disconnected"
|
||||||
rtcIceConnectionStateFailedStr = "failed"
|
iceConnectionStateFailedStr = "failed"
|
||||||
rtcIceConnectionStateClosedStr = "closed"
|
iceConnectionStateClosedStr = "closed"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRTCIceConnectionState(raw string) RTCIceConnectionState {
|
func newICEConnectionState(raw string) ICEConnectionState {
|
||||||
switch raw {
|
switch raw {
|
||||||
case rtcIceConnectionStateNewStr:
|
case iceConnectionStateNewStr:
|
||||||
return RTCIceConnectionStateNew
|
return ICEConnectionStateNew
|
||||||
case rtcIceConnectionStateCheckingStr:
|
case iceConnectionStateCheckingStr:
|
||||||
return RTCIceConnectionStateChecking
|
return ICEConnectionStateChecking
|
||||||
case rtcIceConnectionStateConnectedStr:
|
case iceConnectionStateConnectedStr:
|
||||||
return RTCIceConnectionStateConnected
|
return ICEConnectionStateConnected
|
||||||
case rtcIceConnectionStateCompletedStr:
|
case iceConnectionStateCompletedStr:
|
||||||
return RTCIceConnectionStateCompleted
|
return ICEConnectionStateCompleted
|
||||||
case rtcIceConnectionStateDisconnectedStr:
|
case iceConnectionStateDisconnectedStr:
|
||||||
return RTCIceConnectionStateDisconnected
|
return ICEConnectionStateDisconnected
|
||||||
case rtcIceConnectionStateFailedStr:
|
case iceConnectionStateFailedStr:
|
||||||
return RTCIceConnectionStateFailed
|
return ICEConnectionStateFailed
|
||||||
case rtcIceConnectionStateClosedStr:
|
case iceConnectionStateClosedStr:
|
||||||
return RTCIceConnectionStateClosed
|
return ICEConnectionStateClosed
|
||||||
default:
|
default:
|
||||||
return RTCIceConnectionState(Unknown)
|
return ICEConnectionState(Unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c RTCIceConnectionState) String() string {
|
func (c ICEConnectionState) String() string {
|
||||||
switch c {
|
switch c {
|
||||||
case RTCIceConnectionStateNew:
|
case ICEConnectionStateNew:
|
||||||
return rtcIceConnectionStateNewStr
|
return iceConnectionStateNewStr
|
||||||
case RTCIceConnectionStateChecking:
|
case ICEConnectionStateChecking:
|
||||||
return rtcIceConnectionStateCheckingStr
|
return iceConnectionStateCheckingStr
|
||||||
case RTCIceConnectionStateConnected:
|
case ICEConnectionStateConnected:
|
||||||
return rtcIceConnectionStateConnectedStr
|
return iceConnectionStateConnectedStr
|
||||||
case RTCIceConnectionStateCompleted:
|
case ICEConnectionStateCompleted:
|
||||||
return rtcIceConnectionStateCompletedStr
|
return iceConnectionStateCompletedStr
|
||||||
case RTCIceConnectionStateDisconnected:
|
case ICEConnectionStateDisconnected:
|
||||||
return rtcIceConnectionStateDisconnectedStr
|
return iceConnectionStateDisconnectedStr
|
||||||
case RTCIceConnectionStateFailed:
|
case ICEConnectionStateFailed:
|
||||||
return rtcIceConnectionStateFailedStr
|
return iceConnectionStateFailedStr
|
||||||
case RTCIceConnectionStateClosed:
|
case ICEConnectionStateClosed:
|
||||||
return rtcIceConnectionStateClosedStr
|
return iceConnectionStateClosedStr
|
||||||
default:
|
default:
|
||||||
return ErrUnknownType.Error()
|
return ErrUnknownType.Error()
|
||||||
}
|
}
|
||||||
|
@@ -6,43 +6,43 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewRTCIceConnectionState(t *testing.T) {
|
func TestNewICEConnectionState(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
stateString string
|
stateString string
|
||||||
expectedState RTCIceConnectionState
|
expectedState ICEConnectionState
|
||||||
}{
|
}{
|
||||||
{unknownStr, RTCIceConnectionState(Unknown)},
|
{unknownStr, ICEConnectionState(Unknown)},
|
||||||
{"new", RTCIceConnectionStateNew},
|
{"new", ICEConnectionStateNew},
|
||||||
{"checking", RTCIceConnectionStateChecking},
|
{"checking", ICEConnectionStateChecking},
|
||||||
{"connected", RTCIceConnectionStateConnected},
|
{"connected", ICEConnectionStateConnected},
|
||||||
{"completed", RTCIceConnectionStateCompleted},
|
{"completed", ICEConnectionStateCompleted},
|
||||||
{"disconnected", RTCIceConnectionStateDisconnected},
|
{"disconnected", ICEConnectionStateDisconnected},
|
||||||
{"failed", RTCIceConnectionStateFailed},
|
{"failed", ICEConnectionStateFailed},
|
||||||
{"closed", RTCIceConnectionStateClosed},
|
{"closed", ICEConnectionStateClosed},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
testCase.expectedState,
|
testCase.expectedState,
|
||||||
newRTCIceConnectionState(testCase.stateString),
|
newICEConnectionState(testCase.stateString),
|
||||||
"testCase: %d %v", i, testCase,
|
"testCase: %d %v", i, testCase,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCIceConnectionState_String(t *testing.T) {
|
func TestICEConnectionState_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
state RTCIceConnectionState
|
state ICEConnectionState
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCIceConnectionState(Unknown), unknownStr},
|
{ICEConnectionState(Unknown), unknownStr},
|
||||||
{RTCIceConnectionStateNew, "new"},
|
{ICEConnectionStateNew, "new"},
|
||||||
{RTCIceConnectionStateChecking, "checking"},
|
{ICEConnectionStateChecking, "checking"},
|
||||||
{RTCIceConnectionStateConnected, "connected"},
|
{ICEConnectionStateConnected, "connected"},
|
||||||
{RTCIceConnectionStateCompleted, "completed"},
|
{ICEConnectionStateCompleted, "completed"},
|
||||||
{RTCIceConnectionStateDisconnected, "disconnected"},
|
{ICEConnectionStateDisconnected, "disconnected"},
|
||||||
{RTCIceConnectionStateFailed, "failed"},
|
{ICEConnectionStateFailed, "failed"},
|
||||||
{RTCIceConnectionStateClosed, "closed"},
|
{ICEConnectionStateClosed, "closed"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@@ -1,42 +1,42 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCIceCredentialType indicates the type of credentials used to connect to
|
// ICECredentialType indicates the type of credentials used to connect to
|
||||||
// an ICE server.
|
// an ICE server.
|
||||||
type RTCIceCredentialType int
|
type ICECredentialType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCIceCredentialTypePassword describes username and pasword based
|
// ICECredentialTypePassword describes username and pasword based
|
||||||
// credentials as described in https://tools.ietf.org/html/rfc5389.
|
// credentials as described in https://tools.ietf.org/html/rfc5389.
|
||||||
RTCIceCredentialTypePassword RTCIceCredentialType = iota + 1
|
ICECredentialTypePassword ICECredentialType = iota + 1
|
||||||
|
|
||||||
// RTCIceCredentialTypeOauth describes token based credential as described
|
// ICECredentialTypeOauth describes token based credential as described
|
||||||
// in https://tools.ietf.org/html/rfc7635.
|
// in https://tools.ietf.org/html/rfc7635.
|
||||||
RTCIceCredentialTypeOauth
|
ICECredentialTypeOauth
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is done this way because of a linter.
|
// This is done this way because of a linter.
|
||||||
const (
|
const (
|
||||||
rtcIceCredentialTypePasswordStr = "password"
|
iceCredentialTypePasswordStr = "password"
|
||||||
rtcIceCredentialTypeOauthStr = "oauth"
|
iceCredentialTypeOauthStr = "oauth"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRTCIceCredentialType(raw string) RTCIceCredentialType {
|
func newICECredentialType(raw string) ICECredentialType {
|
||||||
switch raw {
|
switch raw {
|
||||||
case rtcIceCredentialTypePasswordStr:
|
case iceCredentialTypePasswordStr:
|
||||||
return RTCIceCredentialTypePassword
|
return ICECredentialTypePassword
|
||||||
case rtcIceCredentialTypeOauthStr:
|
case iceCredentialTypeOauthStr:
|
||||||
return RTCIceCredentialTypeOauth
|
return ICECredentialTypeOauth
|
||||||
default:
|
default:
|
||||||
return RTCIceCredentialType(Unknown)
|
return ICECredentialType(Unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t RTCIceCredentialType) String() string {
|
func (t ICECredentialType) String() string {
|
||||||
switch t {
|
switch t {
|
||||||
case RTCIceCredentialTypePassword:
|
case ICECredentialTypePassword:
|
||||||
return rtcIceCredentialTypePasswordStr
|
return iceCredentialTypePasswordStr
|
||||||
case RTCIceCredentialTypeOauth:
|
case ICECredentialTypeOauth:
|
||||||
return rtcIceCredentialTypeOauthStr
|
return iceCredentialTypeOauthStr
|
||||||
default:
|
default:
|
||||||
return ErrUnknownType.Error()
|
return ErrUnknownType.Error()
|
||||||
}
|
}
|
||||||
|
@@ -6,33 +6,33 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewRTCIceCredentialType(t *testing.T) {
|
func TestNewICECredentialType(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
credentialTypeString string
|
credentialTypeString string
|
||||||
expectedCredentialType RTCIceCredentialType
|
expectedCredentialType ICECredentialType
|
||||||
}{
|
}{
|
||||||
{unknownStr, RTCIceCredentialType(Unknown)},
|
{unknownStr, ICECredentialType(Unknown)},
|
||||||
{"password", RTCIceCredentialTypePassword},
|
{"password", ICECredentialTypePassword},
|
||||||
{"oauth", RTCIceCredentialTypeOauth},
|
{"oauth", ICECredentialTypeOauth},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
testCase.expectedCredentialType,
|
testCase.expectedCredentialType,
|
||||||
newRTCIceCredentialType(testCase.credentialTypeString),
|
newICECredentialType(testCase.credentialTypeString),
|
||||||
"testCase: %d %v", i, testCase,
|
"testCase: %d %v", i, testCase,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCIceCredentialType_String(t *testing.T) {
|
func TestICECredentialType_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
credentialType RTCIceCredentialType
|
credentialType ICECredentialType
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCIceCredentialType(Unknown), unknownStr},
|
{ICECredentialType(Unknown), unknownStr},
|
||||||
{RTCIceCredentialTypePassword, "password"},
|
{ICECredentialTypePassword, "password"},
|
||||||
{RTCIceCredentialTypeOauth, "oauth"},
|
{ICECredentialTypeOauth, "oauth"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@@ -7,13 +7,13 @@ import (
|
|||||||
"github.com/pions/webrtc/pkg/ice"
|
"github.com/pions/webrtc/pkg/ice"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The RTCIceGatherer gathers local host, server reflexive and relay
|
// The ICEGatherer gathers local host, server reflexive and relay
|
||||||
// candidates, as well as enabling the retrieval of local Interactive
|
// candidates, as well as enabling the retrieval of local Interactive
|
||||||
// Connectivity Establishment (ICE) parameters which can be
|
// Connectivity Establishment (ICE) parameters which can be
|
||||||
// exchanged in signaling.
|
// exchanged in signaling.
|
||||||
type RTCIceGatherer struct {
|
type ICEGatherer struct {
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
state RTCIceGathererState
|
state ICEGathererState
|
||||||
|
|
||||||
validatedServers []*ice.URL
|
validatedServers []*ice.URL
|
||||||
|
|
||||||
@@ -22,10 +22,10 @@ type RTCIceGatherer struct {
|
|||||||
api *API
|
api *API
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRTCIceGatherer creates a new NewRTCIceGatherer.
|
// NewICEGatherer creates a new NewICEGatherer.
|
||||||
// This constructor is part of the ORTC API. It is not
|
// This constructor is part of the ORTC API. It is not
|
||||||
// meant to be used together with the basic WebRTC API.
|
// meant to be used together with the basic WebRTC API.
|
||||||
func (api *API) NewRTCIceGatherer(opts RTCIceGatherOptions) (*RTCIceGatherer, error) {
|
func (api *API) NewICEGatherer(opts ICEGatherOptions) (*ICEGatherer, error) {
|
||||||
validatedServers := []*ice.URL{}
|
validatedServers := []*ice.URL{}
|
||||||
if len(opts.ICEServers) > 0 {
|
if len(opts.ICEServers) > 0 {
|
||||||
for _, server := range opts.ICEServers {
|
for _, server := range opts.ICEServers {
|
||||||
@@ -37,22 +37,22 @@ func (api *API) NewRTCIceGatherer(opts RTCIceGatherOptions) (*RTCIceGatherer, er
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &RTCIceGatherer{
|
return &ICEGatherer{
|
||||||
state: RTCIceGathererStateNew,
|
state: ICEGathererStateNew,
|
||||||
validatedServers: validatedServers,
|
validatedServers: validatedServers,
|
||||||
api: api,
|
api: api,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// State indicates the current state of the ICE gatherer.
|
// State indicates the current state of the ICE gatherer.
|
||||||
func (g *RTCIceGatherer) State() RTCIceGathererState {
|
func (g *ICEGatherer) State() ICEGathererState {
|
||||||
g.lock.RLock()
|
g.lock.RLock()
|
||||||
defer g.lock.RUnlock()
|
defer g.lock.RUnlock()
|
||||||
return g.state
|
return g.state
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gather ICE candidates.
|
// Gather ICE candidates.
|
||||||
func (g *RTCIceGatherer) Gather() error {
|
func (g *ICEGatherer) Gather() error {
|
||||||
g.lock.Lock()
|
g.lock.Lock()
|
||||||
defer g.lock.Unlock()
|
defer g.lock.Unlock()
|
||||||
|
|
||||||
@@ -70,13 +70,13 @@ func (g *RTCIceGatherer) Gather() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
g.agent = agent
|
g.agent = agent
|
||||||
g.state = RTCIceGathererStateComplete
|
g.state = ICEGathererStateComplete
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close prunes all local candidates, and closes the ports.
|
// Close prunes all local candidates, and closes the ports.
|
||||||
func (g *RTCIceGatherer) Close() error {
|
func (g *ICEGatherer) Close() error {
|
||||||
g.lock.Lock()
|
g.lock.Lock()
|
||||||
defer g.lock.Unlock()
|
defer g.lock.Unlock()
|
||||||
|
|
||||||
@@ -93,25 +93,25 @@ func (g *RTCIceGatherer) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLocalParameters returns the ICE parameters of the RTCIceGatherer.
|
// GetLocalParameters returns the ICE parameters of the ICEGatherer.
|
||||||
func (g *RTCIceGatherer) GetLocalParameters() (RTCIceParameters, error) {
|
func (g *ICEGatherer) GetLocalParameters() (ICEParameters, error) {
|
||||||
g.lock.RLock()
|
g.lock.RLock()
|
||||||
defer g.lock.RUnlock()
|
defer g.lock.RUnlock()
|
||||||
if g.agent == nil {
|
if g.agent == nil {
|
||||||
return RTCIceParameters{}, errors.New("Gatherer not started")
|
return ICEParameters{}, errors.New("Gatherer not started")
|
||||||
}
|
}
|
||||||
|
|
||||||
frag, pwd := g.agent.GetLocalUserCredentials()
|
frag, pwd := g.agent.GetLocalUserCredentials()
|
||||||
|
|
||||||
return RTCIceParameters{
|
return ICEParameters{
|
||||||
UsernameFragment: frag,
|
UsernameFragment: frag,
|
||||||
Password: pwd,
|
Password: pwd,
|
||||||
IceLite: false,
|
ICELite: false,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLocalCandidates returns the sequence of valid local candidates associated with the RTCIceGatherer.
|
// GetLocalCandidates returns the sequence of valid local candidates associated with the ICEGatherer.
|
||||||
func (g *RTCIceGatherer) GetLocalCandidates() ([]RTCIceCandidate, error) {
|
func (g *ICEGatherer) GetLocalCandidates() ([]ICECandidate, error) {
|
||||||
g.lock.RLock()
|
g.lock.RLock()
|
||||||
defer g.lock.RUnlock()
|
defer g.lock.RUnlock()
|
||||||
|
|
||||||
@@ -124,5 +124,5 @@ func (g *RTCIceGatherer) GetLocalCandidates() ([]RTCIceCandidate, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return newRTCIceCandidatesFromICE(iceCandidates)
|
return newICECandidatesFromICE(iceCandidates)
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,7 @@ import (
|
|||||||
"github.com/pions/transport/test"
|
"github.com/pions/transport/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewRTCIceGatherer_Success(t *testing.T) {
|
func TestNewICEGatherer_Success(t *testing.T) {
|
||||||
// Limit runtime in case of deadlocks
|
// Limit runtime in case of deadlocks
|
||||||
lim := test.TimeOut(time.Second * 20)
|
lim := test.TimeOut(time.Second * 20)
|
||||||
defer lim.Stop()
|
defer lim.Stop()
|
||||||
@@ -15,18 +15,18 @@ func TestNewRTCIceGatherer_Success(t *testing.T) {
|
|||||||
report := test.CheckRoutines(t)
|
report := test.CheckRoutines(t)
|
||||||
defer report()
|
defer report()
|
||||||
|
|
||||||
opts := RTCIceGatherOptions{
|
opts := ICEGatherOptions{
|
||||||
ICEServers: []RTCIceServer{{URLs: []string{"stun:stun.l.google.com:19302"}}},
|
ICEServers: []ICEServer{{URLs: []string{"stun:stun.l.google.com:19302"}}},
|
||||||
}
|
}
|
||||||
|
|
||||||
api := NewAPI()
|
api := NewAPI()
|
||||||
|
|
||||||
gatherer, err := api.NewRTCIceGatherer(opts)
|
gatherer, err := api.NewICEGatherer(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if gatherer.State() != RTCIceGathererStateNew {
|
if gatherer.State() != ICEGathererStateNew {
|
||||||
t.Fatalf("Expected gathering state new")
|
t.Fatalf("Expected gathering state new")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,34 +1,34 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCIceGathererState represents the current state of the ICE gatherer.
|
// ICEGathererState represents the current state of the ICE gatherer.
|
||||||
type RTCIceGathererState byte
|
type ICEGathererState byte
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCIceGathererStateNew indicates object has been created but
|
// ICEGathererStateNew indicates object has been created but
|
||||||
// gather() has not been called.
|
// gather() has not been called.
|
||||||
RTCIceGathererStateNew RTCIceGathererState = iota + 1
|
ICEGathererStateNew ICEGathererState = iota + 1
|
||||||
|
|
||||||
// RTCIceGathererStateGathering indicates gather() has been called,
|
// ICEGathererStateGathering indicates gather() has been called,
|
||||||
// and the RTCIceGatherer is in the process of gathering candidates.
|
// and the ICEGatherer is in the process of gathering candidates.
|
||||||
RTCIceGathererStateGathering
|
ICEGathererStateGathering
|
||||||
|
|
||||||
// RTCIceGathererStateComplete indicates the RTCIceGatherer has completed gathering.
|
// ICEGathererStateComplete indicates the ICEGatherer has completed gathering.
|
||||||
RTCIceGathererStateComplete
|
ICEGathererStateComplete
|
||||||
|
|
||||||
// RTCIceGathererStateClosed indicates the closed state can only be entered
|
// ICEGathererStateClosed indicates the closed state can only be entered
|
||||||
// when the RTCIceGatherer has been closed intentionally by calling close().
|
// when the ICEGatherer has been closed intentionally by calling close().
|
||||||
RTCIceGathererStateClosed
|
ICEGathererStateClosed
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s RTCIceGathererState) String() string {
|
func (s ICEGathererState) String() string {
|
||||||
switch s {
|
switch s {
|
||||||
case RTCIceGathererStateNew:
|
case ICEGathererStateNew:
|
||||||
return "new"
|
return "new"
|
||||||
case RTCIceGathererStateGathering:
|
case ICEGathererStateGathering:
|
||||||
return "gathering"
|
return "gathering"
|
||||||
case RTCIceGathererStateComplete:
|
case ICEGathererStateComplete:
|
||||||
return "complete"
|
return "complete"
|
||||||
case RTCIceGathererStateClosed:
|
case ICEGathererStateClosed:
|
||||||
return "closed"
|
return "closed"
|
||||||
default:
|
default:
|
||||||
return unknownStr
|
return unknownStr
|
||||||
|
@@ -6,16 +6,16 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRTCIceGathererState_String(t *testing.T) {
|
func TestICEGathererState_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
state RTCIceGathererState
|
state ICEGathererState
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCIceGathererState(Unknown), unknownStr},
|
{ICEGathererState(Unknown), unknownStr},
|
||||||
{RTCIceGathererStateNew, "new"},
|
{ICEGathererStateNew, "new"},
|
||||||
{RTCIceGathererStateGathering, "gathering"},
|
{ICEGathererStateGathering, "gathering"},
|
||||||
{RTCIceGathererStateComplete, "complete"},
|
{ICEGathererStateComplete, "complete"},
|
||||||
{RTCIceGathererStateClosed, "closed"},
|
{ICEGathererStateClosed, "closed"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@@ -1,51 +1,51 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCIceGatheringState describes the state of the candidate gathering process.
|
// ICEGatheringState describes the state of the candidate gathering process.
|
||||||
type RTCIceGatheringState int
|
type ICEGatheringState int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCIceGatheringStateNew indicates that any of the RTCIceTransports are
|
// ICEGatheringStateNew indicates that any of the ICETransports are
|
||||||
// in the "new" gathering state and none of the transports are in the
|
// in the "new" gathering state and none of the transports are in the
|
||||||
// "gathering" state, or there are no transports.
|
// "gathering" state, or there are no transports.
|
||||||
RTCIceGatheringStateNew RTCIceGatheringState = iota + 1
|
ICEGatheringStateNew ICEGatheringState = iota + 1
|
||||||
|
|
||||||
// RTCIceGatheringStateGathering indicates that any of the RTCIceTransports
|
// ICEGatheringStateGathering indicates that any of the ICETransports
|
||||||
// are in the "gathering" state.
|
// are in the "gathering" state.
|
||||||
RTCIceGatheringStateGathering
|
ICEGatheringStateGathering
|
||||||
|
|
||||||
// RTCIceGatheringStateComplete indicates that at least one RTCIceTransport
|
// ICEGatheringStateComplete indicates that at least one ICETransport
|
||||||
// exists, and all RTCIceTransports are in the "completed" gathering state.
|
// exists, and all ICETransports are in the "completed" gathering state.
|
||||||
RTCIceGatheringStateComplete
|
ICEGatheringStateComplete
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is done this way because of a linter.
|
// This is done this way because of a linter.
|
||||||
const (
|
const (
|
||||||
rtcIceGatheringStateNewStr = "new"
|
iceGatheringStateNewStr = "new"
|
||||||
rtcIceGatheringStateGatheringStr = "gathering"
|
iceGatheringStateGatheringStr = "gathering"
|
||||||
rtcIceGatheringStateCompleteStr = "complete"
|
iceGatheringStateCompleteStr = "complete"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRTCIceGatheringState(raw string) RTCIceGatheringState {
|
func newICEGatheringState(raw string) ICEGatheringState {
|
||||||
switch raw {
|
switch raw {
|
||||||
case rtcIceGatheringStateNewStr:
|
case iceGatheringStateNewStr:
|
||||||
return RTCIceGatheringStateNew
|
return ICEGatheringStateNew
|
||||||
case rtcIceGatheringStateGatheringStr:
|
case iceGatheringStateGatheringStr:
|
||||||
return RTCIceGatheringStateGathering
|
return ICEGatheringStateGathering
|
||||||
case rtcIceGatheringStateCompleteStr:
|
case iceGatheringStateCompleteStr:
|
||||||
return RTCIceGatheringStateComplete
|
return ICEGatheringStateComplete
|
||||||
default:
|
default:
|
||||||
return RTCIceGatheringState(Unknown)
|
return ICEGatheringState(Unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t RTCIceGatheringState) String() string {
|
func (t ICEGatheringState) String() string {
|
||||||
switch t {
|
switch t {
|
||||||
case RTCIceGatheringStateNew:
|
case ICEGatheringStateNew:
|
||||||
return rtcIceGatheringStateNewStr
|
return iceGatheringStateNewStr
|
||||||
case RTCIceGatheringStateGathering:
|
case ICEGatheringStateGathering:
|
||||||
return rtcIceGatheringStateGatheringStr
|
return iceGatheringStateGatheringStr
|
||||||
case RTCIceGatheringStateComplete:
|
case ICEGatheringStateComplete:
|
||||||
return rtcIceGatheringStateCompleteStr
|
return iceGatheringStateCompleteStr
|
||||||
default:
|
default:
|
||||||
return ErrUnknownType.Error()
|
return ErrUnknownType.Error()
|
||||||
}
|
}
|
||||||
|
@@ -6,35 +6,35 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewRTCIceGatheringState(t *testing.T) {
|
func TestNewICEGatheringState(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
stateString string
|
stateString string
|
||||||
expectedState RTCIceGatheringState
|
expectedState ICEGatheringState
|
||||||
}{
|
}{
|
||||||
{unknownStr, RTCIceGatheringState(Unknown)},
|
{unknownStr, ICEGatheringState(Unknown)},
|
||||||
{"new", RTCIceGatheringStateNew},
|
{"new", ICEGatheringStateNew},
|
||||||
{"gathering", RTCIceGatheringStateGathering},
|
{"gathering", ICEGatheringStateGathering},
|
||||||
{"complete", RTCIceGatheringStateComplete},
|
{"complete", ICEGatheringStateComplete},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
testCase.expectedState,
|
testCase.expectedState,
|
||||||
newRTCIceGatheringState(testCase.stateString),
|
newICEGatheringState(testCase.stateString),
|
||||||
"testCase: %d %v", i, testCase,
|
"testCase: %d %v", i, testCase,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCIceGatheringState_String(t *testing.T) {
|
func TestICEGatheringState_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
state RTCIceGatheringState
|
state ICEGatheringState
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCIceGatheringState(Unknown), unknownStr},
|
{ICEGatheringState(Unknown), unknownStr},
|
||||||
{RTCIceGatheringStateNew, "new"},
|
{ICEGatheringStateNew, "new"},
|
||||||
{RTCIceGatheringStateGathering, "gathering"},
|
{ICEGatheringStateGathering, "gathering"},
|
||||||
{RTCIceGatheringStateComplete, "complete"},
|
{ICEGatheringStateComplete, "complete"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCIceGatherOptions provides options relating to the gathering of ICE candidates.
|
// ICEGatherOptions provides options relating to the gathering of ICE candidates.
|
||||||
type RTCIceGatherOptions struct {
|
type ICEGatherOptions struct {
|
||||||
ICEServers []RTCIceServer
|
ICEServers []ICEServer
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCIceParameters includes the ICE username fragment
|
// ICEParameters includes the ICE username fragment
|
||||||
// and password and other ICE-related parameters.
|
// and password and other ICE-related parameters.
|
||||||
type RTCIceParameters struct {
|
type ICEParameters struct {
|
||||||
UsernameFragment string `json:"usernameFragment"`
|
UsernameFragment string `json:"usernameFragment"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
IceLite bool `json:"iceLite"`
|
ICELite bool `json:"iceLite"`
|
||||||
}
|
}
|
||||||
|
@@ -5,41 +5,41 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RTCIceProtocol indicates the transport protocol type that is used in the
|
// ICEProtocol indicates the transport protocol type that is used in the
|
||||||
// ice.URL structure.
|
// ice.URL structure.
|
||||||
type RTCIceProtocol int
|
type ICEProtocol int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCIceProtocolUDP indicates the URL uses a UDP transport.
|
// ICEProtocolUDP indicates the URL uses a UDP transport.
|
||||||
RTCIceProtocolUDP RTCIceProtocol = iota + 1
|
ICEProtocolUDP ICEProtocol = iota + 1
|
||||||
|
|
||||||
// RTCIceProtocolTCP indicates the URL uses a TCP transport.
|
// ICEProtocolTCP indicates the URL uses a TCP transport.
|
||||||
RTCIceProtocolTCP
|
ICEProtocolTCP
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is done this way because of a linter.
|
// This is done this way because of a linter.
|
||||||
const (
|
const (
|
||||||
rtcIceProtocolUDPStr = "udp"
|
iceProtocolUDPStr = "udp"
|
||||||
rtcIceProtocolTCPStr = "tcp"
|
iceProtocolTCPStr = "tcp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRTCIceProtocol(raw string) (RTCIceProtocol, error) {
|
func newICEProtocol(raw string) (ICEProtocol, error) {
|
||||||
switch {
|
switch {
|
||||||
case strings.EqualFold(rtcIceProtocolUDPStr, raw):
|
case strings.EqualFold(iceProtocolUDPStr, raw):
|
||||||
return RTCIceProtocolUDP, nil
|
return ICEProtocolUDP, nil
|
||||||
case strings.EqualFold(rtcIceProtocolTCPStr, raw):
|
case strings.EqualFold(iceProtocolTCPStr, raw):
|
||||||
return RTCIceProtocolTCP, nil
|
return ICEProtocolTCP, nil
|
||||||
default:
|
default:
|
||||||
return RTCIceProtocol(Unknown), fmt.Errorf("unknown protocol: %s", raw)
|
return ICEProtocol(Unknown), fmt.Errorf("unknown protocol: %s", raw)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t RTCIceProtocol) String() string {
|
func (t ICEProtocol) String() string {
|
||||||
switch t {
|
switch t {
|
||||||
case RTCIceProtocolUDP:
|
case ICEProtocolUDP:
|
||||||
return rtcIceProtocolUDPStr
|
return iceProtocolUDPStr
|
||||||
case RTCIceProtocolTCP:
|
case ICEProtocolTCP:
|
||||||
return rtcIceProtocolTCPStr
|
return iceProtocolTCPStr
|
||||||
default:
|
default:
|
||||||
return ErrUnknownType.Error()
|
return ErrUnknownType.Error()
|
||||||
}
|
}
|
||||||
|
@@ -6,21 +6,21 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewRTCIceProtocol(t *testing.T) {
|
func TestNewICEProtocol(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
protoString string
|
protoString string
|
||||||
shouldFail bool
|
shouldFail bool
|
||||||
expectedProto RTCIceProtocol
|
expectedProto ICEProtocol
|
||||||
}{
|
}{
|
||||||
{unknownStr, true, RTCIceProtocol(Unknown)},
|
{unknownStr, true, ICEProtocol(Unknown)},
|
||||||
{"udp", false, RTCIceProtocolUDP},
|
{"udp", false, ICEProtocolUDP},
|
||||||
{"tcp", false, RTCIceProtocolTCP},
|
{"tcp", false, ICEProtocolTCP},
|
||||||
{"UDP", false, RTCIceProtocolUDP},
|
{"UDP", false, ICEProtocolUDP},
|
||||||
{"TCP", false, RTCIceProtocolTCP},
|
{"TCP", false, ICEProtocolTCP},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
actual, err := newRTCIceProtocol(testCase.protoString)
|
actual, err := newICEProtocol(testCase.protoString)
|
||||||
if (err != nil) != testCase.shouldFail {
|
if (err != nil) != testCase.shouldFail {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@@ -32,14 +32,14 @@ func TestNewRTCIceProtocol(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCIceProtocol_String(t *testing.T) {
|
func TestICEProtocol_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
proto RTCIceProtocol
|
proto ICEProtocol
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCIceProtocol(Unknown), unknownStr},
|
{ICEProtocol(Unknown), unknownStr},
|
||||||
{RTCIceProtocolUDP, "udp"},
|
{ICEProtocolUDP, "udp"},
|
||||||
{RTCIceProtocolTCP, "tcp"},
|
{ICEProtocolTCP, "tcp"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@@ -1,44 +1,44 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCIceRole describes the role ice.Agent is playing in selecting the
|
// ICERole describes the role ice.Agent is playing in selecting the
|
||||||
// preferred the candidate pair.
|
// preferred the candidate pair.
|
||||||
type RTCIceRole int
|
type ICERole int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCIceRoleControlling indicates that the ICE agent that is responsible
|
// ICERoleControlling indicates that the ICE agent that is responsible
|
||||||
// for selecting the final choice of candidate pairs and signaling them
|
// for selecting the final choice of candidate pairs and signaling them
|
||||||
// through STUN and an updated offer, if needed. In any session, one agent
|
// through STUN and an updated offer, if needed. In any session, one agent
|
||||||
// is always controlling. The other is the controlled agent.
|
// is always controlling. The other is the controlled agent.
|
||||||
RTCIceRoleControlling RTCIceRole = iota + 1
|
ICERoleControlling ICERole = iota + 1
|
||||||
|
|
||||||
// RTCIceRoleControlled indicates that an ICE agent that waits for the
|
// ICERoleControlled indicates that an ICE agent that waits for the
|
||||||
// controlling agent to select the final choice of candidate pairs.
|
// controlling agent to select the final choice of candidate pairs.
|
||||||
RTCIceRoleControlled
|
ICERoleControlled
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is done this way because of a linter.
|
// This is done this way because of a linter.
|
||||||
const (
|
const (
|
||||||
rtcIceRoleControllingStr = "controlling"
|
iceRoleControllingStr = "controlling"
|
||||||
rtcIceRoleControlledStr = "controlled"
|
iceRoleControlledStr = "controlled"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRTCIceRole(raw string) RTCIceRole {
|
func newICERole(raw string) ICERole {
|
||||||
switch raw {
|
switch raw {
|
||||||
case rtcIceRoleControllingStr:
|
case iceRoleControllingStr:
|
||||||
return RTCIceRoleControlling
|
return ICERoleControlling
|
||||||
case rtcIceRoleControlledStr:
|
case iceRoleControlledStr:
|
||||||
return RTCIceRoleControlled
|
return ICERoleControlled
|
||||||
default:
|
default:
|
||||||
return RTCIceRole(Unknown)
|
return ICERole(Unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t RTCIceRole) String() string {
|
func (t ICERole) String() string {
|
||||||
switch t {
|
switch t {
|
||||||
case RTCIceRoleControlling:
|
case ICERoleControlling:
|
||||||
return rtcIceRoleControllingStr
|
return iceRoleControllingStr
|
||||||
case RTCIceRoleControlled:
|
case ICERoleControlled:
|
||||||
return rtcIceRoleControlledStr
|
return iceRoleControlledStr
|
||||||
default:
|
default:
|
||||||
return ErrUnknownType.Error()
|
return ErrUnknownType.Error()
|
||||||
}
|
}
|
||||||
|
@@ -6,33 +6,33 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewRTCIceRole(t *testing.T) {
|
func TestNewICERole(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
roleString string
|
roleString string
|
||||||
expectedRole RTCIceRole
|
expectedRole ICERole
|
||||||
}{
|
}{
|
||||||
{unknownStr, RTCIceRole(Unknown)},
|
{unknownStr, ICERole(Unknown)},
|
||||||
{"controlling", RTCIceRoleControlling},
|
{"controlling", ICERoleControlling},
|
||||||
{"controlled", RTCIceRoleControlled},
|
{"controlled", ICERoleControlled},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
testCase.expectedRole,
|
testCase.expectedRole,
|
||||||
newRTCIceRole(testCase.roleString),
|
newICERole(testCase.roleString),
|
||||||
"testCase: %d %v", i, testCase,
|
"testCase: %d %v", i, testCase,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCIceRole_String(t *testing.T) {
|
func TestICERole_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
proto RTCIceRole
|
proto ICERole
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCIceRole(Unknown), unknownStr},
|
{ICERole(Unknown), unknownStr},
|
||||||
{RTCIceRoleControlling, "controlling"},
|
{ICERoleControlling, "controlling"},
|
||||||
{RTCIceRoleControlled, "controlled"},
|
{ICERoleControlled, "controlled"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@@ -5,20 +5,20 @@ import (
|
|||||||
"github.com/pions/webrtc/pkg/rtcerr"
|
"github.com/pions/webrtc/pkg/rtcerr"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RTCIceServer describes a single STUN and TURN server that can be used by
|
// ICEServer describes a single STUN and TURN server that can be used by
|
||||||
// the IceAgent to establish a connection with a peer.
|
// the ICEAgent to establish a connection with a peer.
|
||||||
type RTCIceServer struct {
|
type ICEServer struct {
|
||||||
URLs []string
|
URLs []string
|
||||||
Username string
|
Username string
|
||||||
Credential interface{}
|
Credential interface{}
|
||||||
CredentialType RTCIceCredentialType
|
CredentialType ICECredentialType
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s RTCIceServer) parseURL(i int) (*ice.URL, error) {
|
func (s ICEServer) parseURL(i int) (*ice.URL, error) {
|
||||||
return ice.ParseURL(s.URLs[i])
|
return ice.ParseURL(s.URLs[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s RTCIceServer) validate() ([]*ice.URL, error) {
|
func (s ICEServer) validate() ([]*ice.URL, error) {
|
||||||
urls := []*ice.URL{}
|
urls := []*ice.URL{}
|
||||||
|
|
||||||
for i := range s.URLs {
|
for i := range s.URLs {
|
||||||
@@ -34,15 +34,15 @@ func (s RTCIceServer) validate() ([]*ice.URL, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch s.CredentialType {
|
switch s.CredentialType {
|
||||||
case RTCIceCredentialTypePassword:
|
case ICECredentialTypePassword:
|
||||||
// https://www.w3.org/TR/webrtc/#set-the-configuration (step #11.3.3)
|
// https://www.w3.org/TR/webrtc/#set-the-configuration (step #11.3.3)
|
||||||
if _, ok := s.Credential.(string); !ok {
|
if _, ok := s.Credential.(string); !ok {
|
||||||
return nil, &rtcerr.InvalidAccessError{Err: ErrTurnCredencials}
|
return nil, &rtcerr.InvalidAccessError{Err: ErrTurnCredencials}
|
||||||
}
|
}
|
||||||
|
|
||||||
case RTCIceCredentialTypeOauth:
|
case ICECredentialTypeOauth:
|
||||||
// https://www.w3.org/TR/webrtc/#set-the-configuration (step #11.3.4)
|
// https://www.w3.org/TR/webrtc/#set-the-configuration (step #11.3.4)
|
||||||
if _, ok := s.Credential.(RTCOAuthCredential); !ok {
|
if _, ok := s.Credential.(OAuthCredential); !ok {
|
||||||
return nil, &rtcerr.InvalidAccessError{Err: ErrTurnCredencials}
|
return nil, &rtcerr.InvalidAccessError{Err: ErrTurnCredencials}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,26 +8,26 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRTCIceServer_validate(t *testing.T) {
|
func TestICEServer_validate(t *testing.T) {
|
||||||
t.Run("Success", func(t *testing.T) {
|
t.Run("Success", func(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
iceServer RTCIceServer
|
iceServer ICEServer
|
||||||
expectedValidate bool
|
expectedValidate bool
|
||||||
}{
|
}{
|
||||||
{RTCIceServer{
|
{ICEServer{
|
||||||
URLs: []string{"turn:192.158.29.39?transport=udp"},
|
URLs: []string{"turn:192.158.29.39?transport=udp"},
|
||||||
Username: "unittest",
|
Username: "unittest",
|
||||||
Credential: "placeholder",
|
Credential: "placeholder",
|
||||||
CredentialType: RTCIceCredentialTypePassword,
|
CredentialType: ICECredentialTypePassword,
|
||||||
}, true},
|
}, true},
|
||||||
{RTCIceServer{
|
{ICEServer{
|
||||||
URLs: []string{"turn:192.158.29.39?transport=udp"},
|
URLs: []string{"turn:192.158.29.39?transport=udp"},
|
||||||
Username: "unittest",
|
Username: "unittest",
|
||||||
Credential: RTCOAuthCredential{
|
Credential: OAuthCredential{
|
||||||
MacKey: "WmtzanB3ZW9peFhtdm42NzUzNG0=",
|
MacKey: "WmtzanB3ZW9peFhtdm42NzUzNG0=",
|
||||||
AccessToken: "AAwg3kPHWPfvk9bDFL936wYvkoctMADzQ5VhNDgeMR3+ZlZ35byg972fW8QjpEl7bx91YLBPFsIhsxloWcXPhA==",
|
AccessToken: "AAwg3kPHWPfvk9bDFL936wYvkoctMADzQ5VhNDgeMR3+ZlZ35byg972fW8QjpEl7bx91YLBPFsIhsxloWcXPhA==",
|
||||||
},
|
},
|
||||||
CredentialType: RTCIceCredentialTypeOauth,
|
CredentialType: ICECredentialTypeOauth,
|
||||||
}, true},
|
}, true},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,35 +38,35 @@ func TestRTCIceServer_validate(t *testing.T) {
|
|||||||
})
|
})
|
||||||
t.Run("Failure", func(t *testing.T) {
|
t.Run("Failure", func(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
iceServer RTCIceServer
|
iceServer ICEServer
|
||||||
expectedErr error
|
expectedErr error
|
||||||
}{
|
}{
|
||||||
{RTCIceServer{
|
{ICEServer{
|
||||||
URLs: []string{"turn:192.158.29.39?transport=udp"},
|
URLs: []string{"turn:192.158.29.39?transport=udp"},
|
||||||
}, &rtcerr.InvalidAccessError{Err: ErrNoTurnCredencials}},
|
}, &rtcerr.InvalidAccessError{Err: ErrNoTurnCredencials}},
|
||||||
{RTCIceServer{
|
{ICEServer{
|
||||||
URLs: []string{"turn:192.158.29.39?transport=udp"},
|
URLs: []string{"turn:192.158.29.39?transport=udp"},
|
||||||
Username: "unittest",
|
Username: "unittest",
|
||||||
Credential: false,
|
Credential: false,
|
||||||
CredentialType: RTCIceCredentialTypePassword,
|
CredentialType: ICECredentialTypePassword,
|
||||||
}, &rtcerr.InvalidAccessError{Err: ErrTurnCredencials}},
|
}, &rtcerr.InvalidAccessError{Err: ErrTurnCredencials}},
|
||||||
{RTCIceServer{
|
{ICEServer{
|
||||||
URLs: []string{"turn:192.158.29.39?transport=udp"},
|
URLs: []string{"turn:192.158.29.39?transport=udp"},
|
||||||
Username: "unittest",
|
Username: "unittest",
|
||||||
Credential: false,
|
Credential: false,
|
||||||
CredentialType: RTCIceCredentialTypeOauth,
|
CredentialType: ICECredentialTypeOauth,
|
||||||
}, &rtcerr.InvalidAccessError{Err: ErrTurnCredencials}},
|
}, &rtcerr.InvalidAccessError{Err: ErrTurnCredencials}},
|
||||||
{RTCIceServer{
|
{ICEServer{
|
||||||
URLs: []string{"turn:192.158.29.39?transport=udp"},
|
URLs: []string{"turn:192.158.29.39?transport=udp"},
|
||||||
Username: "unittest",
|
Username: "unittest",
|
||||||
Credential: false,
|
Credential: false,
|
||||||
CredentialType: Unknown,
|
CredentialType: Unknown,
|
||||||
}, &rtcerr.InvalidAccessError{Err: ErrTurnCredencials}},
|
}, &rtcerr.InvalidAccessError{Err: ErrTurnCredencials}},
|
||||||
{RTCIceServer{
|
{ICEServer{
|
||||||
URLs: []string{"stun:google.de?transport=udp"},
|
URLs: []string{"stun:google.de?transport=udp"},
|
||||||
Username: "unittest",
|
Username: "unittest",
|
||||||
Credential: false,
|
Credential: false,
|
||||||
CredentialType: RTCIceCredentialTypeOauth,
|
CredentialType: ICECredentialTypeOauth,
|
||||||
}, &rtcerr.SyntaxError{Err: ice.ErrSTUNQuery}},
|
}, &rtcerr.SyntaxError{Err: ice.ErrSTUNQuery}},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,52 +9,52 @@ import (
|
|||||||
"github.com/pions/webrtc/pkg/ice"
|
"github.com/pions/webrtc/pkg/ice"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RTCIceTransport allows an application access to information about the ICE
|
// ICETransport allows an application access to information about the ICE
|
||||||
// transport over which packets are sent and received.
|
// transport over which packets are sent and received.
|
||||||
type RTCIceTransport struct {
|
type ICETransport struct {
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
|
|
||||||
role RTCIceRole
|
role ICERole
|
||||||
// Component RTCIceComponent
|
// Component ICEComponent
|
||||||
// State RTCIceTransportState
|
// State ICETransportState
|
||||||
// gatheringState RTCIceGathererState
|
// gatheringState ICEGathererState
|
||||||
|
|
||||||
onConnectionStateChangeHdlr func(RTCIceTransportState)
|
onConnectionStateChangeHdlr func(ICETransportState)
|
||||||
|
|
||||||
gatherer *RTCIceGatherer
|
gatherer *ICEGatherer
|
||||||
conn *ice.Conn
|
conn *ice.Conn
|
||||||
mux *mux.Mux
|
mux *mux.Mux
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (t *RTCIceTransport) GetLocalCandidates() []RTCIceCandidate {
|
// func (t *ICETransport) GetLocalCandidates() []ICECandidate {
|
||||||
//
|
//
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// func (t *RTCIceTransport) GetRemoteCandidates() []RTCIceCandidate {
|
// func (t *ICETransport) GetRemoteCandidates() []ICECandidate {
|
||||||
//
|
//
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// func (t *RTCIceTransport) GetSelectedCandidatePair() RTCIceCandidatePair {
|
// func (t *ICETransport) GetSelectedCandidatePair() ICECandidatePair {
|
||||||
//
|
//
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// func (t *RTCIceTransport) GetLocalParameters() RTCIceParameters {
|
// func (t *ICETransport) GetLocalParameters() ICEParameters {
|
||||||
//
|
//
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// func (t *RTCIceTransport) GetRemoteParameters() RTCIceParameters {
|
// func (t *ICETransport) GetRemoteParameters() ICEParameters {
|
||||||
//
|
//
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// NewRTCIceTransport creates a new NewRTCIceTransport.
|
// NewICETransport creates a new NewICETransport.
|
||||||
// This constructor is part of the ORTC API. It is not
|
// This constructor is part of the ORTC API. It is not
|
||||||
// meant to be used together with the basic WebRTC API.
|
// meant to be used together with the basic WebRTC API.
|
||||||
func (api *API) NewRTCIceTransport(gatherer *RTCIceGatherer) *RTCIceTransport {
|
func (api *API) NewICETransport(gatherer *ICEGatherer) *ICETransport {
|
||||||
return &RTCIceTransport{gatherer: gatherer}
|
return &ICETransport{gatherer: gatherer}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start incoming connectivity checks based on its configured role.
|
// Start incoming connectivity checks based on its configured role.
|
||||||
func (t *RTCIceTransport) Start(gatherer *RTCIceGatherer, params RTCIceParameters, role *RTCIceRole) error {
|
func (t *ICETransport) Start(gatherer *ICEGatherer, params ICEParameters, role *ICERole) error {
|
||||||
t.lock.Lock()
|
t.lock.Lock()
|
||||||
defer t.lock.Unlock()
|
defer t.lock.Unlock()
|
||||||
|
|
||||||
@@ -68,14 +68,14 @@ func (t *RTCIceTransport) Start(gatherer *RTCIceGatherer, params RTCIceParameter
|
|||||||
|
|
||||||
agent := t.gatherer.agent
|
agent := t.gatherer.agent
|
||||||
err := agent.OnConnectionStateChange(func(iceState ice.ConnectionState) {
|
err := agent.OnConnectionStateChange(func(iceState ice.ConnectionState) {
|
||||||
t.onConnectionStateChange(newRTCIceTransportStateFromICE(iceState))
|
t.onConnectionStateChange(newICETransportStateFromICE(iceState))
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if role == nil {
|
if role == nil {
|
||||||
controlled := RTCIceRoleControlled
|
controlled := ICERoleControlled
|
||||||
role = &controlled
|
role = &controlled
|
||||||
}
|
}
|
||||||
t.role = *role
|
t.role = *role
|
||||||
@@ -86,12 +86,12 @@ func (t *RTCIceTransport) Start(gatherer *RTCIceGatherer, params RTCIceParameter
|
|||||||
|
|
||||||
var iceConn *ice.Conn
|
var iceConn *ice.Conn
|
||||||
switch *role {
|
switch *role {
|
||||||
case RTCIceRoleControlling:
|
case ICERoleControlling:
|
||||||
iceConn, err = agent.Dial(context.TODO(),
|
iceConn, err = agent.Dial(context.TODO(),
|
||||||
params.UsernameFragment,
|
params.UsernameFragment,
|
||||||
params.Password)
|
params.Password)
|
||||||
|
|
||||||
case RTCIceRoleControlled:
|
case ICERoleControlled:
|
||||||
iceConn, err = agent.Accept(context.TODO(),
|
iceConn, err = agent.Accept(context.TODO(),
|
||||||
params.UsernameFragment,
|
params.UsernameFragment,
|
||||||
params.Password)
|
params.Password)
|
||||||
@@ -112,8 +112,8 @@ func (t *RTCIceTransport) Start(gatherer *RTCIceGatherer, params RTCIceParameter
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop irreversibly stops the RTCIceTransport.
|
// Stop irreversibly stops the ICETransport.
|
||||||
func (t *RTCIceTransport) Stop() error {
|
func (t *ICETransport) Stop() error {
|
||||||
// Close the Mux. This closes the Mux and the underlying ICE conn.
|
// Close the Mux. This closes the Mux and the underlying ICE conn.
|
||||||
t.lock.Lock()
|
t.lock.Lock()
|
||||||
defer t.lock.Unlock()
|
defer t.lock.Unlock()
|
||||||
@@ -126,13 +126,13 @@ func (t *RTCIceTransport) Stop() error {
|
|||||||
|
|
||||||
// OnConnectionStateChange sets a handler that is fired when the ICE
|
// OnConnectionStateChange sets a handler that is fired when the ICE
|
||||||
// connection state changes.
|
// connection state changes.
|
||||||
func (t *RTCIceTransport) OnConnectionStateChange(f func(RTCIceTransportState)) {
|
func (t *ICETransport) OnConnectionStateChange(f func(ICETransportState)) {
|
||||||
t.lock.Lock()
|
t.lock.Lock()
|
||||||
defer t.lock.Unlock()
|
defer t.lock.Unlock()
|
||||||
t.onConnectionStateChangeHdlr = f
|
t.onConnectionStateChangeHdlr = f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RTCIceTransport) onConnectionStateChange(state RTCIceTransportState) {
|
func (t *ICETransport) onConnectionStateChange(state ICETransportState) {
|
||||||
t.lock.RLock()
|
t.lock.RLock()
|
||||||
hdlr := t.onConnectionStateChangeHdlr
|
hdlr := t.onConnectionStateChangeHdlr
|
||||||
t.lock.RUnlock()
|
t.lock.RUnlock()
|
||||||
@@ -142,15 +142,15 @@ func (t *RTCIceTransport) onConnectionStateChange(state RTCIceTransportState) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Role indicates the current role of the ICE transport.
|
// Role indicates the current role of the ICE transport.
|
||||||
func (t *RTCIceTransport) Role() RTCIceRole {
|
func (t *ICETransport) Role() ICERole {
|
||||||
t.lock.RLock()
|
t.lock.RLock()
|
||||||
defer t.lock.RUnlock()
|
defer t.lock.RUnlock()
|
||||||
|
|
||||||
return t.role
|
return t.role
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetRemoteCandidates sets the sequence of candidates associated with the remote RTCIceTransport.
|
// SetRemoteCandidates sets the sequence of candidates associated with the remote ICETransport.
|
||||||
func (t *RTCIceTransport) SetRemoteCandidates(remoteCandidates []RTCIceCandidate) error {
|
func (t *ICETransport) SetRemoteCandidates(remoteCandidates []ICECandidate) error {
|
||||||
t.lock.RLock()
|
t.lock.RLock()
|
||||||
defer t.lock.RUnlock()
|
defer t.lock.RUnlock()
|
||||||
|
|
||||||
@@ -172,8 +172,8 @@ func (t *RTCIceTransport) SetRemoteCandidates(remoteCandidates []RTCIceCandidate
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddRemoteCandidate adds a candidate associated with the remote RTCIceTransport.
|
// AddRemoteCandidate adds a candidate associated with the remote ICETransport.
|
||||||
func (t *RTCIceTransport) AddRemoteCandidate(remoteCandidate RTCIceCandidate) error {
|
func (t *ICETransport) AddRemoteCandidate(remoteCandidate ICECandidate) error {
|
||||||
t.lock.RLock()
|
t.lock.RLock()
|
||||||
defer t.lock.RUnlock()
|
defer t.lock.RUnlock()
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ func (t *RTCIceTransport) AddRemoteCandidate(remoteCandidate RTCIceCandidate) er
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RTCIceTransport) ensureGatherer() error {
|
func (t *ICETransport) ensureGatherer() error {
|
||||||
if t.gatherer == nil ||
|
if t.gatherer == nil ||
|
||||||
t.gatherer.agent == nil {
|
t.gatherer.agent == nil {
|
||||||
return errors.New("Gatherer not started")
|
return errors.New("Gatherer not started")
|
||||||
|
@@ -1,41 +1,41 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCIceTransportPolicy defines the ICE candidate policy surface the
|
// ICETransportPolicy defines the ICE candidate policy surface the
|
||||||
// permitted candidates. Only these candidates are used for connectivity checks.
|
// permitted candidates. Only these candidates are used for connectivity checks.
|
||||||
type RTCIceTransportPolicy int
|
type ICETransportPolicy int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCIceTransportPolicyRelay indicates only media relay candidates such
|
// ICETransportPolicyRelay indicates only media relay candidates such
|
||||||
// as candidates passing through a TURN server are used.
|
// as candidates passing through a TURN server are used.
|
||||||
RTCIceTransportPolicyRelay RTCIceTransportPolicy = iota + 1
|
ICETransportPolicyRelay ICETransportPolicy = iota + 1
|
||||||
|
|
||||||
// RTCIceTransportPolicyAll indicates any type of candidate is used.
|
// ICETransportPolicyAll indicates any type of candidate is used.
|
||||||
RTCIceTransportPolicyAll
|
ICETransportPolicyAll
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is done this way because of a linter.
|
// This is done this way because of a linter.
|
||||||
const (
|
const (
|
||||||
rtcIceTransportPolicyRelayStr = "relay"
|
iceTransportPolicyRelayStr = "relay"
|
||||||
rtcIceTransportPolicyAllStr = "all"
|
iceTransportPolicyAllStr = "all"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRTCIceTransportPolicy(raw string) RTCIceTransportPolicy {
|
func newICETransportPolicy(raw string) ICETransportPolicy {
|
||||||
switch raw {
|
switch raw {
|
||||||
case rtcIceTransportPolicyRelayStr:
|
case iceTransportPolicyRelayStr:
|
||||||
return RTCIceTransportPolicyRelay
|
return ICETransportPolicyRelay
|
||||||
case rtcIceTransportPolicyAllStr:
|
case iceTransportPolicyAllStr:
|
||||||
return RTCIceTransportPolicyAll
|
return ICETransportPolicyAll
|
||||||
default:
|
default:
|
||||||
return RTCIceTransportPolicy(Unknown)
|
return ICETransportPolicy(Unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t RTCIceTransportPolicy) String() string {
|
func (t ICETransportPolicy) String() string {
|
||||||
switch t {
|
switch t {
|
||||||
case RTCIceTransportPolicyRelay:
|
case ICETransportPolicyRelay:
|
||||||
return rtcIceTransportPolicyRelayStr
|
return iceTransportPolicyRelayStr
|
||||||
case RTCIceTransportPolicyAll:
|
case ICETransportPolicyAll:
|
||||||
return rtcIceTransportPolicyAllStr
|
return iceTransportPolicyAllStr
|
||||||
default:
|
default:
|
||||||
return ErrUnknownType.Error()
|
return ErrUnknownType.Error()
|
||||||
}
|
}
|
||||||
|
@@ -6,33 +6,33 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewRTCIceTransportPolicy(t *testing.T) {
|
func TestNewICETransportPolicy(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
policyString string
|
policyString string
|
||||||
expectedPolicy RTCIceTransportPolicy
|
expectedPolicy ICETransportPolicy
|
||||||
}{
|
}{
|
||||||
{unknownStr, RTCIceTransportPolicy(Unknown)},
|
{unknownStr, ICETransportPolicy(Unknown)},
|
||||||
{"relay", RTCIceTransportPolicyRelay},
|
{"relay", ICETransportPolicyRelay},
|
||||||
{"all", RTCIceTransportPolicyAll},
|
{"all", ICETransportPolicyAll},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
testCase.expectedPolicy,
|
testCase.expectedPolicy,
|
||||||
newRTCIceTransportPolicy(testCase.policyString),
|
newICETransportPolicy(testCase.policyString),
|
||||||
"testCase: %d %v", i, testCase,
|
"testCase: %d %v", i, testCase,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCIceTransportPolicy_String(t *testing.T) {
|
func TestICETransportPolicy_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
policy RTCIceTransportPolicy
|
policy ICETransportPolicy
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCIceTransportPolicy(Unknown), unknownStr},
|
{ICETransportPolicy(Unknown), unknownStr},
|
||||||
{RTCIceTransportPolicyRelay, "relay"},
|
{ICETransportPolicyRelay, "relay"},
|
||||||
{RTCIceTransportPolicyAll, "all"},
|
{ICETransportPolicyAll, "all"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@@ -2,104 +2,104 @@ package webrtc
|
|||||||
|
|
||||||
import "github.com/pions/webrtc/pkg/ice"
|
import "github.com/pions/webrtc/pkg/ice"
|
||||||
|
|
||||||
// RTCIceTransportState represents the current state of the ICE transport.
|
// ICETransportState represents the current state of the ICE transport.
|
||||||
type RTCIceTransportState int
|
type ICETransportState int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCIceTransportStateNew indicates the RTCIceTransport is waiting
|
// ICETransportStateNew indicates the ICETransport is waiting
|
||||||
// for remote candidates to be supplied.
|
// for remote candidates to be supplied.
|
||||||
RTCIceTransportStateNew = iota + 1
|
ICETransportStateNew = iota + 1
|
||||||
|
|
||||||
// RTCIceTransportStateChecking indicates the RTCIceTransport has
|
// ICETransportStateChecking indicates the ICETransport has
|
||||||
// received at least one remote candidate, and a local and remote
|
// received at least one remote candidate, and a local and remote
|
||||||
// RTCIceCandidateComplete dictionary was not added as the last candidate.
|
// ICECandidateComplete dictionary was not added as the last candidate.
|
||||||
RTCIceTransportStateChecking
|
ICETransportStateChecking
|
||||||
|
|
||||||
// RTCIceTransportStateConnected indicates the RTCIceTransport has
|
// ICETransportStateConnected indicates the ICETransport has
|
||||||
// received a response to an outgoing connectivity check, or has
|
// received a response to an outgoing connectivity check, or has
|
||||||
// received incoming DTLS/media after a successful response to an
|
// received incoming DTLS/media after a successful response to an
|
||||||
// incoming connectivity check, but is still checking other candidate
|
// incoming connectivity check, but is still checking other candidate
|
||||||
// pairs to see if there is a better connection.
|
// pairs to see if there is a better connection.
|
||||||
RTCIceTransportStateConnected
|
ICETransportStateConnected
|
||||||
|
|
||||||
// RTCIceTransportStateCompleted indicates the RTCIceTransport tested
|
// ICETransportStateCompleted indicates the ICETransport tested
|
||||||
// all appropriate candidate pairs and at least one functioning
|
// all appropriate candidate pairs and at least one functioning
|
||||||
// candidate pair has been found.
|
// candidate pair has been found.
|
||||||
RTCIceTransportStateCompleted
|
ICETransportStateCompleted
|
||||||
|
|
||||||
// RTCIceTransportStateFailed indicates the RTCIceTransport the last
|
// ICETransportStateFailed indicates the ICETransport the last
|
||||||
// candidate was added and all appropriate candidate pairs have either
|
// candidate was added and all appropriate candidate pairs have either
|
||||||
// failed connectivity checks or have lost consent.
|
// failed connectivity checks or have lost consent.
|
||||||
RTCIceTransportStateFailed
|
ICETransportStateFailed
|
||||||
|
|
||||||
// RTCIceTransportStateDisconnected indicates the RTCIceTransport has received
|
// ICETransportStateDisconnected indicates the ICETransport has received
|
||||||
// at least one local and remote candidate, but the final candidate was
|
// at least one local and remote candidate, but the final candidate was
|
||||||
// received yet and all appropriate candidate pairs thus far have been
|
// received yet and all appropriate candidate pairs thus far have been
|
||||||
// tested and failed.
|
// tested and failed.
|
||||||
RTCIceTransportStateDisconnected
|
ICETransportStateDisconnected
|
||||||
|
|
||||||
// RTCIceTransportStateClosed indicates the RTCIceTransport has shut down
|
// ICETransportStateClosed indicates the ICETransport has shut down
|
||||||
// and is no longer responding to STUN requests.
|
// and is no longer responding to STUN requests.
|
||||||
RTCIceTransportStateClosed
|
ICETransportStateClosed
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c RTCIceTransportState) String() string {
|
func (c ICETransportState) String() string {
|
||||||
switch c {
|
switch c {
|
||||||
case RTCIceTransportStateNew:
|
case ICETransportStateNew:
|
||||||
return "new"
|
return "new"
|
||||||
case RTCIceTransportStateChecking:
|
case ICETransportStateChecking:
|
||||||
return "checking"
|
return "checking"
|
||||||
case RTCIceTransportStateConnected:
|
case ICETransportStateConnected:
|
||||||
return "connected"
|
return "connected"
|
||||||
case RTCIceTransportStateCompleted:
|
case ICETransportStateCompleted:
|
||||||
return "completed"
|
return "completed"
|
||||||
case RTCIceTransportStateFailed:
|
case ICETransportStateFailed:
|
||||||
return "failed"
|
return "failed"
|
||||||
case RTCIceTransportStateDisconnected:
|
case ICETransportStateDisconnected:
|
||||||
return "disconnected"
|
return "disconnected"
|
||||||
case RTCIceTransportStateClosed:
|
case ICETransportStateClosed:
|
||||||
return "closed"
|
return "closed"
|
||||||
default:
|
default:
|
||||||
return unknownStr
|
return unknownStr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRTCIceTransportStateFromICE(i ice.ConnectionState) RTCIceTransportState {
|
func newICETransportStateFromICE(i ice.ConnectionState) ICETransportState {
|
||||||
switch i {
|
switch i {
|
||||||
case ice.ConnectionStateNew:
|
case ice.ConnectionStateNew:
|
||||||
return RTCIceTransportStateNew
|
return ICETransportStateNew
|
||||||
case ice.ConnectionStateChecking:
|
case ice.ConnectionStateChecking:
|
||||||
return RTCIceTransportStateChecking
|
return ICETransportStateChecking
|
||||||
case ice.ConnectionStateConnected:
|
case ice.ConnectionStateConnected:
|
||||||
return RTCIceTransportStateConnected
|
return ICETransportStateConnected
|
||||||
case ice.ConnectionStateCompleted:
|
case ice.ConnectionStateCompleted:
|
||||||
return RTCIceTransportStateCompleted
|
return ICETransportStateCompleted
|
||||||
case ice.ConnectionStateFailed:
|
case ice.ConnectionStateFailed:
|
||||||
return RTCIceTransportStateFailed
|
return ICETransportStateFailed
|
||||||
case ice.ConnectionStateDisconnected:
|
case ice.ConnectionStateDisconnected:
|
||||||
return RTCIceTransportStateDisconnected
|
return ICETransportStateDisconnected
|
||||||
case ice.ConnectionStateClosed:
|
case ice.ConnectionStateClosed:
|
||||||
return RTCIceTransportStateClosed
|
return ICETransportStateClosed
|
||||||
default:
|
default:
|
||||||
return RTCIceTransportState(Unknown)
|
return ICETransportState(Unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c RTCIceTransportState) toICE() ice.ConnectionState {
|
func (c ICETransportState) toICE() ice.ConnectionState {
|
||||||
switch c {
|
switch c {
|
||||||
case RTCIceTransportStateNew:
|
case ICETransportStateNew:
|
||||||
return ice.ConnectionStateNew
|
return ice.ConnectionStateNew
|
||||||
case RTCIceTransportStateChecking:
|
case ICETransportStateChecking:
|
||||||
return ice.ConnectionStateChecking
|
return ice.ConnectionStateChecking
|
||||||
case RTCIceTransportStateConnected:
|
case ICETransportStateConnected:
|
||||||
return ice.ConnectionStateConnected
|
return ice.ConnectionStateConnected
|
||||||
case RTCIceTransportStateCompleted:
|
case ICETransportStateCompleted:
|
||||||
return ice.ConnectionStateCompleted
|
return ice.ConnectionStateCompleted
|
||||||
case RTCIceTransportStateFailed:
|
case ICETransportStateFailed:
|
||||||
return ice.ConnectionStateFailed
|
return ice.ConnectionStateFailed
|
||||||
case RTCIceTransportStateDisconnected:
|
case ICETransportStateDisconnected:
|
||||||
return ice.ConnectionStateDisconnected
|
return ice.ConnectionStateDisconnected
|
||||||
case RTCIceTransportStateClosed:
|
case ICETransportStateClosed:
|
||||||
return ice.ConnectionStateClosed
|
return ice.ConnectionStateClosed
|
||||||
default:
|
default:
|
||||||
return ice.ConnectionState(Unknown)
|
return ice.ConnectionState(Unknown)
|
||||||
|
@@ -7,19 +7,19 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRTCIceTransportState_String(t *testing.T) {
|
func TestICETransportState_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
state RTCIceTransportState
|
state ICETransportState
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCIceTransportState(Unknown), unknownStr},
|
{ICETransportState(Unknown), unknownStr},
|
||||||
{RTCIceTransportStateNew, "new"},
|
{ICETransportStateNew, "new"},
|
||||||
{RTCIceTransportStateChecking, "checking"},
|
{ICETransportStateChecking, "checking"},
|
||||||
{RTCIceTransportStateConnected, "connected"},
|
{ICETransportStateConnected, "connected"},
|
||||||
{RTCIceTransportStateCompleted, "completed"},
|
{ICETransportStateCompleted, "completed"},
|
||||||
{RTCIceTransportStateFailed, "failed"},
|
{ICETransportStateFailed, "failed"},
|
||||||
{RTCIceTransportStateDisconnected, "disconnected"},
|
{ICETransportStateDisconnected, "disconnected"},
|
||||||
{RTCIceTransportStateClosed, "closed"},
|
{ICETransportStateClosed, "closed"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
@@ -31,19 +31,19 @@ func TestRTCIceTransportState_String(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCIceTransportState_Convert(t *testing.T) {
|
func TestICETransportState_Convert(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
native RTCIceTransportState
|
native ICETransportState
|
||||||
ice ice.ConnectionState
|
ice ice.ConnectionState
|
||||||
}{
|
}{
|
||||||
{RTCIceTransportState(Unknown), ice.ConnectionState(Unknown)},
|
{ICETransportState(Unknown), ice.ConnectionState(Unknown)},
|
||||||
{RTCIceTransportStateNew, ice.ConnectionStateNew},
|
{ICETransportStateNew, ice.ConnectionStateNew},
|
||||||
{RTCIceTransportStateChecking, ice.ConnectionStateChecking},
|
{ICETransportStateChecking, ice.ConnectionStateChecking},
|
||||||
{RTCIceTransportStateConnected, ice.ConnectionStateConnected},
|
{ICETransportStateConnected, ice.ConnectionStateConnected},
|
||||||
{RTCIceTransportStateCompleted, ice.ConnectionStateCompleted},
|
{ICETransportStateCompleted, ice.ConnectionStateCompleted},
|
||||||
{RTCIceTransportStateFailed, ice.ConnectionStateFailed},
|
{ICETransportStateFailed, ice.ConnectionStateFailed},
|
||||||
{RTCIceTransportStateDisconnected, ice.ConnectionStateDisconnected},
|
{ICETransportStateDisconnected, ice.ConnectionStateDisconnected},
|
||||||
{RTCIceTransportStateClosed, ice.ConnectionStateClosed},
|
{ICETransportStateClosed, ice.ConnectionStateClosed},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
@@ -54,7 +54,7 @@ func TestRTCIceTransportState_Convert(t *testing.T) {
|
|||||||
)
|
)
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
testCase.native,
|
testCase.native,
|
||||||
newRTCIceTransportStateFromICE(testCase.ice),
|
newICETransportStateFromICE(testCase.ice),
|
||||||
"testCase: %d %v", i, testCase,
|
"testCase: %d %v", i, testCase,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCOAuthCredential represents OAuth credential information which is used by
|
// OAuthCredential represents OAuth credential information which is used by
|
||||||
// the STUN/TURN client to connect to an ICE server as defined in
|
// the STUN/TURN client to connect to an ICE server as defined in
|
||||||
// https://tools.ietf.org/html/rfc7635. Note that the kid parameter is not
|
// https://tools.ietf.org/html/rfc7635. Note that the kid parameter is not
|
||||||
// located in RTCOAuthCredential, but in RTCIceServer's username member.
|
// located in OAuthCredential, but in ICEServer's username member.
|
||||||
type RTCOAuthCredential struct {
|
type OAuthCredential struct {
|
||||||
// MacKey is a base64-url encoded format. It is used in STUN message
|
// MacKey is a base64-url encoded format. It is used in STUN message
|
||||||
// integrity hash calculation.
|
// integrity hash calculation.
|
||||||
MacKey string
|
MacKey string
|
||||||
|
@@ -1,26 +1,26 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCOfferAnswerOptions is a base structure which describes the options that
|
// OfferAnswerOptions is a base structure which describes the options that
|
||||||
// can be used to control the offer/answer creation process.
|
// can be used to control the offer/answer creation process.
|
||||||
type RTCOfferAnswerOptions struct {
|
type OfferAnswerOptions struct {
|
||||||
// VoiceActivityDetection allows the application to provide information
|
// VoiceActivityDetection allows the application to provide information
|
||||||
// about whether it wishes voice detection feature to be enabled or disabled.
|
// about whether it wishes voice detection feature to be enabled or disabled.
|
||||||
VoiceActivityDetection bool
|
VoiceActivityDetection bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTCAnswerOptions structure describes the options used to control the answer
|
// AnswerOptions structure describes the options used to control the answer
|
||||||
// creation process.
|
// creation process.
|
||||||
type RTCAnswerOptions struct {
|
type AnswerOptions struct {
|
||||||
RTCOfferAnswerOptions
|
OfferAnswerOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTCOfferOptions structure describes the options used to control the offer
|
// OfferOptions structure describes the options used to control the offer
|
||||||
// creation process
|
// creation process
|
||||||
type RTCOfferOptions struct {
|
type OfferOptions struct {
|
||||||
RTCOfferAnswerOptions
|
OfferAnswerOptions
|
||||||
|
|
||||||
// IceRestart forces the underlying ice gathering process to be restarted.
|
// ICERestart forces the underlying ice gathering process to be restarted.
|
||||||
// When this value is true, the generated description will have ICE
|
// When this value is true, the generated description will have ICE
|
||||||
// credentials that are different from the current credentials
|
// credentials that are different from the current credentials
|
||||||
IceRestart bool
|
ICERestart bool
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -7,10 +7,10 @@ import (
|
|||||||
"github.com/pions/transport/test"
|
"github.com/pions/transport/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestRTCPeerConnection_Close is moved to it's on file because the tests
|
// TestPeerConnection_Close is moved to it's on file because the tests
|
||||||
// in rtcpeerconnection_test.go are leaky, making the goroutine report useless.
|
// in rtcpeerconnection_test.go are leaky, making the goroutine report useless.
|
||||||
|
|
||||||
func TestRTCPeerConnection_Close(t *testing.T) {
|
func TestPeerConnection_Close(t *testing.T) {
|
||||||
api := NewAPI()
|
api := NewAPI()
|
||||||
|
|
||||||
// Limit runtime in case of deadlocks
|
// Limit runtime in case of deadlocks
|
||||||
@@ -26,7 +26,7 @@ func TestRTCPeerConnection_Close(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
awaitSetup := make(chan struct{})
|
awaitSetup := make(chan struct{})
|
||||||
pcAnswer.OnDataChannel(func(d *RTCDataChannel) {
|
pcAnswer.OnDataChannel(func(d *DataChannel) {
|
||||||
close(awaitSetup)
|
close(awaitSetup)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@@ -12,7 +12,7 @@ import (
|
|||||||
"github.com/pions/webrtc/pkg/media"
|
"github.com/pions/webrtc/pkg/media"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRTCPeerConnection_Media_Sample(t *testing.T) {
|
func TestPeerConnection_Media_Sample(t *testing.T) {
|
||||||
api := NewAPI()
|
api := NewAPI()
|
||||||
lim := test.TimeOut(time.Second * 30)
|
lim := test.TimeOut(time.Second * 30)
|
||||||
defer lim.Stop()
|
defer lim.Stop()
|
||||||
@@ -36,7 +36,7 @@ func TestRTCPeerConnection_Media_Sample(t *testing.T) {
|
|||||||
awaitRTCPRecieverRecv := make(chan bool)
|
awaitRTCPRecieverRecv := make(chan bool)
|
||||||
awaitRTCPRecieverSend := make(chan error)
|
awaitRTCPRecieverSend := make(chan error)
|
||||||
|
|
||||||
pcAnswer.OnTrack(func(track *RTCTrack) {
|
pcAnswer.OnTrack(func(track *Track) {
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
time.Sleep(time.Millisecond * 100)
|
time.Sleep(time.Millisecond * 100)
|
||||||
@@ -72,7 +72,7 @@ func TestRTCPeerConnection_Media_Sample(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
vp8Track, err := pcOffer.NewRTCSampleTrack(DefaultPayloadTypeVP8, "video", "pion")
|
vp8Track, err := pcOffer.NewSampleTrack(DefaultPayloadTypeVP8, "video", "pion")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -83,7 +83,7 @@ func TestRTCPeerConnection_Media_Sample(t *testing.T) {
|
|||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
time.Sleep(time.Millisecond * 100)
|
time.Sleep(time.Millisecond * 100)
|
||||||
vp8Track.Samples <- media.RTCSample{Data: []byte{0x00}, Samples: 1}
|
vp8Track.Samples <- media.Sample{Data: []byte{0x00}, Samples: 1}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-awaitRTPRecv:
|
case <-awaitRTPRecv:
|
||||||
@@ -149,14 +149,14 @@ func TestRTCPeerConnection_Media_Sample(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
RTCPeerConnection should be able to be torn down at anytime
|
PeerConnection should be able to be torn down at anytime
|
||||||
This test adds an input track and asserts
|
This test adds an input track and asserts
|
||||||
|
|
||||||
* OnTrack doesn't fire since no video packets will arrive
|
* OnTrack doesn't fire since no video packets will arrive
|
||||||
* No goroutine leaks
|
* No goroutine leaks
|
||||||
* No deadlocks on shutdown
|
* No deadlocks on shutdown
|
||||||
*/
|
*/
|
||||||
func TestRTCPeerConnection_Media_Shutdown(t *testing.T) {
|
func TestPeerConnection_Media_Shutdown(t *testing.T) {
|
||||||
iceComplete := make(chan bool)
|
iceComplete := make(chan bool)
|
||||||
|
|
||||||
api := NewAPI()
|
api := NewAPI()
|
||||||
@@ -172,11 +172,11 @@ func TestRTCPeerConnection_Media_Shutdown(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
opusTrack, err := pcOffer.NewRTCSampleTrack(DefaultPayloadTypeOpus, "audio", "pion1")
|
opusTrack, err := pcOffer.NewSampleTrack(DefaultPayloadTypeOpus, "audio", "pion1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
vp8Track, err := pcOffer.NewRTCSampleTrack(DefaultPayloadTypeVP8, "video", "pion2")
|
vp8Track, err := pcOffer.NewSampleTrack(DefaultPayloadTypeVP8, "video", "pion2")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -190,7 +190,7 @@ func TestRTCPeerConnection_Media_Shutdown(t *testing.T) {
|
|||||||
var onTrackFiredLock sync.RWMutex
|
var onTrackFiredLock sync.RWMutex
|
||||||
onTrackFired := false
|
onTrackFired := false
|
||||||
|
|
||||||
pcAnswer.OnTrack(func(track *RTCTrack) {
|
pcAnswer.OnTrack(func(track *Track) {
|
||||||
onTrackFiredLock.Lock()
|
onTrackFiredLock.Lock()
|
||||||
defer onTrackFiredLock.Unlock()
|
defer onTrackFiredLock.Unlock()
|
||||||
onTrackFired = true
|
onTrackFired = true
|
||||||
@@ -199,7 +199,7 @@ func TestRTCPeerConnection_Media_Shutdown(t *testing.T) {
|
|||||||
pcAnswer.OnICEConnectionStateChange(func(iceState ice.ConnectionState) {
|
pcAnswer.OnICEConnectionStateChange(func(iceState ice.ConnectionState) {
|
||||||
if iceState == ice.ConnectionStateConnected {
|
if iceState == ice.ConnectionStateConnected {
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(3 * time.Second) // TODO RTCPeerConnection.Close() doesn't block for all subsystems
|
time.Sleep(3 * time.Second) // TODO PeerConnection.Close() doesn't block for all subsystems
|
||||||
close(iceComplete)
|
close(iceComplete)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@@ -224,7 +224,7 @@ func TestRTCPeerConnection_Media_Shutdown(t *testing.T) {
|
|||||||
|
|
||||||
onTrackFiredLock.Lock()
|
onTrackFiredLock.Lock()
|
||||||
if onTrackFired {
|
if onTrackFired {
|
||||||
t.Fatalf("RTCPeerConnection OnTrack fired even though we got no packets")
|
t.Fatalf("PeerConnection OnTrack fired even though we got no packets")
|
||||||
}
|
}
|
||||||
onTrackFiredLock.Unlock()
|
onTrackFiredLock.Unlock()
|
||||||
|
|
||||||
|
@@ -17,13 +17,13 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (api *API) newPair() (pcOffer *RTCPeerConnection, pcAnswer *RTCPeerConnection, err error) {
|
func (api *API) newPair() (pcOffer *PeerConnection, pcAnswer *PeerConnection, err error) {
|
||||||
pca, err := api.NewRTCPeerConnection(RTCConfiguration{})
|
pca, err := api.NewPeerConnection(Configuration{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pcb, err := api.NewRTCPeerConnection(RTCConfiguration{})
|
pcb, err := api.NewPeerConnection(Configuration{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@ func (api *API) newPair() (pcOffer *RTCPeerConnection, pcAnswer *RTCPeerConnecti
|
|||||||
return pca, pcb, nil
|
return pca, pcb, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func signalPair(pcOffer *RTCPeerConnection, pcAnswer *RTCPeerConnection) error {
|
func signalPair(pcOffer *PeerConnection, pcAnswer *PeerConnection) error {
|
||||||
offer, err := pcOffer.CreateOffer(nil)
|
offer, err := pcOffer.CreateOffer(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -72,41 +72,41 @@ func TestNew(t *testing.T) {
|
|||||||
certificate, err := GenerateCertificate(secretKey)
|
certificate, err := GenerateCertificate(secretKey)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
pc, err := api.NewRTCPeerConnection(RTCConfiguration{
|
pc, err := api.NewPeerConnection(Configuration{
|
||||||
IceServers: []RTCIceServer{
|
ICEServers: []ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{
|
URLs: []string{
|
||||||
"stun:stun.l.google.com:19302",
|
"stun:stun.l.google.com:19302",
|
||||||
"turns:google.de?transport=tcp",
|
"turns:google.de?transport=tcp",
|
||||||
},
|
},
|
||||||
Username: "unittest",
|
Username: "unittest",
|
||||||
Credential: RTCOAuthCredential{
|
Credential: OAuthCredential{
|
||||||
MacKey: "WmtzanB3ZW9peFhtdm42NzUzNG0=",
|
MacKey: "WmtzanB3ZW9peFhtdm42NzUzNG0=",
|
||||||
AccessToken: "AAwg3kPHWPfvk9bDFL936wYvkoctMADzQ==",
|
AccessToken: "AAwg3kPHWPfvk9bDFL936wYvkoctMADzQ==",
|
||||||
},
|
},
|
||||||
CredentialType: RTCIceCredentialTypeOauth,
|
CredentialType: ICECredentialTypeOauth,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
IceTransportPolicy: RTCIceTransportPolicyRelay,
|
ICETransportPolicy: ICETransportPolicyRelay,
|
||||||
BundlePolicy: RTCBundlePolicyMaxCompat,
|
BundlePolicy: BundlePolicyMaxCompat,
|
||||||
RtcpMuxPolicy: RTCRtcpMuxPolicyNegotiate,
|
RTCPMuxPolicy: RTCPMuxPolicyNegotiate,
|
||||||
PeerIdentity: "unittest",
|
PeerIdentity: "unittest",
|
||||||
Certificates: []RTCCertificate{*certificate},
|
Certificates: []Certificate{*certificate},
|
||||||
IceCandidatePoolSize: 5,
|
ICECandidatePoolSize: 5,
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.NotNil(t, pc)
|
assert.NotNil(t, pc)
|
||||||
})
|
})
|
||||||
t.Run("Failure", func(t *testing.T) {
|
t.Run("Failure", func(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
initialize func() (*RTCPeerConnection, error)
|
initialize func() (*PeerConnection, error)
|
||||||
expectedErr error
|
expectedErr error
|
||||||
}{
|
}{
|
||||||
{func() (*RTCPeerConnection, error) {
|
{func() (*PeerConnection, error) {
|
||||||
secretKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
secretKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
certificate, err := NewRTCCertificate(secretKey, x509.Certificate{
|
certificate, err := NewCertificate(secretKey, x509.Certificate{
|
||||||
Version: 2,
|
Version: 2,
|
||||||
SerialNumber: big.NewInt(1653),
|
SerialNumber: big.NewInt(1653),
|
||||||
NotBefore: time.Now().AddDate(0, -2, 0),
|
NotBefore: time.Now().AddDate(0, -2, 0),
|
||||||
@@ -114,13 +114,13 @@ func TestNew(t *testing.T) {
|
|||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
return api.NewRTCPeerConnection(RTCConfiguration{
|
return api.NewPeerConnection(Configuration{
|
||||||
Certificates: []RTCCertificate{*certificate},
|
Certificates: []Certificate{*certificate},
|
||||||
})
|
})
|
||||||
}, &rtcerr.InvalidAccessError{Err: ErrCertificateExpired}},
|
}, &rtcerr.InvalidAccessError{Err: ErrCertificateExpired}},
|
||||||
{func() (*RTCPeerConnection, error) {
|
{func() (*PeerConnection, error) {
|
||||||
return api.NewRTCPeerConnection(RTCConfiguration{
|
return api.NewPeerConnection(Configuration{
|
||||||
IceServers: []RTCIceServer{
|
ICEServers: []ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{
|
URLs: []string{
|
||||||
"stun:stun.l.google.com:19302",
|
"stun:stun.l.google.com:19302",
|
||||||
@@ -142,7 +142,7 @@ func TestNew(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCPeerConnection_SetConfiguration(t *testing.T) {
|
func TestPeerConnection_SetConfiguration(t *testing.T) {
|
||||||
api := NewAPI()
|
api := NewAPI()
|
||||||
t.Run("Success", func(t *testing.T) {
|
t.Run("Success", func(t *testing.T) {
|
||||||
secretKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
secretKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
@@ -151,63 +151,63 @@ func TestRTCPeerConnection_SetConfiguration(t *testing.T) {
|
|||||||
certificate, err := GenerateCertificate(secretKey)
|
certificate, err := GenerateCertificate(secretKey)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
pc, err := api.NewRTCPeerConnection(RTCConfiguration{
|
pc, err := api.NewPeerConnection(Configuration{
|
||||||
PeerIdentity: "unittest",
|
PeerIdentity: "unittest",
|
||||||
Certificates: []RTCCertificate{*certificate},
|
Certificates: []Certificate{*certificate},
|
||||||
IceCandidatePoolSize: 5,
|
ICECandidatePoolSize: 5,
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
err = pc.SetConfiguration(RTCConfiguration{
|
err = pc.SetConfiguration(Configuration{
|
||||||
IceServers: []RTCIceServer{
|
ICEServers: []ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{
|
URLs: []string{
|
||||||
"stun:stun.l.google.com:19302",
|
"stun:stun.l.google.com:19302",
|
||||||
"turns:google.de?transport=tcp",
|
"turns:google.de?transport=tcp",
|
||||||
},
|
},
|
||||||
Username: "unittest",
|
Username: "unittest",
|
||||||
Credential: RTCOAuthCredential{
|
Credential: OAuthCredential{
|
||||||
MacKey: "WmtzanB3ZW9peFhtdm42NzUzNG0=",
|
MacKey: "WmtzanB3ZW9peFhtdm42NzUzNG0=",
|
||||||
AccessToken: "AAwg3kPHWPfvk9bDFL936wYvkoctMADzQ==",
|
AccessToken: "AAwg3kPHWPfvk9bDFL936wYvkoctMADzQ==",
|
||||||
},
|
},
|
||||||
CredentialType: RTCIceCredentialTypeOauth,
|
CredentialType: ICECredentialTypeOauth,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
IceTransportPolicy: RTCIceTransportPolicyAll,
|
ICETransportPolicy: ICETransportPolicyAll,
|
||||||
BundlePolicy: RTCBundlePolicyBalanced,
|
BundlePolicy: BundlePolicyBalanced,
|
||||||
RtcpMuxPolicy: RTCRtcpMuxPolicyRequire,
|
RTCPMuxPolicy: RTCPMuxPolicyRequire,
|
||||||
PeerIdentity: "unittest",
|
PeerIdentity: "unittest",
|
||||||
Certificates: []RTCCertificate{*certificate},
|
Certificates: []Certificate{*certificate},
|
||||||
IceCandidatePoolSize: 5,
|
ICECandidatePoolSize: 5,
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
})
|
})
|
||||||
t.Run("Failure", func(t *testing.T) {
|
t.Run("Failure", func(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
initialize func() (*RTCPeerConnection, error)
|
initialize func() (*PeerConnection, error)
|
||||||
updatingConfig func() RTCConfiguration
|
updatingConfig func() Configuration
|
||||||
expectedErr error
|
expectedErr error
|
||||||
}{
|
}{
|
||||||
{func() (*RTCPeerConnection, error) {
|
{func() (*PeerConnection, error) {
|
||||||
pc, err := api.NewRTCPeerConnection(RTCConfiguration{})
|
pc, err := api.NewPeerConnection(Configuration{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
err = pc.Close()
|
err = pc.Close()
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
return pc, err
|
return pc, err
|
||||||
}, func() RTCConfiguration {
|
}, func() Configuration {
|
||||||
return RTCConfiguration{}
|
return Configuration{}
|
||||||
}, &rtcerr.InvalidStateError{Err: ErrConnectionClosed}},
|
}, &rtcerr.InvalidStateError{Err: ErrConnectionClosed}},
|
||||||
{func() (*RTCPeerConnection, error) {
|
{func() (*PeerConnection, error) {
|
||||||
return api.NewRTCPeerConnection(RTCConfiguration{})
|
return api.NewPeerConnection(Configuration{})
|
||||||
}, func() RTCConfiguration {
|
}, func() Configuration {
|
||||||
return RTCConfiguration{
|
return Configuration{
|
||||||
PeerIdentity: "unittest",
|
PeerIdentity: "unittest",
|
||||||
}
|
}
|
||||||
}, &rtcerr.InvalidModificationError{Err: ErrModifyingPeerIdentity}},
|
}, &rtcerr.InvalidModificationError{Err: ErrModifyingPeerIdentity}},
|
||||||
{func() (*RTCPeerConnection, error) {
|
{func() (*PeerConnection, error) {
|
||||||
return api.NewRTCPeerConnection(RTCConfiguration{})
|
return api.NewPeerConnection(Configuration{})
|
||||||
}, func() RTCConfiguration {
|
}, func() Configuration {
|
||||||
secretKey1, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
secretKey1, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
@@ -220,43 +220,43 @@ func TestRTCPeerConnection_SetConfiguration(t *testing.T) {
|
|||||||
certificate2, err := GenerateCertificate(secretKey2)
|
certificate2, err := GenerateCertificate(secretKey2)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
return RTCConfiguration{
|
return Configuration{
|
||||||
Certificates: []RTCCertificate{*certificate1, *certificate2},
|
Certificates: []Certificate{*certificate1, *certificate2},
|
||||||
}
|
}
|
||||||
}, &rtcerr.InvalidModificationError{Err: ErrModifyingCertificates}},
|
}, &rtcerr.InvalidModificationError{Err: ErrModifyingCertificates}},
|
||||||
{func() (*RTCPeerConnection, error) {
|
{func() (*PeerConnection, error) {
|
||||||
return api.NewRTCPeerConnection(RTCConfiguration{})
|
return api.NewPeerConnection(Configuration{})
|
||||||
}, func() RTCConfiguration {
|
}, func() Configuration {
|
||||||
secretKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
secretKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
certificate, err := GenerateCertificate(secretKey)
|
certificate, err := GenerateCertificate(secretKey)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
return RTCConfiguration{
|
return Configuration{
|
||||||
Certificates: []RTCCertificate{*certificate},
|
Certificates: []Certificate{*certificate},
|
||||||
}
|
}
|
||||||
}, &rtcerr.InvalidModificationError{Err: ErrModifyingCertificates}},
|
}, &rtcerr.InvalidModificationError{Err: ErrModifyingCertificates}},
|
||||||
{func() (*RTCPeerConnection, error) {
|
{func() (*PeerConnection, error) {
|
||||||
return api.NewRTCPeerConnection(RTCConfiguration{})
|
return api.NewPeerConnection(Configuration{})
|
||||||
}, func() RTCConfiguration {
|
}, func() Configuration {
|
||||||
return RTCConfiguration{
|
return Configuration{
|
||||||
BundlePolicy: RTCBundlePolicyMaxCompat,
|
BundlePolicy: BundlePolicyMaxCompat,
|
||||||
}
|
}
|
||||||
}, &rtcerr.InvalidModificationError{Err: ErrModifyingBundlePolicy}},
|
}, &rtcerr.InvalidModificationError{Err: ErrModifyingBundlePolicy}},
|
||||||
{func() (*RTCPeerConnection, error) {
|
{func() (*PeerConnection, error) {
|
||||||
return api.NewRTCPeerConnection(RTCConfiguration{})
|
return api.NewPeerConnection(Configuration{})
|
||||||
}, func() RTCConfiguration {
|
}, func() Configuration {
|
||||||
return RTCConfiguration{
|
return Configuration{
|
||||||
RtcpMuxPolicy: RTCRtcpMuxPolicyNegotiate,
|
RTCPMuxPolicy: RTCPMuxPolicyNegotiate,
|
||||||
}
|
}
|
||||||
}, &rtcerr.InvalidModificationError{Err: ErrModifyingRtcpMuxPolicy}},
|
}, &rtcerr.InvalidModificationError{Err: ErrModifyingRTCPMuxPolicy}},
|
||||||
// TODO Unittest for IceCandidatePoolSize cannot be done now needs pc.LocalDescription()
|
// TODO Unittest for ICECandidatePoolSize cannot be done now needs pc.LocalDescription()
|
||||||
{func() (*RTCPeerConnection, error) {
|
{func() (*PeerConnection, error) {
|
||||||
return api.NewRTCPeerConnection(RTCConfiguration{})
|
return api.NewPeerConnection(Configuration{})
|
||||||
}, func() RTCConfiguration {
|
}, func() Configuration {
|
||||||
return RTCConfiguration{
|
return Configuration{
|
||||||
IceServers: []RTCIceServer{
|
ICEServers: []ICEServer{
|
||||||
{
|
{
|
||||||
URLs: []string{
|
URLs: []string{
|
||||||
"stun:stun.l.google.com:19302",
|
"stun:stun.l.google.com:19302",
|
||||||
@@ -281,35 +281,35 @@ func TestRTCPeerConnection_SetConfiguration(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCPeerConnection_GetConfiguration(t *testing.T) {
|
func TestPeerConnection_GetConfiguration(t *testing.T) {
|
||||||
api := NewAPI()
|
api := NewAPI()
|
||||||
pc, err := api.NewRTCPeerConnection(RTCConfiguration{})
|
pc, err := api.NewPeerConnection(Configuration{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
expected := RTCConfiguration{
|
expected := Configuration{
|
||||||
IceServers: []RTCIceServer{},
|
ICEServers: []ICEServer{},
|
||||||
IceTransportPolicy: RTCIceTransportPolicyAll,
|
ICETransportPolicy: ICETransportPolicyAll,
|
||||||
BundlePolicy: RTCBundlePolicyBalanced,
|
BundlePolicy: BundlePolicyBalanced,
|
||||||
RtcpMuxPolicy: RTCRtcpMuxPolicyRequire,
|
RTCPMuxPolicy: RTCPMuxPolicyRequire,
|
||||||
Certificates: []RTCCertificate{},
|
Certificates: []Certificate{},
|
||||||
IceCandidatePoolSize: 0,
|
ICECandidatePoolSize: 0,
|
||||||
}
|
}
|
||||||
actual := pc.GetConfiguration()
|
actual := pc.GetConfiguration()
|
||||||
assert.True(t, &expected != &actual)
|
assert.True(t, &expected != &actual)
|
||||||
assert.Equal(t, expected.IceServers, actual.IceServers)
|
assert.Equal(t, expected.ICEServers, actual.ICEServers)
|
||||||
assert.Equal(t, expected.IceTransportPolicy, actual.IceTransportPolicy)
|
assert.Equal(t, expected.ICETransportPolicy, actual.ICETransportPolicy)
|
||||||
assert.Equal(t, expected.BundlePolicy, actual.BundlePolicy)
|
assert.Equal(t, expected.BundlePolicy, actual.BundlePolicy)
|
||||||
assert.Equal(t, expected.RtcpMuxPolicy, actual.RtcpMuxPolicy)
|
assert.Equal(t, expected.RTCPMuxPolicy, actual.RTCPMuxPolicy)
|
||||||
assert.NotEqual(t, len(expected.Certificates), len(actual.Certificates))
|
assert.NotEqual(t, len(expected.Certificates), len(actual.Certificates))
|
||||||
assert.Equal(t, expected.IceCandidatePoolSize, actual.IceCandidatePoolSize)
|
assert.Equal(t, expected.ICECandidatePoolSize, actual.ICECandidatePoolSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - This unittest needs to be completed when CreateDataChannel is complete
|
// TODO - This unittest needs to be completed when CreateDataChannel is complete
|
||||||
// func TestRTCPeerConnection_CreateDataChannel(t *testing.T) {
|
// func TestPeerConnection_CreateDataChannel(t *testing.T) {
|
||||||
// pc, err := New(RTCConfiguration{})
|
// pc, err := New(Configuration{})
|
||||||
// assert.Nil(t, err)
|
// assert.Nil(t, err)
|
||||||
//
|
//
|
||||||
// _, err = pc.CreateDataChannel("data", &RTCDataChannelInit{
|
// _, err = pc.CreateDataChannel("data", &DataChannelInit{
|
||||||
//
|
//
|
||||||
// })
|
// })
|
||||||
// assert.Nil(t, err)
|
// assert.Nil(t, err)
|
||||||
@@ -336,13 +336,13 @@ a=rtpmap:96 VP8/90000
|
|||||||
func TestSetRemoteDescription(t *testing.T) {
|
func TestSetRemoteDescription(t *testing.T) {
|
||||||
api := NewAPI()
|
api := NewAPI()
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc RTCSessionDescription
|
desc SessionDescription
|
||||||
}{
|
}{
|
||||||
{RTCSessionDescription{Type: RTCSdpTypeOffer, Sdp: minimalOffer}},
|
{SessionDescription{Type: SDPTypeOffer, Sdp: minimalOffer}},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
peerConn, err := api.NewRTCPeerConnection(RTCConfiguration{})
|
peerConn, err := api.NewPeerConnection(Configuration{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Case %d: got error: %v", i, err)
|
t.Errorf("Case %d: got error: %v", i, err)
|
||||||
}
|
}
|
||||||
@@ -355,9 +355,9 @@ func TestSetRemoteDescription(t *testing.T) {
|
|||||||
|
|
||||||
func TestCreateOfferAnswer(t *testing.T) {
|
func TestCreateOfferAnswer(t *testing.T) {
|
||||||
api := NewAPI()
|
api := NewAPI()
|
||||||
offerPeerConn, err := api.NewRTCPeerConnection(RTCConfiguration{})
|
offerPeerConn, err := api.NewPeerConnection(Configuration{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("New RTCPeerConnection: got error: %v", err)
|
t.Errorf("New PeerConnection: got error: %v", err)
|
||||||
}
|
}
|
||||||
offer, err := offerPeerConn.CreateOffer(nil)
|
offer, err := offerPeerConn.CreateOffer(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -366,9 +366,9 @@ func TestCreateOfferAnswer(t *testing.T) {
|
|||||||
if err = offerPeerConn.SetLocalDescription(offer); err != nil {
|
if err = offerPeerConn.SetLocalDescription(offer); err != nil {
|
||||||
t.Errorf("SetLocalDescription: got error: %v", err)
|
t.Errorf("SetLocalDescription: got error: %v", err)
|
||||||
}
|
}
|
||||||
answerPeerConn, err := api.NewRTCPeerConnection(RTCConfiguration{})
|
answerPeerConn, err := api.NewPeerConnection(Configuration{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("New RTCPeerConnection: got error: %v", err)
|
t.Errorf("New PeerConnection: got error: %v", err)
|
||||||
}
|
}
|
||||||
err = answerPeerConn.SetRemoteDescription(offer)
|
err = answerPeerConn.SetRemoteDescription(offer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -387,11 +387,11 @@ func TestCreateOfferAnswer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCPeerConnection_NewRawRTPTrack(t *testing.T) {
|
func TestPeerConnection_NewRawRTPTrack(t *testing.T) {
|
||||||
api := NewAPI()
|
api := NewAPI()
|
||||||
api.mediaEngine.RegisterDefaultCodecs()
|
api.mediaEngine.RegisterDefaultCodecs()
|
||||||
|
|
||||||
pc, err := api.NewRTCPeerConnection(RTCConfiguration{})
|
pc, err := api.NewPeerConnection(Configuration{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
_, err = pc.NewRawRTPTrack(DefaultPayloadTypeH264, 0, "trackId", "trackLabel")
|
_, err = pc.NewRawRTPTrack(DefaultPayloadTypeH264, 0, "trackId", "trackLabel")
|
||||||
@@ -405,7 +405,7 @@ func TestRTCPeerConnection_NewRawRTPTrack(t *testing.T) {
|
|||||||
|
|
||||||
// This channel should not be set up for a RawRTP track
|
// This channel should not be set up for a RawRTP track
|
||||||
assert.Panics(t, func() {
|
assert.Panics(t, func() {
|
||||||
track.Samples <- media.RTCSample{}
|
track.Samples <- media.Sample{}
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.NotPanics(t, func() {
|
assert.NotPanics(t, func() {
|
||||||
@@ -413,32 +413,32 @@ func TestRTCPeerConnection_NewRawRTPTrack(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCPeerConnection_NewRTCSampleTrack(t *testing.T) {
|
func TestPeerConnection_NewSampleTrack(t *testing.T) {
|
||||||
api := NewAPI()
|
api := NewAPI()
|
||||||
api.mediaEngine.RegisterDefaultCodecs()
|
api.mediaEngine.RegisterDefaultCodecs()
|
||||||
|
|
||||||
pc, err := api.NewRTCPeerConnection(RTCConfiguration{})
|
pc, err := api.NewPeerConnection(Configuration{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
track, err := pc.NewRTCSampleTrack(DefaultPayloadTypeH264, "trackId", "trackLabel")
|
track, err := pc.NewSampleTrack(DefaultPayloadTypeH264, "trackId", "trackLabel")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
_, err = pc.AddTrack(track)
|
_, err = pc.AddTrack(track)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
// This channel should not be set up for a RTCSample track
|
// This channel should not be set up for a Sample track
|
||||||
assert.Panics(t, func() {
|
assert.Panics(t, func() {
|
||||||
track.RawRTP <- &rtp.Packet{}
|
track.RawRTP <- &rtp.Packet{}
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.NotPanics(t, func() {
|
assert.NotPanics(t, func() {
|
||||||
track.Samples <- media.RTCSample{}
|
track.Samples <- media.Sample{}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCPeerConnection_EventHandlers(t *testing.T) {
|
func TestPeerConnection_EventHandlers(t *testing.T) {
|
||||||
api := NewAPI()
|
api := NewAPI()
|
||||||
pc, err := api.NewRTCPeerConnection(RTCConfiguration{})
|
pc, err := api.NewPeerConnection(Configuration{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
onTrackCalled := make(chan bool)
|
onTrackCalled := make(chan bool)
|
||||||
@@ -449,7 +449,7 @@ func TestRTCPeerConnection_EventHandlers(t *testing.T) {
|
|||||||
assert.NotPanics(t, func() { pc.onTrack(nil) })
|
assert.NotPanics(t, func() { pc.onTrack(nil) })
|
||||||
assert.NotPanics(t, func() { pc.onICEConnectionStateChange(ice.ConnectionStateNew) })
|
assert.NotPanics(t, func() { pc.onICEConnectionStateChange(ice.ConnectionStateNew) })
|
||||||
|
|
||||||
pc.OnTrack(func(t *RTCTrack) {
|
pc.OnTrack(func(t *Track) {
|
||||||
onTrackCalled <- true
|
onTrackCalled <- true
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -457,7 +457,7 @@ func TestRTCPeerConnection_EventHandlers(t *testing.T) {
|
|||||||
onICEConnectionStateChangeCalled <- true
|
onICEConnectionStateChangeCalled <- true
|
||||||
})
|
})
|
||||||
|
|
||||||
pc.OnDataChannel(func(dc *RTCDataChannel) {
|
pc.OnDataChannel(func(dc *DataChannel) {
|
||||||
onDataChannelCalled <- true
|
onDataChannelCalled <- true
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -466,9 +466,9 @@ func TestRTCPeerConnection_EventHandlers(t *testing.T) {
|
|||||||
assert.NotPanics(t, func() { go pc.onDataChannelHandler(nil) })
|
assert.NotPanics(t, func() { go pc.onDataChannelHandler(nil) })
|
||||||
|
|
||||||
// Verify that the set handlers are called
|
// Verify that the set handlers are called
|
||||||
assert.NotPanics(t, func() { pc.onTrack(&RTCTrack{}) })
|
assert.NotPanics(t, func() { pc.onTrack(&Track{}) })
|
||||||
assert.NotPanics(t, func() { pc.onICEConnectionStateChange(ice.ConnectionStateNew) })
|
assert.NotPanics(t, func() { pc.onICEConnectionStateChange(ice.ConnectionStateNew) })
|
||||||
assert.NotPanics(t, func() { go pc.onDataChannelHandler(&RTCDataChannel{api: api}) })
|
assert.NotPanics(t, func() { go pc.onDataChannelHandler(&DataChannel{api: api}) })
|
||||||
|
|
||||||
allTrue := func(vals []bool) bool {
|
allTrue := func(vals []bool) bool {
|
||||||
for _, val := range vals {
|
for _, val := range vals {
|
||||||
|
@@ -1,82 +1,82 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCPeerConnectionState indicates the state of the RTCPeerConnection.
|
// PeerConnectionState indicates the state of the PeerConnection.
|
||||||
type RTCPeerConnectionState int
|
type PeerConnectionState int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCPeerConnectionStateNew indicates that any of the RTCIceTransports or
|
// PeerConnectionStateNew indicates that any of the ICETransports or
|
||||||
// RTCDtlsTransports are in the "new" state and none of the transports are
|
// DTLSTransports are in the "new" state and none of the transports are
|
||||||
// in the "connecting", "checking", "failed" or "disconnected" state, or
|
// in the "connecting", "checking", "failed" or "disconnected" state, or
|
||||||
// all transports are in the "closed" state, or there are no transports.
|
// all transports are in the "closed" state, or there are no transports.
|
||||||
RTCPeerConnectionStateNew RTCPeerConnectionState = iota + 1
|
PeerConnectionStateNew PeerConnectionState = iota + 1
|
||||||
|
|
||||||
// RTCPeerConnectionStateConnecting indicates that any of the
|
// PeerConnectionStateConnecting indicates that any of the
|
||||||
// RTCIceTransports or RTCDtlsTransports are in the "connecting" or
|
// ICETransports or DTLSTransports are in the "connecting" or
|
||||||
// "checking" state and none of them is in the "failed" state.
|
// "checking" state and none of them is in the "failed" state.
|
||||||
RTCPeerConnectionStateConnecting
|
PeerConnectionStateConnecting
|
||||||
|
|
||||||
// RTCPeerConnectionStateConnected indicates that all RTCIceTransports and
|
// PeerConnectionStateConnected indicates that all ICETransports and
|
||||||
// RTCDtlsTransports are in the "connected", "completed" or "closed" state
|
// DTLSTransports are in the "connected", "completed" or "closed" state
|
||||||
// and at least one of them is in the "connected" or "completed" state.
|
// and at least one of them is in the "connected" or "completed" state.
|
||||||
RTCPeerConnectionStateConnected
|
PeerConnectionStateConnected
|
||||||
|
|
||||||
// RTCPeerConnectionStateDisconnected indicates that any of the
|
// PeerConnectionStateDisconnected indicates that any of the
|
||||||
// RTCIceTransports or RTCDtlsTransports are in the "disconnected" state
|
// ICETransports or DTLSTransports are in the "disconnected" state
|
||||||
// and none of them are in the "failed" or "connecting" or "checking" state.
|
// and none of them are in the "failed" or "connecting" or "checking" state.
|
||||||
RTCPeerConnectionStateDisconnected
|
PeerConnectionStateDisconnected
|
||||||
|
|
||||||
// RTCPeerConnectionStateFailed indicates that any of the RTCIceTransports
|
// PeerConnectionStateFailed indicates that any of the ICETransports
|
||||||
// or RTCDtlsTransports are in a "failed" state.
|
// or DTLSTransports are in a "failed" state.
|
||||||
RTCPeerConnectionStateFailed
|
PeerConnectionStateFailed
|
||||||
|
|
||||||
// RTCPeerConnectionStateClosed indicates the peer connection is closed
|
// PeerConnectionStateClosed indicates the peer connection is closed
|
||||||
// and the isClosed member variable of RTCPeerConnection is true.
|
// and the isClosed member variable of PeerConnection is true.
|
||||||
RTCPeerConnectionStateClosed
|
PeerConnectionStateClosed
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is done this way because of a linter.
|
// This is done this way because of a linter.
|
||||||
const (
|
const (
|
||||||
rtcPeerConnectionStateNewStr = "new"
|
peerConnectionStateNewStr = "new"
|
||||||
rtcPeerConnectionStateConnectingStr = "connecting"
|
peerConnectionStateConnectingStr = "connecting"
|
||||||
rtcPeerConnectionStateConnectedStr = "connected"
|
peerConnectionStateConnectedStr = "connected"
|
||||||
rtcPeerConnectionStateDisconnectedStr = "disconnected"
|
peerConnectionStateDisconnectedStr = "disconnected"
|
||||||
rtcPeerConnectionStateFailedStr = "failed"
|
peerConnectionStateFailedStr = "failed"
|
||||||
rtcPeerConnectionStateClosedStr = "closed"
|
peerConnectionStateClosedStr = "closed"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRTCPeerConnectionState(raw string) RTCPeerConnectionState {
|
func newPeerConnectionState(raw string) PeerConnectionState {
|
||||||
switch raw {
|
switch raw {
|
||||||
case rtcPeerConnectionStateNewStr:
|
case peerConnectionStateNewStr:
|
||||||
return RTCPeerConnectionStateNew
|
return PeerConnectionStateNew
|
||||||
case rtcPeerConnectionStateConnectingStr:
|
case peerConnectionStateConnectingStr:
|
||||||
return RTCPeerConnectionStateConnecting
|
return PeerConnectionStateConnecting
|
||||||
case rtcPeerConnectionStateConnectedStr:
|
case peerConnectionStateConnectedStr:
|
||||||
return RTCPeerConnectionStateConnected
|
return PeerConnectionStateConnected
|
||||||
case rtcPeerConnectionStateDisconnectedStr:
|
case peerConnectionStateDisconnectedStr:
|
||||||
return RTCPeerConnectionStateDisconnected
|
return PeerConnectionStateDisconnected
|
||||||
case rtcPeerConnectionStateFailedStr:
|
case peerConnectionStateFailedStr:
|
||||||
return RTCPeerConnectionStateFailed
|
return PeerConnectionStateFailed
|
||||||
case rtcPeerConnectionStateClosedStr:
|
case peerConnectionStateClosedStr:
|
||||||
return RTCPeerConnectionStateClosed
|
return PeerConnectionStateClosed
|
||||||
default:
|
default:
|
||||||
return RTCPeerConnectionState(Unknown)
|
return PeerConnectionState(Unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t RTCPeerConnectionState) String() string {
|
func (t PeerConnectionState) String() string {
|
||||||
switch t {
|
switch t {
|
||||||
case RTCPeerConnectionStateNew:
|
case PeerConnectionStateNew:
|
||||||
return rtcPeerConnectionStateNewStr
|
return peerConnectionStateNewStr
|
||||||
case RTCPeerConnectionStateConnecting:
|
case PeerConnectionStateConnecting:
|
||||||
return rtcPeerConnectionStateConnectingStr
|
return peerConnectionStateConnectingStr
|
||||||
case RTCPeerConnectionStateConnected:
|
case PeerConnectionStateConnected:
|
||||||
return rtcPeerConnectionStateConnectedStr
|
return peerConnectionStateConnectedStr
|
||||||
case RTCPeerConnectionStateDisconnected:
|
case PeerConnectionStateDisconnected:
|
||||||
return rtcPeerConnectionStateDisconnectedStr
|
return peerConnectionStateDisconnectedStr
|
||||||
case RTCPeerConnectionStateFailed:
|
case PeerConnectionStateFailed:
|
||||||
return rtcPeerConnectionStateFailedStr
|
return peerConnectionStateFailedStr
|
||||||
case RTCPeerConnectionStateClosed:
|
case PeerConnectionStateClosed:
|
||||||
return rtcPeerConnectionStateClosedStr
|
return peerConnectionStateClosedStr
|
||||||
default:
|
default:
|
||||||
return ErrUnknownType.Error()
|
return ErrUnknownType.Error()
|
||||||
}
|
}
|
||||||
|
@@ -6,41 +6,41 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewRTCPeerConnectionState(t *testing.T) {
|
func TestNewPeerConnectionState(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
stateString string
|
stateString string
|
||||||
expectedState RTCPeerConnectionState
|
expectedState PeerConnectionState
|
||||||
}{
|
}{
|
||||||
{unknownStr, RTCPeerConnectionState(Unknown)},
|
{unknownStr, PeerConnectionState(Unknown)},
|
||||||
{"new", RTCPeerConnectionStateNew},
|
{"new", PeerConnectionStateNew},
|
||||||
{"connecting", RTCPeerConnectionStateConnecting},
|
{"connecting", PeerConnectionStateConnecting},
|
||||||
{"connected", RTCPeerConnectionStateConnected},
|
{"connected", PeerConnectionStateConnected},
|
||||||
{"disconnected", RTCPeerConnectionStateDisconnected},
|
{"disconnected", PeerConnectionStateDisconnected},
|
||||||
{"failed", RTCPeerConnectionStateFailed},
|
{"failed", PeerConnectionStateFailed},
|
||||||
{"closed", RTCPeerConnectionStateClosed},
|
{"closed", PeerConnectionStateClosed},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
testCase.expectedState,
|
testCase.expectedState,
|
||||||
newRTCPeerConnectionState(testCase.stateString),
|
newPeerConnectionState(testCase.stateString),
|
||||||
"testCase: %d %v", i, testCase,
|
"testCase: %d %v", i, testCase,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCPeerConnectionState_String(t *testing.T) {
|
func TestPeerConnectionState_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
state RTCPeerConnectionState
|
state PeerConnectionState
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCPeerConnectionState(Unknown), unknownStr},
|
{PeerConnectionState(Unknown), unknownStr},
|
||||||
{RTCPeerConnectionStateNew, "new"},
|
{PeerConnectionStateNew, "new"},
|
||||||
{RTCPeerConnectionStateConnecting, "connecting"},
|
{PeerConnectionStateConnecting, "connecting"},
|
||||||
{RTCPeerConnectionStateConnected, "connected"},
|
{PeerConnectionStateConnected, "connected"},
|
||||||
{RTCPeerConnectionStateDisconnected, "disconnected"},
|
{PeerConnectionStateDisconnected, "disconnected"},
|
||||||
{RTCPeerConnectionStateFailed, "failed"},
|
{PeerConnectionStateFailed, "failed"},
|
||||||
{RTCPeerConnectionStateClosed, "closed"},
|
{PeerConnectionStateClosed, "closed"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@@ -1,70 +1,70 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCPriorityType determines the priority type of a data channel.
|
// PriorityType determines the priority type of a data channel.
|
||||||
type RTCPriorityType int
|
type PriorityType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCPriorityTypeVeryLow corresponds to "below normal".
|
// PriorityTypeVeryLow corresponds to "below normal".
|
||||||
RTCPriorityTypeVeryLow RTCPriorityType = iota + 1
|
PriorityTypeVeryLow PriorityType = iota + 1
|
||||||
|
|
||||||
// RTCPriorityTypeLow corresponds to "normal".
|
// PriorityTypeLow corresponds to "normal".
|
||||||
RTCPriorityTypeLow
|
PriorityTypeLow
|
||||||
|
|
||||||
// RTCPriorityTypeMedium corresponds to "high".
|
// PriorityTypeMedium corresponds to "high".
|
||||||
RTCPriorityTypeMedium
|
PriorityTypeMedium
|
||||||
|
|
||||||
// RTCPriorityTypeHigh corresponds to "extra high".
|
// PriorityTypeHigh corresponds to "extra high".
|
||||||
RTCPriorityTypeHigh
|
PriorityTypeHigh
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is done this way because of a linter.
|
// This is done this way because of a linter.
|
||||||
const (
|
const (
|
||||||
rtcPriorityTypeVeryLowStr = "very-low"
|
priorityTypeVeryLowStr = "very-low"
|
||||||
rtcPriorityTypeLowStr = "low"
|
priorityTypeLowStr = "low"
|
||||||
rtcPriorityTypeMediumStr = "medium"
|
priorityTypeMediumStr = "medium"
|
||||||
rtcPriorityTypeHighStr = "high"
|
priorityTypeHighStr = "high"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRTCPriorityTypeFromString(raw string) RTCPriorityType {
|
func newPriorityTypeFromString(raw string) PriorityType {
|
||||||
switch raw {
|
switch raw {
|
||||||
case rtcPriorityTypeVeryLowStr:
|
case priorityTypeVeryLowStr:
|
||||||
return RTCPriorityTypeVeryLow
|
return PriorityTypeVeryLow
|
||||||
case rtcPriorityTypeLowStr:
|
case priorityTypeLowStr:
|
||||||
return RTCPriorityTypeLow
|
return PriorityTypeLow
|
||||||
case rtcPriorityTypeMediumStr:
|
case priorityTypeMediumStr:
|
||||||
return RTCPriorityTypeMedium
|
return PriorityTypeMedium
|
||||||
case rtcPriorityTypeHighStr:
|
case priorityTypeHighStr:
|
||||||
return RTCPriorityTypeHigh
|
return PriorityTypeHigh
|
||||||
default:
|
default:
|
||||||
return RTCPriorityType(Unknown)
|
return PriorityType(Unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRTCPriorityTypeFromUint16(raw uint16) RTCPriorityType {
|
func newPriorityTypeFromUint16(raw uint16) PriorityType {
|
||||||
switch {
|
switch {
|
||||||
case raw <= 128:
|
case raw <= 128:
|
||||||
return RTCPriorityTypeVeryLow
|
return PriorityTypeVeryLow
|
||||||
case 129 <= raw && raw <= 256:
|
case 129 <= raw && raw <= 256:
|
||||||
return RTCPriorityTypeLow
|
return PriorityTypeLow
|
||||||
case 257 <= raw && raw <= 512:
|
case 257 <= raw && raw <= 512:
|
||||||
return RTCPriorityTypeMedium
|
return PriorityTypeMedium
|
||||||
case 513 <= raw:
|
case 513 <= raw:
|
||||||
return RTCPriorityTypeHigh
|
return PriorityTypeHigh
|
||||||
default:
|
default:
|
||||||
return RTCPriorityType(Unknown)
|
return PriorityType(Unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p RTCPriorityType) String() string {
|
func (p PriorityType) String() string {
|
||||||
switch p {
|
switch p {
|
||||||
case RTCPriorityTypeVeryLow:
|
case PriorityTypeVeryLow:
|
||||||
return rtcPriorityTypeVeryLowStr
|
return priorityTypeVeryLowStr
|
||||||
case RTCPriorityTypeLow:
|
case PriorityTypeLow:
|
||||||
return rtcPriorityTypeLowStr
|
return priorityTypeLowStr
|
||||||
case RTCPriorityTypeMedium:
|
case PriorityTypeMedium:
|
||||||
return rtcPriorityTypeMediumStr
|
return priorityTypeMediumStr
|
||||||
case RTCPriorityTypeHigh:
|
case PriorityTypeHigh:
|
||||||
return rtcPriorityTypeHighStr
|
return priorityTypeHighStr
|
||||||
default:
|
default:
|
||||||
return ErrUnknownType.Error()
|
return ErrUnknownType.Error()
|
||||||
}
|
}
|
||||||
|
@@ -6,49 +6,49 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewRTCPriorityType(t *testing.T) {
|
func TestNewPriorityType(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
priorityString string
|
priorityString string
|
||||||
priorityUint16 uint16
|
priorityUint16 uint16
|
||||||
expectedPriority RTCPriorityType
|
expectedPriority PriorityType
|
||||||
}{
|
}{
|
||||||
{unknownStr, 0, RTCPriorityType(Unknown)},
|
{unknownStr, 0, PriorityType(Unknown)},
|
||||||
{"very-low", 100, RTCPriorityTypeVeryLow},
|
{"very-low", 100, PriorityTypeVeryLow},
|
||||||
{"low", 200, RTCPriorityTypeLow},
|
{"low", 200, PriorityTypeLow},
|
||||||
{"medium", 300, RTCPriorityTypeMedium},
|
{"medium", 300, PriorityTypeMedium},
|
||||||
{"high", 1000, RTCPriorityTypeHigh},
|
{"high", 1000, PriorityTypeHigh},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
testCase.expectedPriority,
|
testCase.expectedPriority,
|
||||||
newRTCPriorityTypeFromString(testCase.priorityString),
|
newPriorityTypeFromString(testCase.priorityString),
|
||||||
"testCase: %d %v", i, testCase,
|
"testCase: %d %v", i, testCase,
|
||||||
)
|
)
|
||||||
|
|
||||||
// There is no uint that produces generate RTCPriorityType(Unknown).
|
// There is no uint that produces generate PriorityType(Unknown).
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
testCase.expectedPriority,
|
testCase.expectedPriority,
|
||||||
newRTCPriorityTypeFromUint16(testCase.priorityUint16),
|
newPriorityTypeFromUint16(testCase.priorityUint16),
|
||||||
"testCase: %d %v", i, testCase,
|
"testCase: %d %v", i, testCase,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCPriorityType_String(t *testing.T) {
|
func TestPriorityType_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
priority RTCPriorityType
|
priority PriorityType
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCPriorityType(Unknown), unknownStr},
|
{PriorityType(Unknown), unknownStr},
|
||||||
{RTCPriorityTypeVeryLow, "very-low"},
|
{PriorityTypeVeryLow, "very-low"},
|
||||||
{RTCPriorityTypeLow, "low"},
|
{PriorityTypeLow, "low"},
|
||||||
{RTCPriorityTypeMedium, "medium"},
|
{PriorityTypeMedium, "medium"},
|
||||||
{RTCPriorityTypeHigh, "high"},
|
{PriorityTypeHigh, "high"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCQuicParameters holds information relating to QUIC configuration.
|
// QUICParameters holds information relating to QUIC configuration.
|
||||||
type RTCQuicParameters struct {
|
type QUICParameters struct {
|
||||||
Role RTCQuicRole `json:"role"`
|
Role QUICRole `json:"role"`
|
||||||
Fingerprints []RTCDtlsFingerprint `json:"fingerprints"`
|
Fingerprints []DTLSFingerprint `json:"fingerprints"`
|
||||||
}
|
}
|
||||||
|
@@ -1,28 +1,28 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCQuicRole indicates the role of the Quic transport.
|
// QUICRole indicates the role of the Quic transport.
|
||||||
type RTCQuicRole byte
|
type QUICRole byte
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCQuicRoleAuto defines the Quic role is determined based on
|
// QUICRoleAuto defines the Quic role is determined based on
|
||||||
// the resolved ICE role: the ICE controlled role acts as the Quic
|
// the resolved ICE role: the ICE controlled role acts as the Quic
|
||||||
// client and the ICE controlling role acts as the Quic server.
|
// client and the ICE controlling role acts as the Quic server.
|
||||||
RTCQuicRoleAuto RTCQuicRole = iota + 1
|
QUICRoleAuto QUICRole = iota + 1
|
||||||
|
|
||||||
// RTCQuicRoleClient defines the Quic client role.
|
// QUICRoleClient defines the Quic client role.
|
||||||
RTCQuicRoleClient
|
QUICRoleClient
|
||||||
|
|
||||||
// RTCQuicRoleServer defines the Quic server role.
|
// QUICRoleServer defines the Quic server role.
|
||||||
RTCQuicRoleServer
|
QUICRoleServer
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r RTCQuicRole) String() string {
|
func (r QUICRole) String() string {
|
||||||
switch r {
|
switch r {
|
||||||
case RTCQuicRoleAuto:
|
case QUICRoleAuto:
|
||||||
return "auto"
|
return "auto"
|
||||||
case RTCQuicRoleClient:
|
case QUICRoleClient:
|
||||||
return "client"
|
return "client"
|
||||||
case RTCQuicRoleServer:
|
case QUICRoleServer:
|
||||||
return "server"
|
return "server"
|
||||||
default:
|
default:
|
||||||
return unknownStr
|
return unknownStr
|
||||||
|
@@ -6,15 +6,15 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRTCQuicRole_String(t *testing.T) {
|
func TestQUICRole_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
role RTCQuicRole
|
role QUICRole
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCQuicRole(Unknown), unknownStr},
|
{QUICRole(Unknown), unknownStr},
|
||||||
{RTCQuicRoleAuto, "auto"},
|
{QUICRoleAuto, "auto"},
|
||||||
{RTCQuicRoleClient, "client"},
|
{QUICRoleClient, "client"},
|
||||||
{RTCQuicRoleServer, "server"},
|
{QUICRoleServer, "server"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@@ -17,25 +17,25 @@ import (
|
|||||||
"github.com/pions/webrtc/pkg/rtcerr"
|
"github.com/pions/webrtc/pkg/rtcerr"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RTCQuicTransport is a specialization of QuicTransportBase focused on
|
// QUICTransport is a specialization of QuicTransportBase focused on
|
||||||
// peer-to-peer use cases and includes information relating to use of a
|
// peer-to-peer use cases and includes information relating to use of a
|
||||||
// QUIC transport with an ICE transport.
|
// QUIC transport with an ICE transport.
|
||||||
type RTCQuicTransport struct {
|
type QUICTransport struct {
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
quic.TransportBase
|
quic.TransportBase
|
||||||
|
|
||||||
iceTransport *RTCIceTransport
|
iceTransport *ICETransport
|
||||||
certificates []RTCCertificate
|
certificates []Certificate
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRTCQuicTransport creates a new RTCQuicTransport.
|
// NewQUICTransport creates a new QUICTransport.
|
||||||
// This constructor is part of the ORTC API. It is not
|
// This constructor is part of the ORTC API. It is not
|
||||||
// meant to be used together with the basic WebRTC API.
|
// meant to be used together with the basic WebRTC API.
|
||||||
// Note that the Quic transport is a draft and therefore
|
// Note that the Quic transport is a draft and therefore
|
||||||
// highly experimental. It is currently not supported by
|
// highly experimental. It is currently not supported by
|
||||||
// any browsers yet.
|
// any browsers yet.
|
||||||
func (api *API) NewRTCQuicTransport(transport *RTCIceTransport, certificates []RTCCertificate) (*RTCQuicTransport, error) {
|
func (api *API) NewQUICTransport(transport *ICETransport, certificates []Certificate) (*QUICTransport, error) {
|
||||||
t := &RTCQuicTransport{iceTransport: transport}
|
t := &QUICTransport{iceTransport: transport}
|
||||||
|
|
||||||
if len(certificates) > 0 {
|
if len(certificates) > 0 {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
@@ -54,29 +54,29 @@ func (api *API) NewRTCQuicTransport(transport *RTCIceTransport, certificates []R
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
t.certificates = []RTCCertificate{*certificate}
|
t.certificates = []Certificate{*certificate}
|
||||||
}
|
}
|
||||||
|
|
||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLocalParameters returns the Quic parameters of the local RTCQuicParameters upon construction.
|
// GetLocalParameters returns the Quic parameters of the local QUICParameters upon construction.
|
||||||
func (t *RTCQuicTransport) GetLocalParameters() RTCQuicParameters {
|
func (t *QUICTransport) GetLocalParameters() QUICParameters {
|
||||||
fingerprints := []RTCDtlsFingerprint{}
|
fingerprints := []DTLSFingerprint{}
|
||||||
|
|
||||||
for _, c := range t.certificates {
|
for _, c := range t.certificates {
|
||||||
prints := c.GetFingerprints() // TODO: Should be only one?
|
prints := c.GetFingerprints() // TODO: Should be only one?
|
||||||
fingerprints = append(fingerprints, prints...)
|
fingerprints = append(fingerprints, prints...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return RTCQuicParameters{
|
return QUICParameters{
|
||||||
Role: RTCQuicRoleAuto, // always returns the default role
|
Role: QUICRoleAuto, // always returns the default role
|
||||||
Fingerprints: fingerprints,
|
Fingerprints: fingerprints,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start Quic transport with the parameters of the remote
|
// Start Quic transport with the parameters of the remote
|
||||||
func (t *RTCQuicTransport) Start(remoteParameters RTCQuicParameters) error {
|
func (t *QUICTransport) Start(remoteParameters QUICParameters) error {
|
||||||
t.lock.Lock()
|
t.lock.Lock()
|
||||||
defer t.lock.Unlock()
|
defer t.lock.Unlock()
|
||||||
|
|
||||||
@@ -89,12 +89,12 @@ func (t *RTCQuicTransport) Start(remoteParameters RTCQuicParameters) error {
|
|||||||
|
|
||||||
isClient := true
|
isClient := true
|
||||||
switch remoteParameters.Role {
|
switch remoteParameters.Role {
|
||||||
case RTCQuicRoleClient:
|
case QUICRoleClient:
|
||||||
isClient = true
|
isClient = true
|
||||||
case RTCQuicRoleServer:
|
case QUICRoleServer:
|
||||||
isClient = false
|
isClient = false
|
||||||
default:
|
default:
|
||||||
if t.iceTransport.Role() == RTCIceRoleControlling {
|
if t.iceTransport.Role() == ICERoleControlling {
|
||||||
isClient = false
|
isClient = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,7 +125,7 @@ func (t *RTCQuicTransport) Start(remoteParameters RTCQuicParameters) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RTCQuicTransport) validateFingerPrint(remoteParameters RTCQuicParameters, remoteCert *x509.Certificate) error {
|
func (t *QUICTransport) validateFingerPrint(remoteParameters QUICParameters, remoteCert *x509.Certificate) error {
|
||||||
for _, fp := range remoteParameters.Fingerprints {
|
for _, fp := range remoteParameters.Fingerprints {
|
||||||
hashAlgo, err := dtls.HashAlgorithmString(fp.Algorithm)
|
hashAlgo, err := dtls.HashAlgorithmString(fp.Algorithm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -145,7 +145,7 @@ func (t *RTCQuicTransport) validateFingerPrint(remoteParameters RTCQuicParameter
|
|||||||
return errors.New("No matching fingerprint")
|
return errors.New("No matching fingerprint")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RTCQuicTransport) ensureICEConn() error {
|
func (t *QUICTransport) ensureICEConn() error {
|
||||||
if t.iceTransport == nil ||
|
if t.iceTransport == nil ||
|
||||||
t.iceTransport.conn == nil ||
|
t.iceTransport.conn == nil ||
|
||||||
t.iceTransport.mux == nil {
|
t.iceTransport.mux == nil {
|
||||||
|
@@ -8,7 +8,7 @@ import (
|
|||||||
"github.com/pions/webrtc/pkg/quic"
|
"github.com/pions/webrtc/pkg/quic"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRTCQuicTransport_E2E(t *testing.T) {
|
func TestQUICTransport_E2E(t *testing.T) {
|
||||||
// Limit runtime in case of deadlocks
|
// Limit runtime in case of deadlocks
|
||||||
lim := test.TimeOut(time.Second * 20)
|
lim := test.TimeOut(time.Second * 20)
|
||||||
defer lim.Stop()
|
defer lim.Stop()
|
||||||
@@ -74,16 +74,16 @@ func quicReadLoop(s *quic.BidirectionalStream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type testQuicStack struct {
|
type testQuicStack struct {
|
||||||
gatherer *RTCIceGatherer
|
gatherer *ICEGatherer
|
||||||
ice *RTCIceTransport
|
ice *ICETransport
|
||||||
quic *RTCQuicTransport
|
quic *QUICTransport
|
||||||
api *API
|
api *API
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *testQuicStack) setSignal(sig *testQuicSignal, isOffer bool) error {
|
func (s *testQuicStack) setSignal(sig *testQuicSignal, isOffer bool) error {
|
||||||
iceRole := RTCIceRoleControlled
|
iceRole := ICERoleControlled
|
||||||
if isOffer {
|
if isOffer {
|
||||||
iceRole = RTCIceRoleControlling
|
iceRole = ICERoleControlling
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.ice.SetRemoteCandidates(sig.ICECandidates)
|
err := s.ice.SetRemoteCandidates(sig.ICECandidates)
|
||||||
@@ -147,9 +147,9 @@ func (s *testQuicStack) close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type testQuicSignal struct {
|
type testQuicSignal struct {
|
||||||
ICECandidates []RTCIceCandidate `json:"iceCandidates"`
|
ICECandidates []ICECandidate `json:"iceCandidates"`
|
||||||
ICEParameters RTCIceParameters `json:"iceParameters"`
|
ICEParameters ICEParameters `json:"iceParameters"`
|
||||||
QuicParameters RTCQuicParameters `json:"quicParameters"`
|
QuicParameters QUICParameters `json:"quicParameters"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func newQuicPair() (stackA *testQuicStack, stackB *testQuicStack, err error) {
|
func newQuicPair() (stackA *testQuicStack, stackB *testQuicStack, err error) {
|
||||||
@@ -169,16 +169,16 @@ func newQuicPair() (stackA *testQuicStack, stackB *testQuicStack, err error) {
|
|||||||
func newQuicStack() (*testQuicStack, error) {
|
func newQuicStack() (*testQuicStack, error) {
|
||||||
api := NewAPI()
|
api := NewAPI()
|
||||||
// Create the ICE gatherer
|
// Create the ICE gatherer
|
||||||
gatherer, err := api.NewRTCIceGatherer(RTCIceGatherOptions{})
|
gatherer, err := api.NewICEGatherer(ICEGatherOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct the ICE transport
|
// Construct the ICE transport
|
||||||
ice := api.NewRTCIceTransport(gatherer)
|
ice := api.NewICETransport(gatherer)
|
||||||
|
|
||||||
// Construct the Quic transport
|
// Construct the Quic transport
|
||||||
qt, err := api.NewRTCQuicTransport(ice, nil)
|
qt, err := api.NewQUICTransport(ice, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@@ -1,45 +1,45 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCRtcpMuxPolicy affects what ICE candidates are gathered to support
|
// RTCPMuxPolicy affects what ICE candidates are gathered to support
|
||||||
// non-multiplexed RTCP.
|
// non-multiplexed RTCP.
|
||||||
type RTCRtcpMuxPolicy int
|
type RTCPMuxPolicy int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCRtcpMuxPolicyNegotiate indicates to gather ICE candidates for both
|
// RTCPMuxPolicyNegotiate indicates to gather ICE candidates for both
|
||||||
// RTP and RTCP candidates. If the remote-endpoint is capable of
|
// RTP and RTCP candidates. If the remote-endpoint is capable of
|
||||||
// multiplexing RTCP, multiplex RTCP on the RTP candidates. If it is not,
|
// multiplexing RTCP, multiplex RTCP on the RTP candidates. If it is not,
|
||||||
// use both the RTP and RTCP candidates separately.
|
// use both the RTP and RTCP candidates separately.
|
||||||
RTCRtcpMuxPolicyNegotiate RTCRtcpMuxPolicy = iota + 1
|
RTCPMuxPolicyNegotiate RTCPMuxPolicy = iota + 1
|
||||||
|
|
||||||
// RTCRtcpMuxPolicyRequire indicates to gather ICE candidates only for
|
// RTCPMuxPolicyRequire indicates to gather ICE candidates only for
|
||||||
// RTP and multiplex RTCP on the RTP candidates. If the remote endpoint is
|
// RTP and multiplex RTCP on the RTP candidates. If the remote endpoint is
|
||||||
// not capable of rtcp-mux, session negotiation will fail.
|
// not capable of rtcp-mux, session negotiation will fail.
|
||||||
RTCRtcpMuxPolicyRequire
|
RTCPMuxPolicyRequire
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is done this way because of a linter.
|
// This is done this way because of a linter.
|
||||||
const (
|
const (
|
||||||
rtcRtcpMuxPolicyNegotiateStr = "negotiate"
|
rtcpMuxPolicyNegotiateStr = "negotiate"
|
||||||
rtcRtcpMuxPolicyRequireStr = "require"
|
rtcpMuxPolicyRequireStr = "require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRTCRtcpMuxPolicy(raw string) RTCRtcpMuxPolicy {
|
func newRTCPMuxPolicy(raw string) RTCPMuxPolicy {
|
||||||
switch raw {
|
switch raw {
|
||||||
case rtcRtcpMuxPolicyNegotiateStr:
|
case rtcpMuxPolicyNegotiateStr:
|
||||||
return RTCRtcpMuxPolicyNegotiate
|
return RTCPMuxPolicyNegotiate
|
||||||
case rtcRtcpMuxPolicyRequireStr:
|
case rtcpMuxPolicyRequireStr:
|
||||||
return RTCRtcpMuxPolicyRequire
|
return RTCPMuxPolicyRequire
|
||||||
default:
|
default:
|
||||||
return RTCRtcpMuxPolicy(Unknown)
|
return RTCPMuxPolicy(Unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t RTCRtcpMuxPolicy) String() string {
|
func (t RTCPMuxPolicy) String() string {
|
||||||
switch t {
|
switch t {
|
||||||
case RTCRtcpMuxPolicyNegotiate:
|
case RTCPMuxPolicyNegotiate:
|
||||||
return rtcRtcpMuxPolicyNegotiateStr
|
return rtcpMuxPolicyNegotiateStr
|
||||||
case RTCRtcpMuxPolicyRequire:
|
case RTCPMuxPolicyRequire:
|
||||||
return rtcRtcpMuxPolicyRequireStr
|
return rtcpMuxPolicyRequireStr
|
||||||
default:
|
default:
|
||||||
return ErrUnknownType.Error()
|
return ErrUnknownType.Error()
|
||||||
}
|
}
|
||||||
|
@@ -6,33 +6,33 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewRTCRtcpMuxPolicy(t *testing.T) {
|
func TestNewRTCPMuxPolicy(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
policyString string
|
policyString string
|
||||||
expectedPolicy RTCRtcpMuxPolicy
|
expectedPolicy RTCPMuxPolicy
|
||||||
}{
|
}{
|
||||||
{unknownStr, RTCRtcpMuxPolicy(Unknown)},
|
{unknownStr, RTCPMuxPolicy(Unknown)},
|
||||||
{"negotiate", RTCRtcpMuxPolicyNegotiate},
|
{"negotiate", RTCPMuxPolicyNegotiate},
|
||||||
{"require", RTCRtcpMuxPolicyRequire},
|
{"require", RTCPMuxPolicyRequire},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
testCase.expectedPolicy,
|
testCase.expectedPolicy,
|
||||||
newRTCRtcpMuxPolicy(testCase.policyString),
|
newRTCPMuxPolicy(testCase.policyString),
|
||||||
"testCase: %d %v", i, testCase,
|
"testCase: %d %v", i, testCase,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCRtcpMuxPolicy_String(t *testing.T) {
|
func TestRTCPMuxPolicy_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
policy RTCRtcpMuxPolicy
|
policy RTCPMuxPolicy
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCRtcpMuxPolicy(Unknown), unknownStr},
|
{RTCPMuxPolicy(Unknown), unknownStr},
|
||||||
{RTCRtcpMuxPolicyNegotiate, "negotiate"},
|
{RTCPMuxPolicyNegotiate, "negotiate"},
|
||||||
{RTCRtcpMuxPolicyRequire, "require"},
|
{RTCPMuxPolicyRequire, "require"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCRtpCodingParameters provides information relating to both encoding and decoding.
|
// RTPCodingParameters provides information relating to both encoding and decoding.
|
||||||
// This is a subset of the RFC since Pion WebRTC doesn't implement encoding/decoding itself
|
// This is a subset of the RFC since Pion WebRTC doesn't implement encoding/decoding itself
|
||||||
// http://draft.ortc.org/#dom-rtcrtpcodingparameters
|
// http://draft.ortc.org/#dom-rtcrtpcodingparameters
|
||||||
type RTCRtpCodingParameters struct {
|
type RTPCodingParameters struct {
|
||||||
SSRC uint32 `json:"ssrc"`
|
SSRC uint32 `json:"ssrc"`
|
||||||
PayloadType uint8 `json:"payloadType"`
|
PayloadType uint8 `json:"payloadType"`
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCRtpDecodingParameters provides information relating to both encoding and decoding.
|
// RTPDecodingParameters provides information relating to both encoding and decoding.
|
||||||
// This is a subset of the RFC since Pion WebRTC doesn't implement decoding itself
|
// This is a subset of the RFC since Pion WebRTC doesn't implement decoding itself
|
||||||
// http://draft.ortc.org/#dom-rtcrtpdecodingparameters
|
// http://draft.ortc.org/#dom-rtcrtpdecodingparameters
|
||||||
type RTCRtpDecodingParameters struct {
|
type RTPDecodingParameters struct {
|
||||||
RTCRtpCodingParameters
|
RTPCodingParameters
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCRtpEncodingParameters provides information relating to both encoding and decoding.
|
// RTPEncodingParameters provides information relating to both encoding and decoding.
|
||||||
// This is a subset of the RFC since Pion WebRTC doesn't implement encoding itself
|
// This is a subset of the RFC since Pion WebRTC doesn't implement encoding itself
|
||||||
// http://draft.ortc.org/#dom-rtcrtpencodingparameters
|
// http://draft.ortc.org/#dom-rtcrtpencodingparameters
|
||||||
type RTCRtpEncodingParameters struct {
|
type RTPEncodingParameters struct {
|
||||||
RTCRtpCodingParameters
|
RTPCodingParameters
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCRtpReceiveParameters contains the RTP stack settings used by receivers
|
// RTPReceiveParameters contains the RTP stack settings used by receivers
|
||||||
type RTCRtpReceiveParameters struct {
|
type RTPReceiveParameters struct {
|
||||||
encodings RTCRtpDecodingParameters
|
encodings RTPDecodingParameters
|
||||||
}
|
}
|
||||||
|
@@ -9,14 +9,14 @@ import (
|
|||||||
"github.com/pions/srtp"
|
"github.com/pions/srtp"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RTCRtpReceiver allows an application to inspect the receipt of a RTCTrack
|
// RTPReceiver allows an application to inspect the receipt of a Track
|
||||||
type RTCRtpReceiver struct {
|
type RTPReceiver struct {
|
||||||
kind RTCRtpCodecType
|
kind RTPCodecType
|
||||||
transport *RTCDtlsTransport
|
transport *DTLSTransport
|
||||||
|
|
||||||
hasRecv chan bool
|
hasRecv chan bool
|
||||||
|
|
||||||
Track *RTCTrack
|
Track *Track
|
||||||
|
|
||||||
closed bool
|
closed bool
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
@@ -30,9 +30,9 @@ type RTCRtpReceiver struct {
|
|||||||
rtcpOutDone chan bool
|
rtcpOutDone chan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRTCRtpReceiver constructs a new RTCRtpReceiver
|
// NewRTPReceiver constructs a new RTPReceiver
|
||||||
func NewRTCRtpReceiver(kind RTCRtpCodecType, transport *RTCDtlsTransport) *RTCRtpReceiver {
|
func NewRTPReceiver(kind RTPCodecType, transport *DTLSTransport) *RTPReceiver {
|
||||||
return &RTCRtpReceiver{
|
return &RTPReceiver{
|
||||||
kind: kind,
|
kind: kind,
|
||||||
transport: transport,
|
transport: transport,
|
||||||
|
|
||||||
@@ -46,10 +46,10 @@ func NewRTCRtpReceiver(kind RTCRtpCodecType, transport *RTCDtlsTransport) *RTCRt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Receive blocks until the RTCTrack is available
|
// Receive blocks until the Track is available
|
||||||
func (r *RTCRtpReceiver) Receive(parameters RTCRtpReceiveParameters) chan bool {
|
func (r *RTPReceiver) Receive(parameters RTPReceiveParameters) chan bool {
|
||||||
// TODO atomic only allow this to fire once
|
// TODO atomic only allow this to fire once
|
||||||
r.Track = &RTCTrack{
|
r.Track = &Track{
|
||||||
Kind: r.kind,
|
Kind: r.kind,
|
||||||
Ssrc: parameters.encodings.SSRC,
|
Ssrc: parameters.encodings.SSRC,
|
||||||
Packets: r.rtpOut,
|
Packets: r.rtpOut,
|
||||||
@@ -69,13 +69,13 @@ func (r *RTCRtpReceiver) Receive(parameters RTCRtpReceiveParameters) chan bool {
|
|||||||
|
|
||||||
srtpSession, err := r.transport.getSRTPSession()
|
srtpSession, err := r.transport.getSRTPSession()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pcLog.Warnf("Failed to open SRTPSession, RTCTrack done for: %v %d \n", err, parameters.encodings.SSRC)
|
pcLog.Warnf("Failed to open SRTPSession, Track done for: %v %d \n", err, parameters.encodings.SSRC)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
readStream, err := srtpSession.OpenReadStream(parameters.encodings.SSRC)
|
readStream, err := srtpSession.OpenReadStream(parameters.encodings.SSRC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pcLog.Warnf("Failed to open RTCP ReadStream, RTCTrack done for: %v %d \n", err, parameters.encodings.SSRC)
|
pcLog.Warnf("Failed to open RTCP ReadStream, Track done for: %v %d \n", err, parameters.encodings.SSRC)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.mu.Lock()
|
r.mu.Lock()
|
||||||
@@ -86,7 +86,7 @@ func (r *RTCRtpReceiver) Receive(parameters RTCRtpReceiveParameters) chan bool {
|
|||||||
for {
|
for {
|
||||||
rtpLen, err := readStream.Read(readBuf)
|
rtpLen, err := readStream.Read(readBuf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pcLog.Warnf("Failed to read, RTCTrack done for: %v %d \n", err, parameters.encodings.SSRC)
|
pcLog.Warnf("Failed to read, Track done for: %v %d \n", err, parameters.encodings.SSRC)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,13 +118,13 @@ func (r *RTCRtpReceiver) Receive(parameters RTCRtpReceiveParameters) chan bool {
|
|||||||
|
|
||||||
srtcpSession, err := r.transport.getSRTCPSession()
|
srtcpSession, err := r.transport.getSRTCPSession()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pcLog.Warnf("Failed to open SRTCPSession, RTCTrack done for: %v %d \n", err, parameters.encodings.SSRC)
|
pcLog.Warnf("Failed to open SRTCPSession, Track done for: %v %d \n", err, parameters.encodings.SSRC)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
readStream, err := srtcpSession.OpenReadStream(parameters.encodings.SSRC)
|
readStream, err := srtcpSession.OpenReadStream(parameters.encodings.SSRC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pcLog.Warnf("Failed to open RTCP ReadStream, RTCTrack done for: %v %d \n", err, parameters.encodings.SSRC)
|
pcLog.Warnf("Failed to open RTCP ReadStream, Track done for: %v %d \n", err, parameters.encodings.SSRC)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.mu.Lock()
|
r.mu.Lock()
|
||||||
@@ -135,7 +135,7 @@ func (r *RTCRtpReceiver) Receive(parameters RTCRtpReceiveParameters) chan bool {
|
|||||||
for {
|
for {
|
||||||
rtcpLen, err := readStream.Read(readBuf)
|
rtcpLen, err := readStream.Read(readBuf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pcLog.Warnf("Failed to read, RTCTrack done for: %v %d \n", err, parameters.encodings.SSRC)
|
pcLog.Warnf("Failed to read, Track done for: %v %d \n", err, parameters.encodings.SSRC)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,19 +154,19 @@ func (r *RTCRtpReceiver) Receive(parameters RTCRtpReceiveParameters) chan bool {
|
|||||||
return r.hasRecv
|
return r.hasRecv
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop irreversibly stops the RTCRtpReceiver
|
// Stop irreversibly stops the RTPReceiver
|
||||||
func (r *RTCRtpReceiver) Stop() error {
|
func (r *RTPReceiver) Stop() error {
|
||||||
r.mu.Lock()
|
r.mu.Lock()
|
||||||
defer r.mu.Unlock()
|
defer r.mu.Unlock()
|
||||||
|
|
||||||
if r.closed {
|
if r.closed {
|
||||||
return fmt.Errorf("RTCRtpReceiver has already been closed")
|
return fmt.Errorf("RTPReceiver has already been closed")
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-r.hasRecv:
|
case <-r.hasRecv:
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("RTCRtpReceiver has not been started")
|
return fmt.Errorf("RTPReceiver has not been started")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := r.rtcpReadStream.Close(); err != nil {
|
if err := r.rtcpReadStream.Close(); err != nil {
|
||||||
|
@@ -8,21 +8,21 @@ import (
|
|||||||
|
|
||||||
const rtpOutboundMTU = 1400
|
const rtpOutboundMTU = 1400
|
||||||
|
|
||||||
// RTCRtpSender allows an application to control how a given RTCTrack is encoded and transmitted to a remote peer
|
// RTPSender allows an application to control how a given Track is encoded and transmitted to a remote peer
|
||||||
type RTCRtpSender struct {
|
type RTPSender struct {
|
||||||
Track *RTCTrack
|
Track *Track
|
||||||
|
|
||||||
transport *RTCDtlsTransport
|
transport *DTLSTransport
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRTCRtpSender constructs a new RTCRtpSender
|
// NewRTPSender constructs a new RTPSender
|
||||||
func NewRTCRtpSender(track *RTCTrack, transport *RTCDtlsTransport) *RTCRtpSender {
|
func NewRTPSender(track *Track, transport *DTLSTransport) *RTPSender {
|
||||||
r := &RTCRtpSender{
|
r := &RTPSender{
|
||||||
Track: track,
|
Track: track,
|
||||||
transport: transport,
|
transport: transport,
|
||||||
}
|
}
|
||||||
|
|
||||||
r.Track.sampleInput = make(chan media.RTCSample, 15) // Is the buffering needed?
|
r.Track.sampleInput = make(chan media.Sample, 15) // Is the buffering needed?
|
||||||
r.Track.rawInput = make(chan *rtp.Packet, 15) // Is the buffering needed?
|
r.Track.rawInput = make(chan *rtp.Packet, 15) // Is the buffering needed?
|
||||||
r.Track.rtcpInput = make(chan rtcp.Packet, 15) // Is the buffering needed?
|
r.Track.rtcpInput = make(chan rtcp.Packet, 15) // Is the buffering needed?
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ func NewRTCRtpSender(track *RTCTrack, transport *RTCDtlsTransport) *RTCRtpSender
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send Attempts to set the parameters controlling the sending of media.
|
// Send Attempts to set the parameters controlling the sending of media.
|
||||||
func (r *RTCRtpSender) Send(parameters RTCRtpSendParameters) {
|
func (r *RTPSender) Send(parameters RTPSendParameters) {
|
||||||
if r.Track.isRawRTP {
|
if r.Track.isRawRTP {
|
||||||
go r.handleRawRTP(r.Track.rawInput)
|
go r.handleRawRTP(r.Track.rawInput)
|
||||||
} else {
|
} else {
|
||||||
@@ -50,8 +50,8 @@ func (r *RTCRtpSender) Send(parameters RTCRtpSendParameters) {
|
|||||||
go r.handleRTCP(r.transport, r.Track.rtcpInput)
|
go r.handleRTCP(r.transport, r.Track.rtcpInput)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop irreversibly stops the RTCRtpSender
|
// Stop irreversibly stops the RTPSender
|
||||||
func (r *RTCRtpSender) Stop() {
|
func (r *RTPSender) Stop() {
|
||||||
if r.Track.isRawRTP {
|
if r.Track.isRawRTP {
|
||||||
close(r.Track.RawRTP)
|
close(r.Track.RawRTP)
|
||||||
} else {
|
} else {
|
||||||
@@ -61,7 +61,7 @@ func (r *RTCRtpSender) Stop() {
|
|||||||
// TODO properly tear down all loops (and test that)
|
// TODO properly tear down all loops (and test that)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RTCRtpSender) handleRawRTP(rtpPackets chan *rtp.Packet) {
|
func (r *RTPSender) handleRawRTP(rtpPackets chan *rtp.Packet) {
|
||||||
for {
|
for {
|
||||||
p, ok := <-rtpPackets
|
p, ok := <-rtpPackets
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -72,7 +72,7 @@ func (r *RTCRtpSender) handleRawRTP(rtpPackets chan *rtp.Packet) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RTCRtpSender) handleSampleRTP(rtpPackets chan media.RTCSample) {
|
func (r *RTPSender) handleSampleRTP(rtpPackets chan media.Sample) {
|
||||||
packetizer := rtp.NewPacketizer(
|
packetizer := rtp.NewPacketizer(
|
||||||
rtpOutboundMTU,
|
rtpOutboundMTU,
|
||||||
r.Track.PayloadType,
|
r.Track.PayloadType,
|
||||||
@@ -95,16 +95,16 @@ func (r *RTCRtpSender) handleSampleRTP(rtpPackets chan media.RTCSample) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RTCRtpSender) handleRTCP(transport *RTCDtlsTransport, rtcpPackets chan rtcp.Packet) {
|
func (r *RTPSender) handleRTCP(transport *DTLSTransport, rtcpPackets chan rtcp.Packet) {
|
||||||
srtcpSession, err := transport.getSRTCPSession()
|
srtcpSession, err := transport.getSRTCPSession()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pcLog.Warnf("Failed to open SRTCPSession, RTCTrack done for: %v %d \n", err, r.Track.Ssrc)
|
pcLog.Warnf("Failed to open SRTCPSession, Track done for: %v %d \n", err, r.Track.Ssrc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
readStream, err := srtcpSession.OpenReadStream(r.Track.Ssrc)
|
readStream, err := srtcpSession.OpenReadStream(r.Track.Ssrc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pcLog.Warnf("Failed to open RTCP ReadStream, RTCTrack done for: %v %d \n", err, r.Track.Ssrc)
|
pcLog.Warnf("Failed to open RTCP ReadStream, Track done for: %v %d \n", err, r.Track.Ssrc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ func (r *RTCRtpSender) handleRTCP(transport *RTCDtlsTransport, rtcpPackets chan
|
|||||||
rtcpBuf := make([]byte, receiveMTU)
|
rtcpBuf := make([]byte, receiveMTU)
|
||||||
i, err := readStream.Read(rtcpBuf)
|
i, err := readStream.Read(rtcpBuf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pcLog.Warnf("Failed to read, RTCTrack done for: %v %d \n", err, r.Track.Ssrc)
|
pcLog.Warnf("Failed to read, Track done for: %v %d \n", err, r.Track.Ssrc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ func (r *RTCRtpSender) handleRTCP(transport *RTCDtlsTransport, rtcpPackets chan
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RTCRtpSender) sendRTP(packet *rtp.Packet) {
|
func (r *RTPSender) sendRTP(packet *rtp.Packet) {
|
||||||
srtpSession, err := r.transport.getSRTPSession()
|
srtpSession, err := r.transport.getSRTPSession()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pcLog.Warnf("SendRTP failed to open SrtpSession: %v", err)
|
pcLog.Warnf("SendRTP failed to open SrtpSession: %v", err)
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCRtpSendParameters contains the RTP stack settings used by receivers
|
// RTPSendParameters contains the RTP stack settings used by receivers
|
||||||
type RTCRtpSendParameters struct {
|
type RTPSendParameters struct {
|
||||||
encodings RTCRtpEncodingParameters
|
encodings RTPEncodingParameters
|
||||||
}
|
}
|
||||||
|
@@ -4,34 +4,34 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RTCRtpTransceiver represents a combination of an RTCRtpSender and an RTCRtpReceiver that share a common mid.
|
// RTPTransceiver represents a combination of an RTPSender and an RTPReceiver that share a common mid.
|
||||||
type RTCRtpTransceiver struct {
|
type RTPTransceiver struct {
|
||||||
Mid string
|
Mid string
|
||||||
Sender *RTCRtpSender
|
Sender *RTPSender
|
||||||
Receiver *RTCRtpReceiver
|
Receiver *RTPReceiver
|
||||||
Direction RTCRtpTransceiverDirection
|
Direction RTPTransceiverDirection
|
||||||
// currentDirection RTCRtpTransceiverDirection
|
// currentDirection RTPTransceiverDirection
|
||||||
// firedDirection RTCRtpTransceiverDirection
|
// firedDirection RTPTransceiverDirection
|
||||||
// receptive bool
|
// receptive bool
|
||||||
stopped bool
|
stopped bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RTCRtpTransceiver) setSendingTrack(track *RTCTrack) error {
|
func (t *RTPTransceiver) setSendingTrack(track *Track) error {
|
||||||
t.Sender.Track = track
|
t.Sender.Track = track
|
||||||
|
|
||||||
switch t.Direction {
|
switch t.Direction {
|
||||||
case RTCRtpTransceiverDirectionRecvonly:
|
case RTPTransceiverDirectionRecvonly:
|
||||||
t.Direction = RTCRtpTransceiverDirectionSendrecv
|
t.Direction = RTPTransceiverDirectionSendrecv
|
||||||
case RTCRtpTransceiverDirectionInactive:
|
case RTPTransceiverDirectionInactive:
|
||||||
t.Direction = RTCRtpTransceiverDirectionSendonly
|
t.Direction = RTPTransceiverDirectionSendonly
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("Invalid state change in RTCRtpTransceiver.setSending")
|
return errors.Errorf("Invalid state change in RTPTransceiver.setSending")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop irreversibly stops the RTCRtpTransceiver
|
// Stop irreversibly stops the RTPTransceiver
|
||||||
func (t *RTCRtpTransceiver) Stop() error {
|
func (t *RTPTransceiver) Stop() error {
|
||||||
if t.Sender != nil {
|
if t.Sender != nil {
|
||||||
t.Sender.Stop()
|
t.Sender.Stop()
|
||||||
}
|
}
|
||||||
|
@@ -1,61 +1,61 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
// RTCRtpTransceiverDirection indicates the direction of the RTCRtpTransceiver.
|
// RTPTransceiverDirection indicates the direction of the RTPTransceiver.
|
||||||
type RTCRtpTransceiverDirection int
|
type RTPTransceiverDirection int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RTCRtpTransceiverDirectionSendrecv indicates the RTCRtpSender will offer
|
// RTPTransceiverDirectionSendrecv indicates the RTPSender will offer
|
||||||
// to send RTP and RTCRtpReceiver the will offer to receive RTP.
|
// to send RTP and RTPReceiver the will offer to receive RTP.
|
||||||
RTCRtpTransceiverDirectionSendrecv RTCRtpTransceiverDirection = iota + 1
|
RTPTransceiverDirectionSendrecv RTPTransceiverDirection = iota + 1
|
||||||
|
|
||||||
// RTCRtpTransceiverDirectionSendonly indicates the RTCRtpSender will offer
|
// RTPTransceiverDirectionSendonly indicates the RTPSender will offer
|
||||||
// to send RTP.
|
// to send RTP.
|
||||||
RTCRtpTransceiverDirectionSendonly
|
RTPTransceiverDirectionSendonly
|
||||||
|
|
||||||
// RTCRtpTransceiverDirectionRecvonly indicates the RTCRtpReceiver the will
|
// RTPTransceiverDirectionRecvonly indicates the RTPReceiver the will
|
||||||
// offer to receive RTP.
|
// offer to receive RTP.
|
||||||
RTCRtpTransceiverDirectionRecvonly
|
RTPTransceiverDirectionRecvonly
|
||||||
|
|
||||||
// RTCRtpTransceiverDirectionInactive indicates the RTCRtpSender won't offer
|
// RTPTransceiverDirectionInactive indicates the RTPSender won't offer
|
||||||
// to send RTP and RTCRtpReceiver the won't offer to receive RTP.
|
// to send RTP and RTPReceiver the won't offer to receive RTP.
|
||||||
RTCRtpTransceiverDirectionInactive
|
RTPTransceiverDirectionInactive
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is done this way because of a linter.
|
// This is done this way because of a linter.
|
||||||
const (
|
const (
|
||||||
rtcRtpTransceiverDirectionSendrecvStr = "sendrecv"
|
rtpTransceiverDirectionSendrecvStr = "sendrecv"
|
||||||
rtcRtpTransceiverDirectionSendonlyStr = "sendonly"
|
rtpTransceiverDirectionSendonlyStr = "sendonly"
|
||||||
rtcRtpTransceiverDirectionRecvonlyStr = "recvonly"
|
rtpTransceiverDirectionRecvonlyStr = "recvonly"
|
||||||
rtcRtpTransceiverDirectionInactiveStr = "inactive"
|
rtpTransceiverDirectionInactiveStr = "inactive"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewRTCRtpTransceiverDirection defines a procedure for creating a new
|
// NewRTPTransceiverDirection defines a procedure for creating a new
|
||||||
// RTCRtpTransceiverDirection from a raw string naming the transceiver direction.
|
// RTPTransceiverDirection from a raw string naming the transceiver direction.
|
||||||
func NewRTCRtpTransceiverDirection(raw string) RTCRtpTransceiverDirection {
|
func NewRTPTransceiverDirection(raw string) RTPTransceiverDirection {
|
||||||
switch raw {
|
switch raw {
|
||||||
case rtcRtpTransceiverDirectionSendrecvStr:
|
case rtpTransceiverDirectionSendrecvStr:
|
||||||
return RTCRtpTransceiverDirectionSendrecv
|
return RTPTransceiverDirectionSendrecv
|
||||||
case rtcRtpTransceiverDirectionSendonlyStr:
|
case rtpTransceiverDirectionSendonlyStr:
|
||||||
return RTCRtpTransceiverDirectionSendonly
|
return RTPTransceiverDirectionSendonly
|
||||||
case rtcRtpTransceiverDirectionRecvonlyStr:
|
case rtpTransceiverDirectionRecvonlyStr:
|
||||||
return RTCRtpTransceiverDirectionRecvonly
|
return RTPTransceiverDirectionRecvonly
|
||||||
case rtcRtpTransceiverDirectionInactiveStr:
|
case rtpTransceiverDirectionInactiveStr:
|
||||||
return RTCRtpTransceiverDirectionInactive
|
return RTPTransceiverDirectionInactive
|
||||||
default:
|
default:
|
||||||
return RTCRtpTransceiverDirection(Unknown)
|
return RTPTransceiverDirection(Unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t RTCRtpTransceiverDirection) String() string {
|
func (t RTPTransceiverDirection) String() string {
|
||||||
switch t {
|
switch t {
|
||||||
case RTCRtpTransceiverDirectionSendrecv:
|
case RTPTransceiverDirectionSendrecv:
|
||||||
return rtcRtpTransceiverDirectionSendrecvStr
|
return rtpTransceiverDirectionSendrecvStr
|
||||||
case RTCRtpTransceiverDirectionSendonly:
|
case RTPTransceiverDirectionSendonly:
|
||||||
return rtcRtpTransceiverDirectionSendonlyStr
|
return rtpTransceiverDirectionSendonlyStr
|
||||||
case RTCRtpTransceiverDirectionRecvonly:
|
case RTPTransceiverDirectionRecvonly:
|
||||||
return rtcRtpTransceiverDirectionRecvonlyStr
|
return rtpTransceiverDirectionRecvonlyStr
|
||||||
case RTCRtpTransceiverDirectionInactive:
|
case RTPTransceiverDirectionInactive:
|
||||||
return rtcRtpTransceiverDirectionInactiveStr
|
return rtpTransceiverDirectionInactiveStr
|
||||||
default:
|
default:
|
||||||
return ErrUnknownType.Error()
|
return ErrUnknownType.Error()
|
||||||
}
|
}
|
||||||
|
@@ -6,37 +6,37 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewRTCRtpTransceiverDirection(t *testing.T) {
|
func TestNewRTPTransceiverDirection(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
priorityString string
|
priorityString string
|
||||||
expectedPriority RTCRtpTransceiverDirection
|
expectedPriority RTPTransceiverDirection
|
||||||
}{
|
}{
|
||||||
{unknownStr, RTCRtpTransceiverDirection(Unknown)},
|
{unknownStr, RTPTransceiverDirection(Unknown)},
|
||||||
{"sendrecv", RTCRtpTransceiverDirectionSendrecv},
|
{"sendrecv", RTPTransceiverDirectionSendrecv},
|
||||||
{"sendonly", RTCRtpTransceiverDirectionSendonly},
|
{"sendonly", RTPTransceiverDirectionSendonly},
|
||||||
{"recvonly", RTCRtpTransceiverDirectionRecvonly},
|
{"recvonly", RTPTransceiverDirectionRecvonly},
|
||||||
{"inactive", RTCRtpTransceiverDirectionInactive},
|
{"inactive", RTPTransceiverDirectionInactive},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
NewRTCRtpTransceiverDirection(testCase.priorityString),
|
NewRTPTransceiverDirection(testCase.priorityString),
|
||||||
testCase.expectedPriority,
|
testCase.expectedPriority,
|
||||||
"testCase: %d %v", i, testCase,
|
"testCase: %d %v", i, testCase,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRTCRtpTransceiverDirection_String(t *testing.T) {
|
func TestRTPTransceiverDirection_String(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
priority RTCRtpTransceiverDirection
|
priority RTPTransceiverDirection
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{RTCRtpTransceiverDirection(Unknown), unknownStr},
|
{RTPTransceiverDirection(Unknown), unknownStr},
|
||||||
{RTCRtpTransceiverDirectionSendrecv, "sendrecv"},
|
{RTPTransceiverDirectionSendrecv, "sendrecv"},
|
||||||
{RTCRtpTransceiverDirectionSendonly, "sendonly"},
|
{RTPTransceiverDirectionSendonly, "sendonly"},
|
||||||
{RTCRtpTransceiverDirectionRecvonly, "recvonly"},
|
{RTPTransceiverDirectionRecvonly, "recvonly"},
|
||||||
{RTCRtpTransceiverDirectionInactive, "inactive"},
|
{RTPTransceiverDirectionInactive, "inactive"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user