Overview
The SessionDescription type is used to expose local and remote session descriptions. It encapsulates the Session Description Protocol (SDP) information exchanged between peers during connection establishment.
Source: sessiondescription.go:39-46
Type Definition
type SessionDescription struct {
Type SDPType
SDP string
parsed * sdp . SessionDescription // Internal use only
}
The type of session description (offer, answer, pranswer, or rollback)
Internal parsed representation (not initialized by callers)
SDPType Enumeration
The SDPType describes the type of a SessionDescription.
type SDPType int
const (
SDPTypeUnknown SDPType = iota // Zero-value, invalid
SDPTypeOffer // SDP offer
SDPTypePranswer // Provisional answer
SDPTypeAnswer // Final answer
SDPTypeRollback // Cancel negotiation
)
SDPTypeOffer
Indicates that a description MUST be treated as an SDP offer.
Used when initiating a connection or renegotiating.
offer , err := pc . CreateOffer ( nil )
if err != nil {
return err
}
fmt . Println ( offer . Type ) // Output: offer
SDPTypePranswer
Indicates that a description MUST be treated as an SDP provisional answer, but not a final answer.
A pranswer may be applied as a response to an SDP offer, or an update to a previously sent SDP pranswer.
Provisional answers are rarely used in practice. Most applications use immediate final answers.
SDPTypeAnswer
Indicates that a description MUST be treated as an SDP final answer, and the offer-answer exchange MUST be considered complete.
Used to respond to an offer or update a previously sent pranswer.
answer , err := pc . CreateAnswer ( nil )
if err != nil {
return err
}
fmt . Println ( answer . Type ) // Output: answer
SDPTypeRollback
Indicates that a description MUST be treated as canceling the current SDP negotiation and moving the SDP offer and answer back to what it was in the previous stable state.
Used to abort a negotiation in progress.
rollback := webrtc . SessionDescription {
Type : webrtc . SDPTypeRollback ,
}
err := pc . SetLocalDescription ( rollback )
SDPType Methods
NewSDPType
Creates an SDPType from a string.
func NewSDPType ( raw string ) SDPType
String representation (“offer”, “pranswer”, “answer”, or “rollback”)
The corresponding SDPType, or SDPTypeUnknown if invalid
sdpType := webrtc . NewSDPType ( "offer" )
fmt . Println ( sdpType == webrtc . SDPTypeOffer ) // true
String
Returns the string representation of an SDPType.
func ( t SDPType ) String () string
String representation of the SDPType
sdpType := webrtc . SDPTypeOffer
fmt . Println ( sdpType . String ()) // "offer"
SessionDescription Methods
Unmarshal
A helper to deserialize the SDP.
Source: sessiondescription.go:48-57
func ( sd * SessionDescription ) Unmarshal () ( * sdp . SessionDescription , error )
Error if unmarshaling fails
sd := webrtc . SessionDescription {
Type : webrtc . SDPTypeOffer ,
SDP : receivedSDPString ,
}
parsed , err := sd . Unmarshal ()
if err != nil {
return err
}
This method is typically used internally. Most application code doesn’t need to call it directly.
Usage with PeerConnection
Creating an Offer
offer , err := pc . CreateOffer ( nil )
if err != nil {
return err
}
// Offer is a SessionDescription with Type = SDPTypeOffer
fmt . Printf ( "Type: %s \n " , offer . Type )
fmt . Printf ( "SDP: %s \n " , offer . SDP )
// Set as local description
err = pc . SetLocalDescription ( offer )
if err != nil {
return err
}
// Send offer.SDP to remote peer via signaling
sendToRemotePeer ( offer . SDP )
Handling a Remote Offer
// Receive SDP from remote peer
remoteSDP := receiveFromRemotePeer ()
// Create SessionDescription
remoteOffer := webrtc . SessionDescription {
Type : webrtc . SDPTypeOffer ,
SDP : remoteSDP ,
}
// Set as remote description
err := pc . SetRemoteDescription ( remoteOffer )
if err != nil {
return err
}
// Create and send answer
answer , err := pc . CreateAnswer ( nil )
if err != nil {
return err
}
err = pc . SetLocalDescription ( answer )
if err != nil {
return err
}
sendToRemotePeer ( answer . SDP )
Creating an Answer
// After receiving and setting a remote offer
answer , err := pc . CreateAnswer ( nil )
if err != nil {
return err
}
// Answer is a SessionDescription with Type = SDPTypeAnswer
err = pc . SetLocalDescription ( answer )
if err != nil {
return err
}
// Send answer.SDP to remote peer
sendToRemotePeer ( answer . SDP )
ICE Trickle Support
The SessionDescription type works with ICE trickle capability detection.
Source: sessiondescription.go:14-37
ICETrickleCapability
type ICETrickleCapability int
const (
ICETrickleCapabilityUnknown ICETrickleCapability = iota
ICETrickleCapabilitySupported
ICETrickleCapabilityUnsupported
)
ICETrickleCapabilityUnknown
No remote peer has been established
ICETrickleCapabilitySupported
Remote peer can accept trickled ICE candidates
ICETrickleCapabilityUnsupported
Remote peer didn’t state that it can accept trickle ICE candidates
capability := pc . CanTrickleICECandidates ()
switch capability {
case webrtc . ICETrickleCapabilitySupported :
// Can send candidates as they're gathered
fmt . Println ( "Trickle ICE supported" )
case webrtc . ICETrickleCapabilityUnsupported :
// Must wait for all candidates before signaling
fmt . Println ( "Trickle ICE not supported" )
default :
fmt . Println ( "Trickle ICE capability unknown" )
}
Complete Signaling Example
package main
import (
" encoding/json "
" github.com/pion/webrtc/v4 "
)
func createOffer ( pc * webrtc . PeerConnection , signaling chan [] byte ) error {
// Create offer
offer , err := pc . CreateOffer ( nil )
if err != nil {
return err
}
// Set local description
err = pc . SetLocalDescription ( offer )
if err != nil {
return err
}
// Marshal and send offer
offerJSON , err := json . Marshal ( offer )
if err != nil {
return err
}
signaling <- offerJSON
// Wait for answer
answerJSON := <- signaling
// Unmarshal answer
var answer webrtc . SessionDescription
err = json . Unmarshal ( answerJSON , & answer )
if err != nil {
return err
}
// Set remote description
return pc . SetRemoteDescription ( answer )
}
Best Practices
Always Set Locally First Always call SetLocalDescription with the offer/answer you created before sending it to the remote peer.
Error Handling Check errors from CreateOffer, CreateAnswer, and SetLocalDescription/SetRemoteDescription - they can fail.
Signaling Independence SessionDescriptions are just data - you choose how to exchange them (WebSocket, HTTP, etc.).
JSON Serialization SessionDescription has JSON tags and can be marshaled/unmarshaled directly.
Common Patterns
Perfect Negotiation Pattern
Handle offer collisions gracefully: func handleNegotiation ( pc * webrtc . PeerConnection , isPolite bool ) {
pc . OnNegotiationNeeded ( func () {
offer , err := pc . CreateOffer ( nil )
if err != nil {
return
}
err = pc . SetLocalDescription ( offer )
if err != nil {
return
}
// Send offer
})
// On receiving offer
onOfferReceived := func ( offer webrtc . SessionDescription ) error {
// Check for collision
if pc . SignalingState () != webrtc . SignalingStateStable {
if ! isPolite {
// Ignore the offer
return nil
}
// Rollback local offer
err := pc . SetLocalDescription ( webrtc . SessionDescription {
Type : webrtc . SDPTypeRollback ,
})
if err != nil {
return err
}
}
err := pc . SetRemoteDescription ( offer )
if err != nil {
return err
}
answer , err := pc . CreateAnswer ( nil )
if err != nil {
return err
}
return pc . SetLocalDescription ( answer )
}
}
Modify SDP before setting (advanced): offer , err := pc . CreateOffer ( nil )
if err != nil {
return err
}
// Parse the SDP
parsed , err := offer . Unmarshal ()
if err != nil {
return err
}
// Modify bandwidth, add attributes, etc.
for _ , media := range parsed . MediaDescriptions {
media . Bandwidth = append ( media . Bandwidth , sdp . Bandwidth {
Experimental : false ,
Type : "AS" ,
Bandwidth : 1000 ,
})
}
// Marshal back to string
modifiedSDP , err := parsed . Marshal ()
if err != nil {
return err
}
offer . SDP = string ( modifiedSDP )
// Now set the modified offer
err = pc . SetLocalDescription ( offer )
Handle mid-call changes: // Add a new track mid-call
newTrack , err := webrtc . NewTrackLocalStaticSample (
webrtc . RTPCodecCapability { MimeType : webrtc . MimeTypeVP8 },
"video" ,
"pion" ,
)
if err != nil {
return err
}
_ , err = pc . AddTrack ( newTrack )
if err != nil {
return err
}
// Create new offer for renegotiation
offer , err := pc . CreateOffer ( nil )
if err != nil {
return err
}
err = pc . SetLocalDescription ( offer )
if err != nil {
return err
}
// Send new offer to peer
Troubleshooting
SetRemoteDescription Fails
Common causes:
SDP format is invalid or corrupted
Wrong SDPType for current signaling state
Missing media sections that were in previous offer
err := pc . SetRemoteDescription ( desc )
if err != nil {
fmt . Printf ( "Failed to set remote description: %v \n " , err )
fmt . Printf ( "Current signaling state: %s \n " , pc . SignalingState ())
fmt . Printf ( "Description type: %s \n " , desc . Type )
}
According to JSEP 5.4, you can set an empty SDP string: // This will use the last created offer
err := pc . SetLocalDescription ( webrtc . SessionDescription {
Type : webrtc . SDPTypeOffer ,
SDP : "" , // Will use last created offer
})
See Also