Update CI configs to v0.4.7

Update lint scripts and CI configs.
This commit is contained in:
Sean DuBois
2020-09-29 13:14:15 -07:00
committed by Sean DuBois
parent 0786371c1e
commit 804a12fed3
74 changed files with 518 additions and 346 deletions

View File

@@ -3,6 +3,80 @@ linters-settings:
check-shadowing: true
misspell:
locale: US
exhaustive:
default-signifies-exhaustive: true
linters:
enable:
- asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers
- bodyclose # checks whether HTTP response body is closed successfully
- deadcode # Finds unused code
- depguard # Go linter that checks if package imports are in a list of acceptable packages
- dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())
- dupl # Tool for code clone detection
- errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases
- exhaustive # check exhaustiveness of enum switch statements
- exportloopref # checks for pointers to enclosing loop variables
- gci # Gci control golang package import order and make it always deterministic.
- gochecknoglobals # Checks that no globals are present in Go code
- gochecknoinits # Checks that no init functions are present in Go code
- gocognit # Computes and checks the cognitive complexity of functions
- goconst # Finds repeated strings that could be replaced by a constant
- gocritic # The most opinionated Go source code linter
- godox # Tool for detection of FIXME, TODO and other comment keywords
- goerr113 # Golang linter to check the errors handling expressions
- gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification
- gofumpt # Gofumpt checks whether code was gofumpt-ed.
- goheader # Checks is file header matches to pattern
- goimports # Goimports does everything that gofmt does. Additionally it checks unused imports
- golint # Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes
- gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations.
- goprintffuncname # Checks that printf-like functions are named with `f` at the end
- gosec # Inspects source code for security problems
- gosimple # Linter for Go source code that specializes in simplifying a code
- govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string
- ineffassign # Detects when assignments to existing variables are not used
- misspell # Finds commonly misspelled English words in comments
- nakedret # Finds naked returns in functions greater than a specified function length
- noctx # noctx finds sending http request without context.Context
- scopelint # Scopelint checks for unpinned variables in go programs
- staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks
- structcheck # Finds unused struct fields
- stylecheck # Stylecheck is a replacement for golint
- typecheck # Like the front-end of a Go compiler, parses and type-checks Go code
- unconvert # Remove unnecessary type conversions
- unparam # Reports unused function parameters
- unused # Checks Go code for unused constants, variables, functions and types
- varcheck # Finds unused global variables and constants
- whitespace # Tool for detection of leading and trailing whitespace
disable:
- funlen # Tool for detection of long functions
- gocyclo # Computes and checks the cyclomatic complexity of functions
- godot # Check if comments end in a period
- gomnd # An analyzer to detect magic numbers.
- lll # Reports long lines
- maligned # Tool to detect Go structs that would take less memory if their fields were sorted
- nestif # Reports deeply nested if statements
- nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity
- nolintlint # Reports ill-formed or insufficient nolint directives
- prealloc # Finds slice declarations that could potentially be preallocated
- rowserrcheck # checks whether Err of rows is checked successfully
- sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed.
- testpackage # linter that makes you use a separate _test package
- wsl # Whitespace Linter - Forces you to use empty lines!
issues:
exclude-rules:
# Allow complex tests, better to be self contained
- path: _test\.go
linters:
- gocognit
# Allow complex main function in examples
- path: examples
text: "of func `main` is high"
linters:
- gocognit
run:
skip-dirs-use-default: false

View File

@@ -203,6 +203,7 @@ Check out the **[contributing wiki](https://github.com/pion/webrtc/wiki/Contribu
* [Joshua Obasaju](https://github.com/obasajujoshua31)
* [Mission Liao](https://github.com/mission-liao)
* [Hanjun Kim](https://github.com/hallazzang)
* [ZHENK](https://github.com/scorpionknifes)
### License
MIT License - see [LICENSE](LICENSE) for full text

View File

@@ -103,11 +103,11 @@ func (c Certificate) GetFingerprints() ([]DTLSFingerprint, error) {
for _, algo := range fingerprintAlgorithms {
name, err := fingerprint.StringFromHash(algo)
if err != nil {
return nil, fmt.Errorf("failed to create fingerprint: %v", err)
return nil, fmt.Errorf("%w: %v", ErrFailedToGenerateCertificateFingerprint, err)
}
value, err := fingerprint.Fingerprint(c.x509Cert, algo)
if err != nil {
return nil, fmt.Errorf("failed to create fingerprint: %v", err)
return nil, fmt.Errorf("%w: %v", ErrFailedToGenerateCertificateFingerprint, err)
}
res[i] = DTLSFingerprint{
Algorithm: name,

View File

@@ -15,7 +15,7 @@ import (
"github.com/pion/webrtc/v3/pkg/rtcerr"
)
const dataChannelBufferSize = math.MaxUint16 //message size limit for Chromium
const dataChannelBufferSize = math.MaxUint16 // message size limit for Chromium
var errSCTPNotEstablished = errors.New("SCTP not established")
// DataChannel represents a WebRTC DataChannel
@@ -372,11 +372,11 @@ func (d *DataChannel) Detach() (datachannel.ReadWriteCloser, error) {
defer d.mu.Unlock()
if !d.api.settingEngine.detach.DataChannels {
return nil, fmt.Errorf("enable detaching by calling webrtc.DetachDataChannels()")
return nil, errDetachNotEnabled
}
if d.dataChannel == nil {
return nil, fmt.Errorf("datachannel not opened yet, try calling Detach from OnOpen")
return nil, errDetachBeforeOpened
}
d.detachCalled = true

View File

@@ -67,8 +67,7 @@ func TestDataChannel_MessagesAreOrdered(t *testing.T) {
// math/rand a weak RNG, but this does not need to be secure. Ignore with #nosec
/* #nosec */
randInt, err := rand.Int(rand.Reader, big.NewInt(int64(max)))
/* #nosec */
if err != nil {
/* #nosec */ if err != nil {
t.Fatalf("Failed to get random sleep duration: %s", err)
}
time.Sleep(time.Duration(randInt.Int64()) * time.Microsecond)
@@ -117,7 +116,7 @@ func TestDataChannelParamters_Go(t *testing.T) {
defer report()
t.Run("MaxPacketLifeTime exchange", func(t *testing.T) {
var ordered = true
ordered := true
var maxPacketLifeTime uint16 = 3
options := &DataChannelInit{
Ordered: &ordered,
@@ -218,8 +217,7 @@ func TestDataChannelBufferedAmount(t *testing.T) {
t.Fatalf("Failed to send string on data channel")
}
assert.Equal(t, uint64(1500), dc.BufferedAmountLowThreshold(), "value mismatch")
//assert.Equal(t, (i+1)*len(buf), int(dc.BufferedAmount()), "unexpected bufferedAmount")
// assert.Equal(t, (i+1)*len(buf), int(dc.BufferedAmount()), "unexpected bufferedAmount")
}
})
@@ -300,8 +298,7 @@ func TestDataChannelBufferedAmount(t *testing.T) {
t.Fatalf("Failed to send string on data channel")
}
assert.Equal(t, uint64(1500), dc.BufferedAmountLowThreshold(), "value mismatch")
//assert.Equal(t, (i+1)*len(buf), int(dc.BufferedAmount()), "unexpected bufferedAmount")
// assert.Equal(t, (i+1)*len(buf), int(dc.BufferedAmount()), "unexpected bufferedAmount")
}
})
@@ -436,18 +433,13 @@ func TestEOF(t *testing.T) {
lim := test.TimeOut(time.Second * 5)
defer lim.Stop()
// Use Detach data channels mode
s := SettingEngine{}
//s.DetachDataChannels()
api := NewAPI(WithSettingEngine(s))
// Set up two peer connections.
config := Configuration{}
pca, err := api.NewPeerConnection(config)
pca, err := NewPeerConnection(config)
if err != nil {
t.Fatal(err)
}
pcb, err := api.NewPeerConnection(config)
pcb, err := NewPeerConnection(config)
if err != nil {
t.Fatal(err)
}

View File

@@ -3,13 +3,13 @@
package webrtc
import (
"github.com/stretchr/testify/assert"
"io"
"testing"
"time"
"github.com/pion/transport/test"
"github.com/pion/webrtc/v3/internal/util"
"github.com/stretchr/testify/assert"
)
func TestDataChannel_ORTCE2E(t *testing.T) {

View File

@@ -203,11 +203,8 @@ func TestDataChannel_Send(t *testing.T) {
dc.OnMessage(func(msg DataChannelMessage) {
done <- true
})
// TODO: currently there is no way of properly subscribing to OnOpen with the js binding,
// because CreateDataChannel might return an already open data channel
//
e := dc.SendText("Ping")
if e != nil {
if e := dc.SendText("Ping"); e != nil {
// wasm binding doesn't fire OnOpen (we probably already missed it)
dc.OnOpen(func() {
e = dc.SendText("Ping")

View File

@@ -151,7 +151,7 @@ func (t *DTLSTransport) startSRTP() error {
if t.srtpSession.Load() != nil && t.srtcpSession.Load() != nil {
return nil
} else if t.conn == nil {
return fmt.Errorf("the DTLS transport has not started yet")
return errDtlsTransportNotStarted
}
srtpConfig := &srtp.Config{
@@ -189,17 +189,17 @@ func (t *DTLSTransport) startSRTP() error {
connState := t.conn.ConnectionState()
err := srtpConfig.ExtractSessionKeysFromDTLS(&connState, t.role() == DTLSRoleClient)
if err != nil {
return fmt.Errorf("failed to extract sctp session keys: %v", err)
return fmt.Errorf("%w: %v", errDtlsKeyExtractionFailed, err)
}
srtpSession, err := srtp.NewSessionSRTP(t.srtpEndpoint, srtpConfig)
if err != nil {
return fmt.Errorf("failed to start srtp: %v", err)
return fmt.Errorf("%w: %v", errFailedToStartSRTP, err)
}
srtcpSession, err := srtp.NewSessionSRTCP(t.srtcpEndpoint, srtpConfig)
if err != nil {
return fmt.Errorf("failed to start srtp: %v", err)
return fmt.Errorf("%w: %v", errFailedToStartSRTCP, err)
}
t.srtpSession.Store(srtpSession)
@@ -237,6 +237,7 @@ func (t *DTLSTransport) role() DTLSRole {
return DTLSRoleServer
case DTLSRoleServer:
return DTLSRoleClient
default:
}
// If SettingEngine has an explicit role
@@ -245,6 +246,7 @@ func (t *DTLSTransport) role() DTLSRole {
return DTLSRoleServer
case DTLSRoleClient:
return DTLSRoleClient
default:
}
// Remote was auto and no explicit role was configured via SettingEngine
@@ -267,7 +269,7 @@ func (t *DTLSTransport) Start(remoteParameters DTLSParameters) error {
}
if t.state != DTLSTransportStateNew {
return DTLSRole(0), nil, &rtcerr.InvalidStateError{Err: fmt.Errorf("attempted to start DTLSTransport that is not in new state: %s", t.state)}
return DTLSRole(0), nil, &rtcerr.InvalidStateError{Err: fmt.Errorf("%w: %s", errInvalidDTLSStart, t.state)}
}
t.srtpEndpoint = t.iceTransport.NewEndpoint(mux.MatchSRTP)
@@ -282,7 +284,8 @@ func (t *DTLSTransport) Start(remoteParameters DTLSParameters) error {
{
Certificate: [][]byte{cert.x509Cert.Raw},
PrivateKey: cert.privateKey,
}},
},
},
SRTPProtectionProfiles: []dtls.SRTPProtectionProfile{dtls.SRTP_AEAD_AES_128_GCM, dtls.SRTP_AES128_CM_HMAC_SHA1_80},
ClientAuth: dtls.RequireAnyClientCert,
LoggerFactory: t.api.settingEngine.LoggerFactory,
@@ -345,7 +348,7 @@ func (t *DTLSTransport) Start(remoteParameters DTLSParameters) error {
remoteCerts := t.conn.ConnectionState().PeerCertificates
if len(remoteCerts) == 0 {
t.onStateChange(DTLSTransportStateFailed)
return fmt.Errorf("peer didn't provide certificate via DTLS")
return errNoRemoteCertificate
}
t.remoteCertificate = remoteCerts[0]
@@ -386,7 +389,7 @@ func (t *DTLSTransport) Stop() error {
if t.conn != nil {
// dtls connection may be closed on sctp close.
if err := t.conn.Close(); err != nil && err != dtls.ErrConnClosed {
if err := t.conn.Close(); err != nil && !errors.Is(err, dtls.ErrConnClosed) {
closeErrs = append(closeErrs, err)
}
}
@@ -411,12 +414,12 @@ func (t *DTLSTransport) validateFingerPrint(remoteCert *x509.Certificate) error
}
}
return errors.New("no matching fingerprint")
return errNoMatchingCertificateFingerprint
}
func (t *DTLSTransport) ensureICEConn() error {
if t.iceTransport == nil || t.iceTransport.State() == ICETransportStateNew {
return errors.New("ICE connection not started")
return errICEConnectionNotStarted
}
return nil

View File

@@ -7,7 +7,6 @@ import (
"encoding/json"
"errors"
"fmt"
"math/rand"
"os"
"strconv"
"strings"
@@ -16,6 +15,7 @@ import (
"github.com/sclevine/agouti"
"github.com/pion/randutil"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/pkg/media"
)
@@ -351,7 +351,7 @@ func createTrack(offer webrtc.SessionDescription) (*webrtc.PeerConnection, *webr
return nil, nil, nil, errPc
}
track, errTrack := pc.NewTrack(payloadType, rand.Uint32(), "video", "pion")
track, errTrack := pc.NewTrack(payloadType, randutil.NewMathRandomGenerator().Uint32(), "video", "pion")
if errTrack != nil {
return nil, nil, nil, errTrack
}

View File

@@ -88,7 +88,7 @@ var (
ErrIncorrectSignalingState = errors.New("operation can not be run in current signaling state")
// ErrProtocolTooLarge indicates that value given for a DataChannelInit protocol is
//longer then 65535 bytes
// longer then 65535 bytes
ErrProtocolTooLarge = errors.New("protocol is larger then 65535 bytes")
// ErrSenderNotCreatedByConnection indicates RemoveTrack was called with a RtpSender not created
@@ -125,4 +125,89 @@ var (
// ErrNoSRTPProtectionProfile indicates that the DTLS handshake completed and no SRTP Protection Profile was chosen
ErrNoSRTPProtectionProfile = errors.New("DTLS Handshake completed and no SRTP Protection Profile was chosen")
// ErrFailedToGenerateCertificateFingerprint indicates that we failed to generate the fingerprint used for comparing certificates
ErrFailedToGenerateCertificateFingerprint = errors.New("failed to generate certificate fingerprint")
errDetachNotEnabled = errors.New("enable detaching by calling webrtc.DetachDataChannels()")
errDetachBeforeOpened = errors.New("datachannel not opened yet, try calling Detach from OnOpen")
errDtlsTransportNotStarted = errors.New("the DTLS transport has not started yet")
errDtlsKeyExtractionFailed = errors.New("failed extracting keys from DTLS for SRTP")
errFailedToStartSRTP = errors.New("failed to start SRTP")
errFailedToStartSRTCP = errors.New("failed to start SRTCP")
errInvalidDTLSStart = errors.New("attempted to start DTLSTransport that is not in new state")
errNoRemoteCertificate = errors.New("peer didn't provide certificate via DTLS")
errIdentityProviderNotImplemented = errors.New("identity provider is not implemented")
errNoMatchingCertificateFingerprint = errors.New("remote certificate does not match any fingerprint")
errICEConnectionNotStarted = errors.New("ICE connection not started")
errICECandidateTypeUnknown = errors.New("unknown candidate type")
errICEInvalidConvertCandidateType = errors.New("cannot convert ice.CandidateType into webrtc.ICECandidateType, invalid type")
errICEAgentNotExist = errors.New("ICEAgent does not exist")
errICECandiatesCoversionFailed = errors.New("unable to convert ICE candidates to ICECandidates")
errICERoleUnknown = errors.New("unknown ICE Role")
errICEProtocolUnknown = errors.New("unknown protocol")
errICEGathererNotStarted = errors.New("gatherer not started")
errMediaEngineParseError = errors.New("format parse error")
errMediaEngineCodecNotFound = errors.New("could not find codec")
errNetworkTypeUnknown = errors.New("unknown network type")
errSDPDoesNotMatchOffer = errors.New("new sdp does not match previous offer")
errSDPDoesNotMatchAnswer = errors.New("new sdp does not match previous answer")
errPeerConnSDPTypeInvalidValue = errors.New("provided value is not a valid enum value of type SDPType")
errPeerConnStateChangeInvalid = errors.New("invalid state change op")
errPeerConnStateChangeUnhandled = errors.New("unhandled state change op")
errPeerConnSDPTypeInvalidValueSetLocalDescription = errors.New("invalid SDP type supplied to SetLocalDescription()")
errPeerConnRemoteDescriptionWithoutMidValue = errors.New("remoteDescription contained media section without mid value")
errPeerConnRemoteDescriptionNil = errors.New("remoteDescription has not been set yet")
errPeerConnSingleMediaSectionHasExplicitSSRC = errors.New("single media section has an explicit SSRC")
errPeerConnRemoteSSRCAddTransceiver = errors.New("could not add transceiver for remote SSRC")
errPeerConnSimulcastMidAndRidRTPExtensionRequired = errors.New("mid and rid RTP Extensions required for Simulcast")
errPeerConnSimulcastIncomingSSRCFailed = errors.New("incoming SSRC failed Simulcast probing")
errPeerConnAddTransceiverFromKindOnlyAcceptsOne = errors.New("AddTransceiverFromKind only accepts one RtpTransceiverInit")
errPeerConnAddTransceiverFromTrackOnlyAcceptsOne = errors.New("AddTransceiverFromTrack only accepts one RtpTransceiverInit")
errPeerConnCodecsNotFound = errors.New("no codecs found")
errPeerConnAddTransceiverFromKindSupport = errors.New("AddTransceiverFromKind currently only supports recvonly and sendrecv")
errPeerConnAddTransceiverFromTrackOneTransceiver = errors.New("AddTransceiverFromTrack only accepts one RtpTransceiverInit")
errPeerConnSetIdentityProviderNotImplemented = errors.New("TODO SetIdentityProvider")
errPeerConnWriteRTCPOpenWriteStream = errors.New("WriteRTCP failed to open WriteStream")
errPeerConnCodecPayloaderNotSet = errors.New("codec payloader not set")
errPeerConnTranscieverMidNil = errors.New("cannot find transceiver with mid")
errRTPReceiverDTLSTransportNil = errors.New("DTLSTransport must not be nil")
errRTPReceiverReceiveAlreadyCalled = errors.New("Receive has already been called")
errRTPReceiverWithSSRCTrackStreamNotFound = errors.New("unable to find stream for Track with SSRC")
errRTPReceiverForSSRCTrackStreamNotFound = errors.New("no trackStreams found for SSRC")
errRTPSenderTrackNil = errors.New("Track must not be nil")
errRTPSenderDTLSTransportNil = errors.New("DTLSTransport must not be nil")
errRTPSenderCannotConstructRemoteTrack = errors.New("RTPSender can not be constructed with remote track")
errRTPSenderSendAlreadyCalled = errors.New("Send has already been called")
errRTPSenderStopped = errors.New("RTPSender has been stopped")
errRTPTransceiverCannotChangeMid = errors.New("errRTPSenderTrackNil")
errRTPTransceiverSetSendingInvalidState = errors.New("invalid state change in RTPTransceiver.setSending")
errSCTPTransportDTLS = errors.New("DTLS not established")
errSDPZeroTransceivers = errors.New("addTransceiverSDP() called with 0 transceivers")
errSDPMediaSectionMediaDataChanInvalid = errors.New("invalid Media Section. Media + DataChannel both enabled")
errSDPMediaSectionMultipleTrackInvalid = errors.New("invalid Media Section. Can not have multiple tracks in one MediaSection in UnifiedPlan")
errSDPParseExtMap = errors.New("failed to parse ExtMap")
errSDPRemoteDescriptionChangedExtMap = errors.New("RemoteDescription changed some extmaps values")
errSettingEngineSetAnsweringDTLSRole = errors.New("SetAnsweringDTLSRole must DTLSRoleClient or DTLSRoleServer")
errSignalingStateCannotRollback = errors.New("can't rollback from stable state")
errSignalingStateProposedTransitionInvalid = errors.New("invalid proposed signaling state transition")
errStatsICECandidateStateInvalid = errors.New("cannot convert to StatsICECandidatePairStateSucceeded invalid ice candidate state")
errTrackLocalTrackRead = errors.New("this is a local track and must not be read from")
errTrackLocalTrackWrite = errors.New("this is a remote track and must not be written to")
errTrackSSRCNewTrackZero = errors.New("SSRC supplied to NewTrack() must be non-zero")
errQuickTransportFingerprintNoMatch = errors.New("no matching fingerprint")
errQuickTransportICEConnectionNotStarted = errors.New("ICE connection not started")
)

View File

@@ -1,13 +1,13 @@
package main
import (
"errors"
"fmt"
"io"
"time"
"github.com/pion/rtcp"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/examples/internal/signal"
)
@@ -15,7 +15,7 @@ const (
rtcpPLIInterval = time.Second * 3
)
func main() {
func main() { // nolint:gocognit
sdpChan := signal.HTTPSDPServer()
// Everything below is the Pion WebRTC API, thanks for using it ❤️.
@@ -82,7 +82,7 @@ func main() {
}
// ErrClosedPipe means we don't have any subscribers, this is ok if no peers have connected yet
if _, err = localTrack.Write(rtpBuf[:i]); err != nil && err != io.ErrClosedPipe {
if _, err = localTrack.Write(rtpBuf[:i]); err != nil && !errors.Is(err, io.ErrClosedPipe) {
panic(err)
}
}

View File

@@ -6,7 +6,6 @@ import (
"time"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/examples/internal/signal"
)

View File

@@ -5,7 +5,6 @@ import (
"time"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/examples/internal/signal"
)

View File

@@ -6,7 +6,6 @@ import (
"time"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/examples/internal/signal"
)

View File

@@ -6,7 +6,6 @@ import (
"time"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/examples/internal/signal"
)

View File

@@ -2,6 +2,7 @@ package main
import (
"encoding/json"
"errors"
"flag"
"fmt"
"html/template"
@@ -15,6 +16,11 @@ import (
// Examples represents the examples loaded from examples.json.
type Examples []*Example
var (
errListExamples = errors.New("failed to list examples (please run in the examples folder)")
errParseExamples = errors.New("failed to parse examples")
)
// Example represents an example loaded from examples.json.
type Example struct {
Title string `json:"title"`
@@ -113,7 +119,7 @@ func serve(addr string) error {
func getExamples() (*Examples, error) {
file, err := os.Open("./examples.json")
if err != nil {
return nil, fmt.Errorf("failed to list examples (please run in the examples folder): %v", err)
return nil, fmt.Errorf("%w: %v", errListExamples, err)
}
defer func() {
closeErr := file.Close()
@@ -125,7 +131,7 @@ func getExamples() (*Examples, error) {
var examples Examples
err = json.NewDecoder(file).Decode(&examples)
if err != nil {
return nil, fmt.Errorf("failed to parse examples: %v", err)
return nil, fmt.Errorf("%w: %v", errParseExamples, err)
}
for _, example := range examples {

View File

@@ -4,10 +4,10 @@ import (
"context"
"fmt"
"io"
"math/rand"
"os"
"time"
"github.com/pion/randutil"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/examples/internal/signal"
"github.com/pion/webrtc/v3/pkg/media"
@@ -56,7 +56,7 @@ func main() {
}
// Create a video track
videoTrack, err := peerConnection.NewTrack(payloadType, rand.Uint32(), "video", "pion")
videoTrack, err := peerConnection.NewTrack(payloadType, randutil.NewMathRandomGenerator().Uint32(), "video", "pion")
if err != nil {
panic(err)
}

View File

@@ -1,18 +1,16 @@
package signal
import (
"math/rand"
)
import "github.com/pion/randutil"
// RandSeq generates a random string to serve as dummy data
//
// It returns a deterministic sequence of values each time a program is run.
// Use rand.Seed() function in your real applications.
func RandSeq(n int) string {
letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
b := make([]rune, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
val, err := randutil.GenerateCryptoRandomString(n, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
if err != nil {
panic(err)
}
return string(b)
return val
}

View File

@@ -9,7 +9,6 @@ import (
"github.com/pion/quic"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/examples/internal/signal"
)

View File

@@ -6,7 +6,6 @@ import (
"time"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/examples/internal/signal"
)

View File

@@ -11,15 +11,13 @@ import (
"time"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/examples/internal/signal"
)
func signalCandidate(addr string, c *webrtc.ICECandidate) error {
payload := []byte(c.ToJSON().Candidate)
resp, err := http.Post(fmt.Sprintf("http://%s/candidate", addr),
resp, err := http.Post(fmt.Sprintf("http://%s/candidate", addr), // nolint:noctx
"application/json; charset=utf-8", bytes.NewReader(payload))
if err != nil {
return err
}
@@ -31,7 +29,7 @@ func signalCandidate(addr string, c *webrtc.ICECandidate) error {
return nil
}
func main() {
func main() { // nolint:gocognit
offerAddr := flag.String("offer-address", "localhost:50000", "Address that the Offer HTTP server is hosted on.")
answerAddr := flag.String("answer-address", ":60000", "Address that the Answer HTTP server is hosted on.")
flag.Parse()
@@ -108,7 +106,7 @@ func main() {
if err != nil {
panic(err)
}
resp, err := http.Post(fmt.Sprintf("http://%s/sdp", *offerAddr), "application/json; charset=utf-8", bytes.NewReader(payload))
resp, err := http.Post(fmt.Sprintf("http://%s/sdp", *offerAddr), "application/json; charset=utf-8", bytes.NewReader(payload)) // nolint:noctx
if err != nil {
panic(err)
} else if closeErr := resp.Body.Close(); closeErr != nil {

View File

@@ -11,15 +11,12 @@ import (
"time"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/examples/internal/signal"
)
func signalCandidate(addr string, c *webrtc.ICECandidate) error {
payload := []byte(c.ToJSON().Candidate)
resp, err := http.Post(fmt.Sprintf("http://%s/candidate", addr),
"application/json; charset=utf-8", bytes.NewReader(payload))
resp, err := http.Post(fmt.Sprintf("http://%s/candidate", addr), "application/json; charset=utf-8", bytes.NewReader(payload)) //nolint:noctx
if err != nil {
return err
}
@@ -31,7 +28,7 @@ func signalCandidate(addr string, c *webrtc.ICECandidate) error {
return nil
}
func main() {
func main() { //nolint:gocognit
offerAddr := flag.String("offer-address", ":50000", "Address that the Offer HTTP server is hosted on.")
answerAddr := flag.String("answer-address", "127.0.0.1:60000", "Address that the Answer HTTP server is hosted on.")
flag.Parse()
@@ -160,7 +157,7 @@ func main() {
if err != nil {
panic(err)
}
resp, err := http.Post(fmt.Sprintf("http://%s/sdp", *answerAddr), "application/json; charset=utf-8", bytes.NewReader(payload))
resp, err := http.Post(fmt.Sprintf("http://%s/sdp", *answerAddr), "application/json; charset=utf-8", bytes.NewReader(payload)) // nolint:noctx
if err != nil {
panic(err)
} else if err := resp.Body.Close(); err != nil {

View File

@@ -8,6 +8,7 @@ import (
"os"
"time"
"github.com/pion/randutil"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/pkg/media"
"github.com/pion/webrtc/v3/pkg/media/ivfreader"
@@ -65,7 +66,12 @@ func createPeerConnection(w http.ResponseWriter, r *http.Request) {
// Add a single video track
func addVideo(w http.ResponseWriter, r *http.Request) {
videoTrack, err := peerConnection.NewTrack(webrtc.DefaultPayloadTypeVP8, rand.Uint32(), fmt.Sprintf("video-%d", rand.Uint32()), fmt.Sprintf("video-%d", rand.Uint32()))
videoTrack, err := peerConnection.NewTrack(
webrtc.DefaultPayloadTypeVP8,
randutil.NewMathRandomGenerator().Uint32(),
fmt.Sprintf("video-%d", randutil.NewMathRandomGenerator().Uint32()),
fmt.Sprintf("video-%d", randutil.NewMathRandomGenerator().Uint32()),
)
if err != nil {
panic(err)
}

View File

@@ -4,10 +4,10 @@ import (
"context"
"fmt"
"io"
"math/rand"
"os"
"time"
"github.com/pion/randutil"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/examples/internal/signal"
"github.com/pion/webrtc/v3/pkg/media"
@@ -59,7 +59,7 @@ func main() {
if haveVideoFile {
// Create a video track
videoTrack, addTrackErr := peerConnection.NewTrack(getPayloadType(mediaEngine, webrtc.RTPCodecTypeVideo, "VP8"), rand.Uint32(), "video", "pion")
videoTrack, addTrackErr := peerConnection.NewTrack(getPayloadType(mediaEngine, webrtc.RTPCodecTypeVideo, "VP8"), randutil.NewMathRandomGenerator().Uint32(), "video", "pion")
if addTrackErr != nil {
panic(addTrackErr)
}
@@ -106,7 +106,7 @@ func main() {
if haveAudioFile {
// Create a audio track
audioTrack, addTrackErr := peerConnection.NewTrack(getPayloadType(mediaEngine, webrtc.RTPCodecTypeAudio, "opus"), rand.Uint32(), "audio", "pion")
audioTrack, addTrackErr := peerConnection.NewTrack(getPayloadType(mediaEngine, webrtc.RTPCodecTypeAudio, "opus"), randutil.NewMathRandomGenerator().Uint32(), "audio", "pion")
if addTrackErr != nil {
panic(addTrackErr)
}

View File

@@ -2,9 +2,9 @@ package main
import (
"fmt"
"math/rand"
"time"
"github.com/pion/randutil"
"github.com/pion/rtcp"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/examples/internal/signal"
@@ -52,7 +52,7 @@ func main() {
}
// Create Track that we send video back to browser on
outputTrack, err := peerConnection.NewTrack(videoCodecs[0].PayloadType, rand.Uint32(), "video", "pion")
outputTrack, err := peerConnection.NewTrack(videoCodecs[0].PayloadType, randutil.NewMathRandomGenerator().Uint32(), "video", "pion")
if err != nil {
panic(err)
}

View File

@@ -7,11 +7,10 @@ import (
"github.com/pion/rtcp"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/examples/internal/signal"
"github.com/pion/webrtc/v3/pkg/media"
"github.com/pion/webrtc/v3/pkg/media/ivfwriter"
"github.com/pion/webrtc/v3/pkg/media/oggwriter"
"github.com/pion/webrtc/v3/examples/internal/signal"
)
func saveToDisk(i media.Writer, track *webrtc.Track) {

View File

@@ -1,12 +1,13 @@
package main
import (
"errors"
"fmt"
"io"
"math/rand"
"net/url"
"time"
"github.com/pion/randutil"
"github.com/pion/rtcp"
"github.com/pion/sdp/v3"
"github.com/pion/webrtc/v3"
@@ -38,7 +39,7 @@ func main() {
panic("Offer contained no video codecs")
}
//Configure required extensions
// Configure required extensions
sdes, _ := url.Parse(sdp.SDESRTPStreamIDURI)
sdedMid, _ := url.Parse(sdp.SDESMidURI)
@@ -73,19 +74,19 @@ func main() {
outputTracks := map[string]*webrtc.Track{}
// Create Track that we send video back to browser on
outputTrack, err := peerConnection.NewTrack(videoCodecs[0].PayloadType, rand.Uint32(), "video_q", "pion_q")
outputTrack, err := peerConnection.NewTrack(videoCodecs[0].PayloadType, randutil.NewMathRandomGenerator().Uint32(), "video_q", "pion_q")
if err != nil {
panic(err)
}
outputTracks["q"] = outputTrack
outputTrack, err = peerConnection.NewTrack(videoCodecs[0].PayloadType, rand.Uint32(), "video_h", "pion_h")
outputTrack, err = peerConnection.NewTrack(videoCodecs[0].PayloadType, randutil.NewMathRandomGenerator().Uint32(), "video_h", "pion_h")
if err != nil {
panic(err)
}
outputTracks["h"] = outputTrack
outputTrack, err = peerConnection.NewTrack(videoCodecs[0].PayloadType, rand.Uint32(), "video_f", "pion_f")
outputTrack, err = peerConnection.NewTrack(videoCodecs[0].PayloadType, randutil.NewMathRandomGenerator().Uint32(), "video_f", "pion_f")
if err != nil {
panic(err)
}
@@ -135,7 +136,7 @@ func main() {
packet.SSRC = outputTracks[rid].SSRC()
if writeErr := outputTracks[rid].WriteRTP(packet); writeErr != nil && writeErr != io.ErrClosedPipe {
if writeErr := outputTracks[rid].WriteRTP(packet); writeErr != nil && !errors.Is(writeErr, io.ErrClosedPipe) {
panic(writeErr)
}
}

View File

@@ -1,18 +1,19 @@
package main
import (
"errors"
"fmt"
"io"
"math/rand"
"time"
"github.com/pion/randutil"
"github.com/pion/rtcp"
"github.com/pion/rtp"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/examples/internal/signal"
)
func main() {
func main() { // nolint:gocognit
// Everything below is the Pion WebRTC API! Thanks for using it ❤️.
// Wait for the offer to be pasted
@@ -54,7 +55,7 @@ func main() {
}
// Create Track that we send video back to browser on
outputTrack, err := peerConnection.NewTrack(videoCodecs[0].PayloadType, rand.Uint32(), "video", "pion")
outputTrack, err := peerConnection.NewTrack(videoCodecs[0].PayloadType, randutil.NewMathRandomGenerator().Uint32(), "video", "pion")
if err != nil {
panic(err)
}
@@ -174,7 +175,7 @@ func main() {
// Keep an increasing sequence number
packet.SequenceNumber = i
// Write out the packet, ignoring closed pipe if nobody is listening
if err := outputTrack.WriteRTP(packet); err != nil && err != io.ErrClosedPipe {
if err := outputTrack.WriteRTP(packet); err != nil && !errors.Is(err, io.ErrClosedPipe) {
panic(err)
}
}

14
go.mod
View File

@@ -4,16 +4,16 @@ go 1.12
require (
github.com/pion/datachannel v1.4.21
github.com/pion/dtls/v2 v2.0.2
github.com/pion/ice/v2 v2.0.6
github.com/pion/dtls/v2 v2.0.3
github.com/pion/ice/v2 v2.0.7
github.com/pion/logging v0.2.2
github.com/pion/quic v0.1.4
github.com/pion/randutil v0.1.0
github.com/pion/rtcp v1.2.3
github.com/pion/rtp v1.6.0
github.com/pion/sctp v1.7.10
github.com/pion/sdp/v3 v3.0.1
github.com/pion/srtp v1.5.1
github.com/pion/rtcp v1.2.4
github.com/pion/rtp v1.6.1
github.com/pion/sctp v1.7.11
github.com/pion/sdp/v3 v3.0.2
github.com/pion/srtp v1.5.2
github.com/pion/transport v0.10.1
github.com/sclevine/agouti v3.0.0+incompatible
github.com/stretchr/testify v1.6.1

35
go.sum
View File

@@ -102,29 +102,29 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/pion/datachannel v1.4.21 h1:3ZvhNyfmxsAqltQrApLPQMhSFNA+aT87RqyCq4OXmf0=
github.com/pion/datachannel v1.4.21/go.mod h1:oiNyP4gHx2DIwRzX/MFyH0Rz/Gz05OgBlayAI2hAWjg=
github.com/pion/dtls/v2 v2.0.2 h1:FHCHTiM182Y8e15aFTiORroiATUI16ryHiQh8AIOJ1E=
github.com/pion/dtls/v2 v2.0.2/go.mod h1:27PEO3MDdaCfo21heT59/vsdmZc0zMt9wQPcSlLu/1I=
github.com/pion/ice/v2 v2.0.6 h1:7Jf3AX6VIjgO2tGRyT0RGGxkDYOF4m5I5DQzf34IN1Y=
github.com/pion/ice/v2 v2.0.6/go.mod h1:xOXvVRlQC/B7FPJeJYKY6IepFRAKb3t1un1K9boYaaQ=
github.com/pion/dtls/v2 v2.0.3 h1:3qQ0s4+TXD00rsllL8g8KQcxAs+Y/Z6oz618RXX6p14=
github.com/pion/dtls/v2 v2.0.3/go.mod h1:TUjyL8bf8LH95h81Xj7kATmzMRt29F/4lxpIPj2Xe4Y=
github.com/pion/ice/v2 v2.0.7 h1:3Iv+EfthCdPbJCsPbhnL4xRzolR1oh9mJTuUsxyxPJI=
github.com/pion/ice/v2 v2.0.7/go.mod h1:0C4VBZxkO3A7Qj5ZEgZut8OptbJFSbuGNyPyJMftuHA=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/mdns v0.0.4 h1:O4vvVqr4DGX63vzmO6Fw9vpy3lfztVWHGCQfyw0ZLSY=
github.com/pion/mdns v0.0.4/go.mod h1:R1sL0p50l42S5lJs91oNdUL58nm0QHrhxnSegr++qC0=
github.com/pion/quic v0.1.4 h1:bNz9sCJjlM3GqMdq7Fne57FiWfdyiJ++yHVbuqeoD3Y=
github.com/pion/quic v0.1.4/go.mod h1:dBhNvkLoQqRwfi6h3Vqj3IcPLgiW7rkZxBbRdp7Vzvk=
github.com/pion/randutil v0.0.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
github.com/pion/rtcp v1.2.3 h1:2wrhKnqgSz91Q5nzYTO07mQXztYPtxL8a0XOss4rJqA=
github.com/pion/rtcp v1.2.3/go.mod h1:zGhIv0RPRF0Z1Wiij22pUt5W/c9fevqSzT4jje/oK7I=
github.com/pion/rtp v1.6.0 h1:4Ssnl/T5W2LzxHj9ssYpGVEQh3YYhQFNVmSWO88MMwk=
github.com/pion/rtp v1.6.0/go.mod h1:QgfogHsMBVE/RFNno467U/KBqfUywEH+HK+0rtnwsdI=
github.com/pion/sctp v1.7.10 h1:o3p3/hZB5Cx12RMGyWmItevJtZ6o2cpuxaw6GOS4x+8=
github.com/pion/rtcp v1.2.4 h1:NT3H5LkUGgaEapvp0HGik+a+CpflRF7KTD7H+o7OWIM=
github.com/pion/rtcp v1.2.4/go.mod h1:52rMNPWFsjr39z9B9MhnkqhPLoeHTv1aN63o/42bWE0=
github.com/pion/rtp v1.6.1 h1:2Y2elcVBrahYnHKN2X7rMHX/r1R4TEBMP1LaVu/wNhk=
github.com/pion/rtp v1.6.1/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
github.com/pion/sctp v1.7.10/go.mod h1:EhpTUQu1/lcK3xI+eriS6/96fWetHGCvBi9MSsnaBN0=
github.com/pion/sdp/v3 v3.0.1 h1:we4OyeTT6s+6sxrAKy/LVywskx1dzUQlh4xu3b+iAs0=
github.com/pion/sdp/v3 v3.0.1/go.mod h1:bNiSknmJE0HYBprTHXKPQ3+JjacTv5uap92ueJZKsRk=
github.com/pion/srtp v1.5.1 h1:9Q3jAfslYZBt+C69SI/ZcONJh9049JUHZWYRRf5KEKw=
github.com/pion/srtp v1.5.1/go.mod h1:B+QgX5xPeQTNc1CJStJPHzOlHK66ViMDWTT0HZTCkcA=
github.com/pion/sctp v1.7.11 h1:UCnj7MsobLKLuP/Hh+JMiI/6W5Bs/VF45lWKgHFjSIE=
github.com/pion/sctp v1.7.11/go.mod h1:EhpTUQu1/lcK3xI+eriS6/96fWetHGCvBi9MSsnaBN0=
github.com/pion/sdp/v3 v3.0.2 h1:UNnSPVaMM+Pdu/mR9UvAyyo6zkdYbKeuOooCwZvTl/g=
github.com/pion/sdp/v3 v3.0.2/go.mod h1:bNiSknmJE0HYBprTHXKPQ3+JjacTv5uap92ueJZKsRk=
github.com/pion/srtp v1.5.2 h1:25DmvH+fqKZDqvX64vTwnycVwL9ooJxHF/gkX16bDBY=
github.com/pion/srtp v1.5.2/go.mod h1:NiBff/MSxUwMUwx/fRNyD/xGE+dVvf8BOCeXhjCXZ9U=
github.com/pion/stun v0.3.5 h1:uLUCBCkQby4S1cf6CGuR9QrVOKcvUwFeemaC865QHDg=
github.com/pion/stun v0.3.5/go.mod h1:gDMim+47EeEtfWogA37n6qXZS88L5V6LqFcf+DZA2UA=
github.com/pion/transport v0.8.10/go.mod h1:tBmha/UCjpum5hqTWhfAEs3CO4/tHSg0MYRhSzR+CZ8=
@@ -172,7 +172,6 @@ github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYED
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -190,8 +189,9 @@ golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -254,8 +254,9 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=

View File

@@ -122,7 +122,7 @@ func (c ICECandidate) toICE() (ice.Candidate, error) {
}
return ice.NewCandidateRelay(&config)
default:
return nil, fmt.Errorf("unknown candidate type: %s", c.Typ)
return nil, fmt.Errorf("%w: %s", errICECandidateTypeUnknown, c.Typ)
}
}
@@ -137,7 +137,7 @@ func convertTypeFromICE(t ice.CandidateType) (ICECandidateType, error) {
case ice.CandidateTypeRelay:
return ICECandidateTypeRelay, nil
default:
return ICECandidateType(t), fmt.Errorf("unknown ICE candidate type: %s", t)
return ICECandidateType(t), fmt.Errorf("%w: %s", errICECandidateTypeUnknown, t)
}
}

View File

@@ -87,7 +87,7 @@ func TestICECandidate_Convert(t *testing.T) {
for i, testCase := range testCases {
var expectedICE ice.Candidate
var err error
switch testCase.expectedType {
switch testCase.expectedType { // nolint:exhaustive
case ice.CandidateTypeHost:
config := ice.CandidateHostConfig{
Network: testCase.expectedNetwork,
@@ -110,7 +110,6 @@ func TestICECandidate_Convert(t *testing.T) {
RelPort: testCase.expectedRelatedAddress.Port,
}
expectedICE, err = ice.NewCandidateServerReflexive(&config)
assert.NoError(t, err)
case ice.CandidateTypePeerReflexive:
config := ice.CandidatePeerReflexiveConfig{
Network: testCase.expectedNetwork,

View File

@@ -57,7 +57,7 @@ func NewICECandidateType(raw string) (ICECandidateType, error) {
case iceCandidateTypeRelayStr:
return ICECandidateTypeRelay, nil
default:
return ICECandidateType(Unknown), fmt.Errorf("unknown ICE candidate type: %s", raw)
return ICECandidateType(Unknown), fmt.Errorf("%w: %s", errICECandidateTypeUnknown, raw)
}
}
@@ -88,9 +88,7 @@ func getCandidateType(candidateType ice.CandidateType) (ICECandidateType, error)
return ICECandidateTypeRelay, nil
default:
// NOTE: this should never happen[tm]
err := fmt.Errorf(
"cannot convert ice.CandidateType into webrtc.ICECandidateType, invalid type: %s",
candidateType.String())
err := fmt.Errorf("%w: %s", errICEInvalidConvertCandidateType, candidateType.String())
return ICECandidateType(Unknown), err
}
}

View File

@@ -31,7 +31,7 @@ func NewICEProtocol(raw string) (ICEProtocol, error) {
case strings.EqualFold(iceProtocolTCPStr, raw):
return ICEProtocolTCP, nil
default:
return ICEProtocol(Unknown), fmt.Errorf("unknown protocol: %s", raw)
return ICEProtocol(Unknown), fmt.Errorf("%w: %s", errICEProtocolUnknown, raw)
}
}

View File

@@ -4,7 +4,7 @@ package webrtc
import (
"context"
"errors"
"fmt"
"sync"
"sync/atomic"
"time"
@@ -83,7 +83,7 @@ func (t *ICETransport) Start(gatherer *ICEGatherer, params ICEParameters, role *
agent := t.gatherer.getAgent()
if agent == nil {
return errors.New("ICEAgent does not exist, unable to start ICETransport")
return fmt.Errorf("%w: unable to start ICETransport", errICEAgentNotExist)
}
if err := agent.OnConnectionStateChange(func(iceState ice.ConnectionState) {
@@ -99,7 +99,7 @@ func (t *ICETransport) Start(gatherer *ICEGatherer, params ICEParameters, role *
if err := agent.OnSelectedCandidatePairChange(func(local, remote ice.Candidate) {
candidates, err := newICECandidatesFromICE([]ice.Candidate{local, remote})
if err != nil {
t.log.Warnf("Unable to convert ICE candidates to ICECandidates: %s", err)
t.log.Warnf("%w: %s", errICECandiatesCoversionFailed, err)
return
}
t.onSelectedCandidatePairChange(NewICECandidatePair(&candidates[0], &candidates[1]))
@@ -131,7 +131,7 @@ func (t *ICETransport) Start(gatherer *ICEGatherer, params ICEParameters, role *
params.Password)
default:
err = errors.New("unknown ICE Role")
err = errICERoleUnknown
}
// Reacquire the lock to set the connection/mux
@@ -160,7 +160,7 @@ func (t *ICETransport) restart() error {
agent := t.gatherer.getAgent()
if agent == nil {
return errors.New("ICEAgent does not exist, unable to restart ICETransport")
return fmt.Errorf("%w: unable to restart ICETransport", errICEAgentNotExist)
}
if err := agent.Restart(t.gatherer.api.settingEngine.candidates.UsernameFragment, t.gatherer.api.settingEngine.candidates.Password); err != nil {
@@ -227,7 +227,7 @@ func (t *ICETransport) SetRemoteCandidates(remoteCandidates []ICECandidate) erro
agent := t.gatherer.getAgent()
if agent == nil {
return errors.New("ICEAgent does not exist, unable to set remote candidates")
return fmt.Errorf("%w: unable to set remote candidates", errICEAgentNotExist)
}
for _, c := range remoteCandidates {
@@ -260,7 +260,7 @@ func (t *ICETransport) AddRemoteCandidate(remoteCandidate ICECandidate) error {
agent := t.gatherer.getAgent()
if agent == nil {
return errors.New("ICEAgent does not exist, unable to add remote candidates")
return fmt.Errorf("%w: unable to add remote candidates", errICEAgentNotExist)
}
err = agent.AddRemoteCandidate(c)
@@ -287,7 +287,7 @@ func (t *ICETransport) NewEndpoint(f mux.MatchFunc) *mux.Endpoint {
func (t *ICETransport) ensureGatherer() error {
if t.gatherer == nil {
return errors.New("gatherer not started")
return errICEGathererNotStarted
} else if t.gatherer.getAgent() == nil {
if err := t.gatherer.createAgent(); err != nil {
return err
@@ -341,7 +341,7 @@ func (t *ICETransport) setRemoteCredentials(newUfrag, newPwd string) error {
agent := t.gatherer.getAgent()
if agent == nil {
return errors.New("ICEAgent does not exist, unable to SetRemoteCredentials")
return fmt.Errorf("%w: unable to SetRemoteCredentials", errICEAgentNotExist)
}
return agent.SetRemoteCredentials(newUfrag, newPwd)

View File

@@ -3,11 +3,11 @@
package webrtc
import (
"math/rand"
"sync/atomic"
"testing"
"time"
"github.com/pion/randutil"
"github.com/pion/transport/test"
"github.com/stretchr/testify/assert"
)
@@ -26,7 +26,7 @@ func TestICETransport_OnSelectedCandidatePairChange(t *testing.T) {
t.Fatal(err)
}
opusTrack, err := pcOffer.NewTrack(DefaultPayloadTypeOpus, rand.Uint32(), "audio", "pion1")
opusTrack, err := pcOffer.NewTrack(DefaultPayloadTypeOpus, randutil.NewMathRandomGenerator().Uint32(), "audio", "pion1")
if err != nil {
t.Fatal(err)
}
@@ -37,7 +37,7 @@ func TestICETransport_OnSelectedCandidatePairChange(t *testing.T) {
iceComplete := make(chan bool)
pcAnswer.OnICEConnectionStateChange(func(iceState ICEConnectionState) {
if iceState == ICEConnectionStateConnected {
time.Sleep(3 * time.Second) // TODO PeerConnection.Close() doesn't block for all subsystems
time.Sleep(3 * time.Second)
close(iceComplete)
}
})

View File

@@ -1,6 +1,7 @@
package mux
import (
"errors"
"io"
"net"
"time"
@@ -39,9 +40,9 @@ func (e *Endpoint) Read(p []byte) (int, error) {
// Write writes len(p) bytes to the underlying conn
func (e *Endpoint) Write(p []byte) (int, error) {
n, err := e.mux.nextConn.Write(p)
if err == ice.ErrNoCandidatePairs {
if errors.Is(err, ice.ErrNoCandidatePairs) {
return 0, nil
} else if err == ice.ErrClosed {
} else if errors.Is(err, ice.ErrClosed) {
return 0, io.ErrClosedPipe
}

View File

@@ -2,6 +2,7 @@
package util
import (
"errors"
"strings"
"github.com/pion/randutil"
@@ -58,7 +59,7 @@ func (me multiError) Error() string {
func (me multiError) Is(err error) bool {
for _, e := range me {
if e == err {
if errors.Is(e, err) {
return true
}
if me2, ok := e.(multiError); ok {

View File

@@ -11,7 +11,7 @@ func TestMathRandAlpha(t *testing.T) {
t.Errorf("MathRandAlpha return invalid length")
}
var isLetter = regexp.MustCompile(`^[a-zA-Z]+$`).MatchString
isLetter := regexp.MustCompile(`^[a-zA-Z]+$`).MatchString
if !isLetter(MathRandAlpha(10)) {
t.Errorf("MathRandAlpha should be AlphaNumeric only")
}
@@ -19,10 +19,10 @@ func TestMathRandAlpha(t *testing.T) {
func TestMultiError(t *testing.T) {
rawErrs := []error{
errors.New("err1"),
errors.New("err2"),
errors.New("err3"),
errors.New("err4"),
errors.New("err1"), //nolint
errors.New("err2"), //nolint
errors.New("err3"), //nolint
errors.New("err4"), //nolint
}
errs := FlattenErrs([]error{
rawErrs[0],

View File

@@ -40,6 +40,7 @@ type MediaEngine struct {
// RegisterCodec adds codec to m.
// RegisterCodec is not safe for concurrent use.
func (m *MediaEngine) RegisterCodec(codec *RTPCodec) uint8 {
// nolint:godox
// TODO: dynamically generate a payload type in the range 96-127 if one wasn't provided.
// See https://github.com/pion/webrtc/issues/43
m.codecs = append(m.codecs, codec)
@@ -81,13 +82,13 @@ func (m *MediaEngine) PopulateFromSDP(sd SessionDescription) error {
for _, format := range md.MediaName.Formats {
pt, err := strconv.Atoi(format)
if err != nil {
return fmt.Errorf("format parse error")
return errMediaEngineParseError
}
payloadType := uint8(pt)
payloadCodec, err := sdp.GetCodecForPayloadType(payloadType)
if err != nil {
return fmt.Errorf("could not find codec for payload type %d", payloadType)
return fmt.Errorf("%w: codec for payload type %d", errMediaEngineCodecNotFound, payloadType)
}
var codec *RTPCodec
@@ -158,7 +159,6 @@ func (m *MediaEngine) GetCodecsByKind(kind RTPCodecType) []*RTPCodec {
var codecs []*RTPCodec
for _, codec := range m.codecs {
if codec.Type == kind {
// TODO: clone the codec for safety?
codecs = append(codecs, codec)
}
}
@@ -217,7 +217,7 @@ func NewRTPOpusCodec(payloadType uint8, clockrate uint32) *RTPCodec {
c := NewRTPCodec(RTPCodecTypeAudio,
Opus,
clockrate,
2, //According to RFC7587, Opus RTP streams must have exactly 2 channels.
2, // According to RFC7587, Opus RTP streams must have exactly 2 channels.
"minptime=10;useinbandfec=1",
payloadType,
&codecs.OpusPayloader{})
@@ -416,7 +416,6 @@ type RTPCapabilities struct {
}
func (m *MediaEngine) collectStats(collector *statsReportCollector) {
for _, codec := range m.codecs {
collector.Collecting()
stats := CodecStats{

View File

@@ -84,7 +84,7 @@ func NewNetworkType(raw string) (NetworkType, error) {
case networkTypeTCP6Str:
return NetworkTypeTCP6, nil
default:
return NetworkType(Unknown), fmt.Errorf("unknown network type: %s", raw)
return NetworkType(Unknown), fmt.Errorf("%w: %s", errNetworkTypeUnknown, raw)
}
}
@@ -99,6 +99,6 @@ func getNetworkType(iceNetworkType ice.NetworkType) (NetworkType, error) {
case ice.NetworkTypeTCP6:
return NetworkTypeTCP6, nil
default:
return NetworkType(Unknown), fmt.Errorf("unknown network type: %s", iceNetworkType.String())
return NetworkType(Unknown), fmt.Errorf("%w: %s", errNetworkTypeUnknown, iceNetworkType.String())
}
}

View File

@@ -18,7 +18,6 @@ import (
"github.com/pion/logging"
"github.com/pion/rtcp"
"github.com/pion/sdp/v3"
"github.com/pion/webrtc/v3/internal/util"
"github.com/pion/webrtc/v3/pkg/rtcerr"
)
@@ -318,7 +317,7 @@ func (pc *PeerConnection) negotiationNeededOp() {
}
}
func (pc *PeerConnection) checkNegotiationNeeded() bool {
func (pc *PeerConnection) checkNegotiationNeeded() bool { //nolint:gocognit
// To check if negotiation is needed for connection, perform the following checks:
// Skip 1, 2 steps
// Step 3
@@ -378,6 +377,7 @@ func (pc *PeerConnection) checkNegotiationNeeded() bool {
if _, ok := m.Attribute(t.Direction().String()); !ok {
return true
}
default:
}
}
// Step 5.4
@@ -457,7 +457,7 @@ func (pc *PeerConnection) OnConnectionStateChange(f func(PeerConnectionState)) {
}
// SetConfiguration updates the configuration of this PeerConnection object.
func (pc *PeerConnection) SetConfiguration(configuration Configuration) error {
func (pc *PeerConnection) SetConfiguration(configuration Configuration) error { //nolint:gocognit
// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-setconfiguration (step #2)
if pc.isClosed.get() {
return &rtcerr.InvalidStateError{Err: ErrConnectionClosed}
@@ -560,11 +560,11 @@ func (pc *PeerConnection) hasLocalDescriptionChanged(desc *SessionDescription) b
// CreateOffer starts the PeerConnection and generates the localDescription
// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-createoffer
func (pc *PeerConnection) CreateOffer(options *OfferOptions) (SessionDescription, error) {
func (pc *PeerConnection) CreateOffer(options *OfferOptions) (SessionDescription, error) { //nolint:gocognit
useIdentity := pc.idpLoginURL != nil
switch {
case useIdentity:
return SessionDescription{}, fmt.Errorf("TODO handle identity provider")
return SessionDescription{}, errIdentityProviderNotImplemented
case pc.isClosed.get():
return SessionDescription{}, &rtcerr.InvalidStateError{Err: ErrConnectionClosed}
}
@@ -754,7 +754,7 @@ func (pc *PeerConnection) CreateAnswer(options *AnswerOptions) (SessionDescripti
case pc.RemoteDescription() == nil:
return SessionDescription{}, &rtcerr.InvalidStateError{Err: ErrNoRemoteDescription}
case useIdentity:
return SessionDescription{}, fmt.Errorf("TODO handle identity provider")
return SessionDescription{}, errIdentityProviderNotImplemented
case pc.isClosed.get():
return SessionDescription{}, &rtcerr.InvalidStateError{Err: ErrConnectionClosed}
case pc.signalingState.Get() != SignalingStateHaveRemoteOffer && pc.signalingState.Get() != SignalingStateHaveLocalPranswer:
@@ -787,12 +787,12 @@ func (pc *PeerConnection) CreateAnswer(options *AnswerOptions) (SessionDescripti
}
// 4.4.1.6 Set the SessionDescription
func (pc *PeerConnection) setDescription(sd *SessionDescription, op stateChangeOp) error {
func (pc *PeerConnection) setDescription(sd *SessionDescription, op stateChangeOp) error { //nolint:gocognit
switch {
case pc.isClosed.get():
return &rtcerr.InvalidStateError{Err: ErrConnectionClosed}
case newSDPType(sd.Type.String()) == SDPType(Unknown):
return &rtcerr.TypeError{Err: fmt.Errorf("the provided value '%d' is not a valid enum value of type SDPType", sd.Type)}
return &rtcerr.TypeError{Err: fmt.Errorf("%w: '%d' is not a valid enum value of type SDPType", errPeerConnSDPTypeInvalidValue, sd.Type)}
}
nextState, err := func() (SignalingState, error) {
@@ -802,8 +802,8 @@ func (pc *PeerConnection) setDescription(sd *SessionDescription, op stateChangeO
cur := pc.SignalingState()
setLocal := stateChangeOpSetLocal
setRemote := stateChangeOpSetRemote
newSDPDoesNotMatchOffer := &rtcerr.InvalidModificationError{Err: fmt.Errorf("new sdp does not match previous offer")}
newSDPDoesNotMatchAnswer := &rtcerr.InvalidModificationError{Err: fmt.Errorf("new sdp does not match previous answer")}
newSDPDoesNotMatchOffer := &rtcerr.InvalidModificationError{Err: errSDPDoesNotMatchOffer}
newSDPDoesNotMatchAnswer := &rtcerr.InvalidModificationError{Err: errSDPDoesNotMatchAnswer}
var nextState SignalingState
var err error
@@ -847,7 +847,7 @@ func (pc *PeerConnection) setDescription(sd *SessionDescription, op stateChangeO
pc.pendingLocalDescription = sd
}
default:
return nextState, &rtcerr.OperationError{Err: fmt.Errorf("invalid state change op: %s(%s)", op, sd.Type)}
return nextState, &rtcerr.OperationError{Err: fmt.Errorf("%w: %s(%s)", errPeerConnStateChangeInvalid, op, sd.Type)}
}
case setRemote:
switch sd.Type {
@@ -879,10 +879,10 @@ func (pc *PeerConnection) setDescription(sd *SessionDescription, op stateChangeO
pc.pendingRemoteDescription = sd
}
default:
return nextState, &rtcerr.OperationError{Err: fmt.Errorf("invalid state change op: %s(%s)", op, sd.Type)}
return nextState, &rtcerr.OperationError{Err: fmt.Errorf("%w: %s(%s)", errPeerConnStateChangeInvalid, op, sd.Type)}
}
default:
return nextState, &rtcerr.OperationError{Err: fmt.Errorf("unhandled state change op: %q", op)}
return nextState, &rtcerr.OperationError{Err: fmt.Errorf("%w: %q", errPeerConnStateChangeUnhandled, op)}
}
return nextState, nil
@@ -916,7 +916,7 @@ func (pc *PeerConnection) SetLocalDescription(desc SessionDescription) error {
desc.SDP = pc.lastOffer
default:
return &rtcerr.InvalidModificationError{
Err: fmt.Errorf("invalid SDP type supplied to SetLocalDescription(): %s", desc.Type),
Err: fmt.Errorf("%w: %s", errPeerConnSDPTypeInvalidValueSetLocalDescription, desc.Type),
}
}
}
@@ -958,7 +958,7 @@ func (pc *PeerConnection) LocalDescription() *SessionDescription {
// SetRemoteDescription sets the SessionDescription of the remote peer
// nolint: gocyclo
func (pc *PeerConnection) SetRemoteDescription(desc SessionDescription) error {
func (pc *PeerConnection) SetRemoteDescription(desc SessionDescription) error { //nolint:gocognit
if pc.isClosed.get() {
return &rtcerr.InvalidStateError{Err: ErrConnectionClosed}
}
@@ -982,7 +982,7 @@ func (pc *PeerConnection) SetRemoteDescription(desc SessionDescription) error {
for _, media := range pc.RemoteDescription().parsed.MediaDescriptions {
midValue := getMidValue(media)
if midValue == "" {
return fmt.Errorf("RemoteDescription contained media section without mid value")
return errPeerConnRemoteDescriptionWithoutMidValue
}
if media.MediaName.Media == mediaSectionApplication {
@@ -1126,7 +1126,7 @@ func (pc *PeerConnection) startReceiver(incoming trackDetails, receiver *RTPRece
}
// startRTPReceivers opens knows inbound SRTP streams from the RemoteDescription
func (pc *PeerConnection) startRTPReceivers(incomingTracks []trackDetails, currentTransceivers []*RTPTransceiver) {
func (pc *PeerConnection) startRTPReceivers(incomingTracks []trackDetails, currentTransceivers []*RTPTransceiver) { //nolint:gocognit
localTransceivers := append([]*RTPTransceiver{}, currentTransceivers...)
remoteIsPlanB := false
@@ -1135,6 +1135,8 @@ func (pc *PeerConnection) startRTPReceivers(incomingTracks []trackDetails, curre
remoteIsPlanB = true
case SDPSemanticsUnifiedPlanWithFallback:
remoteIsPlanB = descriptionIsPlanB(pc.RemoteDescription())
default:
// none
}
// Ensure we haven't already started a transceiver for this ssrc
@@ -1198,7 +1200,6 @@ func (pc *PeerConnection) startRTPReceivers(incomingTracks []trackDetails, curre
// startRTPSenders starts all outbound RTP streams
func (pc *PeerConnection) startRTPSenders(currentTransceivers []*RTPTransceiver) {
for _, transceiver := range currentTransceivers {
// TODO(sgotti) when in future we'll avoid replacing a transceiver sender just check the transceiver negotiation status
if transceiver.Sender() != nil && transceiver.Sender().isNegotiated() && !transceiver.Sender().hasSent() {
err := transceiver.Sender().Send(RTPSendParameters{
Encodings: RTPEncodingParameters{
@@ -1206,7 +1207,8 @@ func (pc *PeerConnection) startRTPSenders(currentTransceivers []*RTPTransceiver)
SSRC: transceiver.Sender().Track().SSRC(),
PayloadType: transceiver.Sender().Track().PayloadType(),
},
}})
},
})
if err != nil {
pc.log.Warnf("Failed to start Sender: %s", err)
}
@@ -1251,10 +1253,10 @@ func (pc *PeerConnection) startSCTP() {
pc.sctpTransport.lock.Unlock()
}
func (pc *PeerConnection) handleUndeclaredSSRC(rtpStream io.Reader, ssrc uint32) error {
func (pc *PeerConnection) handleUndeclaredSSRC(rtpStream io.Reader, ssrc uint32) error { //nolint:gocognit
remoteDescription := pc.RemoteDescription()
if remoteDescription == nil {
return fmt.Errorf("remote Description has not been set yet")
return errPeerConnRemoteDescriptionNil
}
// If the remote SDP was only one media section the ssrc doesn't have to be explicitly declared
@@ -1262,7 +1264,7 @@ func (pc *PeerConnection) handleUndeclaredSSRC(rtpStream io.Reader, ssrc uint32)
onlyMediaSection := remoteDescription.parsed.MediaDescriptions[0]
for _, a := range onlyMediaSection.Attributes {
if a.Key == ssrcStr {
return fmt.Errorf("single media section has an explicit SSRC")
return errPeerConnSingleMediaSectionHasExplicitSSRC
}
}
@@ -1278,7 +1280,7 @@ func (pc *PeerConnection) handleUndeclaredSSRC(rtpStream io.Reader, ssrc uint32)
Direction: RTPTransceiverDirectionSendrecv,
})
if err != nil {
return fmt.Errorf("could not add transceiver for remote SSRC %d: %s", ssrc, err)
return fmt.Errorf("%w: %d: %s", errPeerConnRemoteSSRCAddTransceiver, ssrc, err)
}
pc.startReceiver(incoming, t.Receiver())
return nil
@@ -1293,7 +1295,7 @@ func (pc *PeerConnection) handleUndeclaredSSRC(rtpStream io.Reader, ssrc uint32)
sdesMidExtMap := getExtMapByURI(matchedSDPMap, sdp.SDESMidURI)
sdesStreamIDExtMap := getExtMapByURI(matchedSDPMap, sdp.SDESRTPStreamIDURI)
if sdesMidExtMap == nil || sdesStreamIDExtMap == nil {
return fmt.Errorf("mid and rid RTP Extensions required for Simulcast")
return errPeerConnSimulcastMidAndRidRTPExtensionRequired
}
b := make([]byte, receiveMTU)
@@ -1339,7 +1341,7 @@ func (pc *PeerConnection) handleUndeclaredSSRC(rtpStream io.Reader, ssrc uint32)
}
}
return fmt.Errorf("incoming SSRC failed Simulcast probing")
return errPeerConnSimulcastIncomingSSRCFailed
}
// undeclaredMediaProcessor handles RTP/RTCP packets that don't match any a:ssrc lines
@@ -1540,7 +1542,7 @@ func (pc *PeerConnection) AddTransceiverFromKind(kind RTPCodecType, init ...RtpT
direction := RTPTransceiverDirectionSendrecv
if len(init) > 1 {
return nil, fmt.Errorf("AddTransceiverFromKind only accepts one RtpTransceiverInit")
return nil, errPeerConnAddTransceiverFromKindOnlyAcceptsOne
} else if len(init) == 1 {
direction = init[0].Direction
}
@@ -1549,7 +1551,7 @@ func (pc *PeerConnection) AddTransceiverFromKind(kind RTPCodecType, init ...RtpT
case RTPTransceiverDirectionSendrecv:
codecs := pc.api.mediaEngine.GetCodecsByKind(kind)
if len(codecs) == 0 {
return nil, fmt.Errorf("no %s codecs found", kind.String())
return nil, fmt.Errorf("%w: %s", errPeerConnCodecsNotFound, kind.String())
}
track, err := pc.NewTrack(codecs[0].PayloadType, util.RandUint32(), util.MathRandAlpha(trackDefaultIDLength), util.MathRandAlpha(trackDefaultLabelLength))
@@ -1576,7 +1578,7 @@ func (pc *PeerConnection) AddTransceiverFromKind(kind RTPCodecType, init ...RtpT
return t, nil
default:
return nil, fmt.Errorf("AddTransceiverFromKind currently only supports recvonly and sendrecv")
return nil, errPeerConnAddTransceiverFromKindSupport
}
}
@@ -1588,7 +1590,7 @@ func (pc *PeerConnection) AddTransceiverFromTrack(track *Track, init ...RtpTrans
direction := RTPTransceiverDirectionSendrecv
if len(init) > 1 {
return nil, fmt.Errorf("AddTransceiverFromTrack only accepts one RtpTransceiverInit")
return nil, errPeerConnAddTransceiverFromTrackOnlyAcceptsOne
} else if len(init) == 1 {
direction = init[0].Direction
}
@@ -1629,7 +1631,7 @@ func (pc *PeerConnection) AddTransceiverFromTrack(track *Track, init ...RtpTrans
pc.onNegotiationNeeded()
return t, nil
default:
return nil, fmt.Errorf("AddTransceiverFromTrack currently only supports sendonly and sendrecv")
return nil, errPeerConnAddTransceiverFromTrackOneTransceiver
}
}
@@ -1715,7 +1717,7 @@ func (pc *PeerConnection) CreateDataChannel(label string, options *DataChannelIn
// SetIdentityProvider is used to configure an identity provider to generate identity assertions
func (pc *PeerConnection) SetIdentityProvider(provider string) error {
return fmt.Errorf("TODO SetIdentityProvider")
return errPeerConnSetIdentityProviderNotImplemented
}
// WriteRTCP sends a user provided RTCP packet to the connected peer
@@ -1733,7 +1735,7 @@ func (pc *PeerConnection) WriteRTCP(pkts []rtcp.Packet) error {
writeStream, err := srtcpSession.OpenWriteStream()
if err != nil {
return fmt.Errorf("WriteRTCP failed to open WriteStream: %v", err)
return fmt.Errorf("%w: %v", errPeerConnWriteRTCPOpenWriteStream, err)
}
if _, err := writeStream.Write(raw); err != nil {
@@ -1804,7 +1806,7 @@ func (pc *PeerConnection) NewTrack(payloadType uint8, ssrc uint32, id, label str
if err != nil {
return nil, err
} else if codec.Payloader == nil {
return nil, fmt.Errorf("codec payloader not set")
return nil, errPeerConnCodecPayloaderNotSet
}
return NewTrack(payloadType, ssrc, id, label, codec)
@@ -2107,7 +2109,7 @@ func (pc *PeerConnection) generateUnmatchedSDP(transceivers []*RTPTransceiver, u
// generateMatchedSDP generates a SDP and takes the remote state into account
// this is used everytime we have a RemoteDescription
// nolint: gocyclo
func (pc *PeerConnection) generateMatchedSDP(transceivers []*RTPTransceiver, useIdentity bool, includeUnmatched bool, connectionRole sdp.ConnectionRole) (*sdp.SessionDescription, error) {
func (pc *PeerConnection) generateMatchedSDP(transceivers []*RTPTransceiver, useIdentity bool, includeUnmatched bool, connectionRole sdp.ConnectionRole) (*sdp.SessionDescription, error) { //nolint:gocognit
d, err := sdp.NewJSEPSessionDescription(useIdentity)
if err != nil {
return nil, err
@@ -2132,7 +2134,7 @@ func (pc *PeerConnection) generateMatchedSDP(transceivers []*RTPTransceiver, use
for _, media := range pc.RemoteDescription().parsed.MediaDescriptions {
midValue := getMidValue(media)
if midValue == "" {
return nil, fmt.Errorf("RemoteDescription contained media section without mid value")
return nil, errPeerConnRemoteDescriptionWithoutMidValue
}
if media.MediaName.Media == mediaSectionApplication {
@@ -2180,7 +2182,7 @@ func (pc *PeerConnection) generateMatchedSDP(transceivers []*RTPTransceiver, use
}
t, localTransceivers = findByMid(midValue, localTransceivers)
if t == nil {
return nil, fmt.Errorf("cannot find transceiver with mid %q", midValue)
return nil, fmt.Errorf("%w: %q", errPeerConnTranscieverMidNil, midValue)
}
if t.Sender() != nil {
t.Sender().setNegotiated()

View File

@@ -654,7 +654,7 @@ func TestOnICEGatheringStateChange(t *testing.T) {
)
}
switch s {
switch s { // nolint:exhaustive
case ICEGathererStateClosed:
close(seenClosed)
return

View File

@@ -5,15 +5,16 @@ package webrtc
import (
"bufio"
"bytes"
"errors"
"fmt"
"io"
"math/rand"
"reflect"
"strings"
"sync"
"testing"
"time"
"github.com/pion/randutil"
"github.com/pion/rtcp"
"github.com/pion/sdp/v3"
"github.com/pion/transport/test"
@@ -22,6 +23,12 @@ import (
"github.com/stretchr/testify/require"
)
var (
errIncomingTrackIDInvalid = errors.New("incoming Track ID is invalid")
errIncomingTrackLabelInvalid = errors.New("incoming Track Label is invalid")
errNoTransceiverwithMid = errors.New("no transceiver with mid")
)
func offerMediaHasDirection(offer SessionDescription, kind RTPCodecType, direction RTPTransceiverDirection) bool {
for _, media := range offer.parsed.MediaDescriptions {
if media.MediaName.Media == kind.String() {
@@ -72,12 +79,12 @@ func TestPeerConnection_Media_Sample(t *testing.T) {
pcAnswer.OnTrack(func(track *Track, receiver *RTPReceiver) {
if track.ID() != expectedTrackID {
trackMetadataValid <- fmt.Errorf("Incoming Track ID is invalid expected(%s) actual(%s)", expectedTrackID, track.ID())
trackMetadataValid <- fmt.Errorf("%w: expected(%s) actual(%s)", errIncomingTrackIDInvalid, expectedTrackID, track.ID())
return
}
if track.Label() != expectedTrackLabel {
trackMetadataValid <- fmt.Errorf("Incoming Track Label is invalid expected(%s) actual(%s)", expectedTrackLabel, track.Label())
trackMetadataValid <- fmt.Errorf("%w: expected(%s) actual(%s)", errIncomingTrackLabelInvalid, expectedTrackLabel, track.Label())
return
}
close(trackMetadataValid)
@@ -121,7 +128,7 @@ func TestPeerConnection_Media_Sample(t *testing.T) {
}
})
vp8Track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), expectedTrackID, expectedTrackLabel)
vp8Track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), expectedTrackID, expectedTrackLabel)
if err != nil {
t.Fatal(err)
}
@@ -233,11 +240,11 @@ func TestPeerConnection_Media_Shutdown(t *testing.T) {
t.Fatal(err)
}
opusTrack, err := pcOffer.NewTrack(DefaultPayloadTypeOpus, rand.Uint32(), "audio", "pion1")
opusTrack, err := pcOffer.NewTrack(DefaultPayloadTypeOpus, randutil.NewMathRandomGenerator().Uint32(), "audio", "pion1")
if err != nil {
t.Fatal(err)
}
vp8Track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion2")
vp8Track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion2")
if err != nil {
t.Fatal(err)
}
@@ -326,7 +333,7 @@ func TestPeerConnection_Media_Disconnected(t *testing.T) {
t.Fatal(err)
}
vp8Track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion2")
vp8Track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion2")
if err != nil {
t.Fatal(err)
}
@@ -406,7 +413,7 @@ func TestPeerConnection_Media_Closed(t *testing.T) {
t.Fatal(err)
}
vp8Writer, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion2")
vp8Writer, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion2")
if err != nil {
t.Fatal(err)
}
@@ -455,9 +462,9 @@ func TestPeerConnection_Media_Closed(t *testing.T) {
assert.NoError(t, pcOffer.Close())
assert.NoError(t, pcAnswer.Close())
if err = vp8Writer.WriteSample(media.Sample{Data: []byte{0x00}, Samples: 1}); err != io.ErrClosedPipe {
if err = vp8Writer.WriteSample(media.Sample{Data: []byte{0x00}, Samples: 1}); !errors.Is(err, io.ErrClosedPipe) {
t.Fatal("Write to Track with no RTPSenders did not return io.ErrClosedPipe")
} else if err = pcAnswer.WriteRTCP([]rtcp.Packet{&rtcp.RapidResynchronizationRequest{SenderSSRC: 0, MediaSSRC: 0}}); err != io.ErrClosedPipe {
} else if err = pcAnswer.WriteRTCP([]rtcp.Packet{&rtcp.RapidResynchronizationRequest{SenderSSRC: 0, MediaSSRC: 0}}); !errors.Is(err, io.ErrClosedPipe) {
t.Fatal("WriteRTCP to closed PeerConnection did not return io.ErrClosedPipe")
}
}
@@ -482,7 +489,7 @@ func TestUndeclaredSSRC(t *testing.T) {
_, err = pcAnswer.AddTransceiverFromKind(RTPCodecTypeVideo)
assert.NoError(t, err)
vp8Writer, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion2")
vp8Writer, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion2")
assert.NoError(t, err)
_, err = pcOffer.AddTrack(vp8Writer)
@@ -573,7 +580,7 @@ func TestOfferRejectionMissingCodec(t *testing.T) {
t.Fatal(err)
}
track, err := pc.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion2")
track, err := pc.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion2")
if err != nil {
t.Fatal(err)
}
@@ -622,7 +629,6 @@ func TestAddTransceiverFromTrackSendOnly(t *testing.T) {
"track-id",
"track-label",
)
if err != nil {
t.Error(err.Error())
}
@@ -680,7 +686,6 @@ func TestAddTransceiverFromTrackSendRecv(t *testing.T) {
"track-id",
"track-label",
)
if err != nil {
t.Error(err.Error())
}
@@ -770,7 +775,7 @@ func TestAddTransceiverAddTrack_Reuse(t *testing.T) {
assert.Equal(t, []*RTPTransceiver{tr}, pc.GetTransceivers())
addTrack := func() (*Track, *RTPSender) {
track, err := pc.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "foo", "bar")
track, err := pc.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "foo", "bar")
assert.NoError(t, err)
sender, err := pc.AddTrack(track)
@@ -811,7 +816,7 @@ func TestAddTransceiverAddTrack_NewRTPSender_Error(t *testing.T) {
dtlsTransport := pc.dtlsTransport
pc.dtlsTransport = nil
track, err := pc.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "foo", "bar")
track, err := pc.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "foo", "bar")
assert.NoError(t, err)
_, err = pc.AddTrack(track)
@@ -929,7 +934,6 @@ func TestAddTransceiverFromTrackFailsRecvOnly(t *testing.T) {
"track-id",
"track-label",
)
if err != nil {
t.Error(err.Error())
}
@@ -1051,7 +1055,7 @@ func TestGetRegisteredRTPCodecs(t *testing.T) {
func TestPlanBMediaExchange(t *testing.T) {
runTest := func(trackCount int, t *testing.T) {
addSingleTrack := func(p *PeerConnection) *Track {
track, err := p.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), fmt.Sprintf("video-%d", rand.Uint32()), fmt.Sprintf("video-%d", rand.Uint32()))
track, err := p.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), fmt.Sprintf("video-%d", randutil.NewMathRandomGenerator().Uint32()), fmt.Sprintf("video-%d", randutil.NewMathRandomGenerator().Uint32()))
assert.NoError(t, err)
_, err = p.AddTrack(track)
@@ -1137,7 +1141,7 @@ func TestPeerConnection_Start_Only_Negotiated_Senders(t *testing.T) {
assert.NoError(t, err)
defer func() { assert.NoError(t, pcAnswer.Close()) }()
track1, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion1")
track1, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion1")
require.NoError(t, err)
sender1, err := pcOffer.AddTrack(track1)
@@ -1158,7 +1162,7 @@ func TestPeerConnection_Start_Only_Negotiated_Senders(t *testing.T) {
// Add a new track between providing the offer and applying the answer
track2, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion2")
track2, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion2")
require.NoError(t, err)
sender2, err := pcOffer.AddTrack(track2)
@@ -1186,7 +1190,7 @@ func TestPeerConnection_Start_Right_Receiver(t *testing.T) {
}
return transceiver.Receiver() != nil && transceiver.Receiver().haveReceived(), nil
}
return false, fmt.Errorf("no transceiver with mid %q", mid)
return false, fmt.Errorf("%w: %q", errNoTransceiverwithMid, mid)
}
api := NewAPI()
@@ -1203,7 +1207,7 @@ func TestPeerConnection_Start_Right_Receiver(t *testing.T) {
_, err = pcAnswer.AddTransceiverFromKind(RTPCodecTypeVideo, RtpTransceiverInit{Direction: RTPTransceiverDirectionRecvonly})
assert.NoError(t, err)
track1, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion1")
track1, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion1")
require.NoError(t, err)
sender1, err := pcOffer.AddTrack(track1)

View File

@@ -5,7 +5,6 @@ package webrtc
import (
"context"
"io"
"math/rand"
"strconv"
"strings"
"sync"
@@ -13,11 +12,11 @@ import (
"testing"
"time"
"github.com/pion/webrtc/v3/pkg/rtcerr"
"github.com/pion/randutil"
"github.com/pion/transport/test"
"github.com/pion/webrtc/v3/internal/util"
"github.com/pion/webrtc/v3/pkg/media"
"github.com/pion/webrtc/v3/pkg/rtcerr"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -96,7 +95,7 @@ func TestPeerConnection_Renegotiation_AddTrack(t *testing.T) {
_, err = pcAnswer.AddTransceiverFromKind(RTPCodecTypeVideo, RtpTransceiverInit{Direction: RTPTransceiverDirectionRecvonly})
assert.NoError(t, err)
vp8Track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "foo", "bar")
vp8Track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "foo", "bar")
assert.NoError(t, err)
sender, err := pcOffer.AddTrack(vp8Track)
@@ -140,7 +139,7 @@ func TestPeerConnection_Renegotiation_AddTrack_Multiple(t *testing.T) {
_, err := pcAnswer.AddTransceiverFromKind(RTPCodecTypeVideo, RtpTransceiverInit{Direction: RTPTransceiverDirectionRecvonly})
assert.NoError(t, err)
track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), trackName, trackName)
track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), trackName, trackName)
assert.NoError(t, err)
_, err = pcOffer.AddTrack(track)
@@ -222,7 +221,7 @@ func TestPeerConnection_Renegotiation_AddTrack_Rename(t *testing.T) {
_, err = pcOffer.AddTransceiverFromKind(RTPCodecTypeVideo, RtpTransceiverInit{Direction: RTPTransceiverDirectionRecvonly})
assert.NoError(t, err)
vp8Track, err := pcAnswer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "foo1", "bar1")
vp8Track, err := pcAnswer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "foo1", "bar1")
assert.NoError(t, err)
_, err = pcAnswer.AddTrack(vp8Track)
assert.NoError(t, err)
@@ -263,13 +262,13 @@ func TestPeerConnection_Transceiver_Mid(t *testing.T) {
pcAnswer, err := NewPeerConnection(Configuration{})
assert.NoError(t, err)
track1, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion1")
track1, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion1")
require.NoError(t, err)
sender1, err := pcOffer.AddTrack(track1)
require.NoError(t, err)
track2, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion2")
track2, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion2")
require.NoError(t, err)
_, err = pcOffer.AddTrack(track2)
@@ -321,7 +320,7 @@ func TestPeerConnection_Transceiver_Mid(t *testing.T) {
pcOffer.ops.Done()
pcAnswer.ops.Done()
track3, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion3")
track3, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion3")
require.NoError(t, err)
_, err = pcOffer.AddTrack(track3)
@@ -454,7 +453,7 @@ func TestPeerConnection_Renegotiation_RemoveTrack(t *testing.T) {
_, err = pcAnswer.AddTransceiverFromKind(RTPCodecTypeVideo, RtpTransceiverInit{Direction: RTPTransceiverDirectionRecvonly})
assert.NoError(t, err)
vp8Track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "foo", "bar")
vp8Track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "foo", "bar")
assert.NoError(t, err)
rtpSender, err := pcOffer.AddTrack(vp8Track)
@@ -511,7 +510,7 @@ func TestPeerConnection_RoleSwitch(t *testing.T) {
_, err = pcFirstOfferer.AddTransceiverFromKind(RTPCodecTypeVideo, RtpTransceiverInit{Direction: RTPTransceiverDirectionRecvonly})
assert.NoError(t, err)
vp8Track, err := pcSecondOfferer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "foo", "bar")
vp8Track, err := pcSecondOfferer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "foo", "bar")
assert.NoError(t, err)
_, err = pcSecondOfferer.AddTrack(vp8Track)
@@ -622,7 +621,7 @@ func TestPeerConnection_Renegotiation_SetLocalDescription(t *testing.T) {
_, err = pcOffer.AddTransceiverFromKind(RTPCodecTypeVideo, RtpTransceiverInit{Direction: RTPTransceiverDirectionRecvonly})
assert.NoError(t, err)
localTrack, err := pcAnswer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "foo", "bar")
localTrack, err := pcAnswer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "foo", "bar")
assert.NoError(t, err)
sender, err := pcAnswer.AddTrack(localTrack)
@@ -724,7 +723,7 @@ func TestAddDataChannelDuringRenegotation(t *testing.T) {
pcAnswer, err := NewPeerConnection(Configuration{})
assert.NoError(t, err)
track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion")
track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion")
assert.NoError(t, err)
_, err = pcOffer.AddTrack(track)
@@ -792,7 +791,7 @@ func TestNegotiationTrackAndChannel(t *testing.T) {
pcAnswer, err := NewPeerConnection(Configuration{})
assert.NoError(t, err)
track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion")
track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion")
assert.NoError(t, err)
pcAnswer.OnDataChannel(func(*DataChannel) {
@@ -860,7 +859,7 @@ func TestNegotiationNeededRemoveTrack(t *testing.T) {
pcAnswer, err := NewPeerConnection(Configuration{})
assert.NoError(t, err)
track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion")
track, err := pcOffer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion")
assert.NoError(t, err)
pcOffer.OnNegotiationNeeded(func() {
@@ -924,7 +923,7 @@ func TestNegotiationNeededStressOneSided(t *testing.T) {
})
for i := 0; i < 500; i++ {
track, err := pcA.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion")
track, err := pcA.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion")
assert.NoError(t, err)
_, err = pcA.AddTrack(track)

View File

@@ -6,10 +6,9 @@ import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/pion/transport/test"
"github.com/pion/webrtc/v3/pkg/rtcerr"
"github.com/stretchr/testify/assert"
)
// newPair creates two new peer connections (an offerer and an answerer)
@@ -225,6 +224,7 @@ func TestPeerConnection_GetConfiguration(t *testing.T) {
assert.Equal(t, expected.ICETransportPolicy, actual.ICETransportPolicy)
assert.Equal(t, expected.BundlePolicy, actual.BundlePolicy)
assert.Equal(t, expected.RTCPMuxPolicy, actual.RTCPMuxPolicy)
// nolint:godox
// TODO(albrow): Uncomment this after #513 is fixed.
// See: https://github.com/pion/webrtc/issues/513.
// assert.Equal(t, len(expected.Certificates), len(actual.Certificates))

View File

@@ -13,8 +13,10 @@ type writerCloser struct {
bytes.Buffer
}
var errCloseErr = errors.New("close error")
func (w *writerCloser) Close() error {
return errors.New("close error")
return errCloseErr
}
func TestNewWith(t *testing.T) {

View File

@@ -3,6 +3,7 @@ package ivfreader
import (
"encoding/binary"
"errors"
"fmt"
"io"
)
@@ -13,6 +14,15 @@ const (
ivfFrameHeaderSize = 12
)
var (
errNilStream = errors.New("stream is nil")
errIncompleteFrameHeader = errors.New("incomplete frame header")
errIncompleteFrameData = errors.New("incomplete frame data")
errIncompleteFileHeader = errors.New("incomplete file header")
errSignatureMismatch = errors.New("IVF signature mismatch")
errUnknownIVFVersion = errors.New("IVF version unknown, parser may not parse correctly")
)
// IVFFileHeader 32-byte header for IVF files
// https://wiki.multimedia.cx/index.php/IVF
type IVFFileHeader struct {
@@ -45,7 +55,7 @@ type IVFReader struct {
// with an io.Reader input
func NewWith(in io.Reader) (*IVFReader, *IVFFileHeader, error) {
if in == nil {
return nil, nil, fmt.Errorf("stream is nil")
return nil, nil, errNilStream
}
reader := &IVFReader{
@@ -76,8 +86,8 @@ func (i *IVFReader) ParseNextFrame() ([]byte, *IVFFrameHeader, error) {
bytesRead, err := io.ReadFull(i.stream, buffer)
headerBytesRead := bytesRead
if err == io.ErrUnexpectedEOF {
return nil, nil, fmt.Errorf("incomplete frame header")
if errors.Is(err, io.ErrUnexpectedEOF) {
return nil, nil, errIncompleteFrameHeader
} else if err != nil {
return nil, nil, err
}
@@ -89,8 +99,8 @@ func (i *IVFReader) ParseNextFrame() ([]byte, *IVFFrameHeader, error) {
payload := make([]byte, header.FrameSize)
bytesRead, err = io.ReadFull(i.stream, payload)
if err == io.ErrUnexpectedEOF {
return nil, nil, fmt.Errorf("incomplete frame data")
if errors.Is(err, io.ErrUnexpectedEOF) {
return nil, nil, errIncompleteFrameData
} else if err != nil {
return nil, nil, err
}
@@ -105,8 +115,8 @@ func (i *IVFReader) parseFileHeader() (*IVFFileHeader, error) {
buffer := make([]byte, ivfFileHeaderSize)
bytesRead, err := io.ReadFull(i.stream, buffer)
if err == io.ErrUnexpectedEOF {
return nil, fmt.Errorf("incomplete file header")
if errors.Is(err, io.ErrUnexpectedEOF) {
return nil, errIncompleteFileHeader
} else if err != nil {
return nil, err
}
@@ -125,11 +135,9 @@ func (i *IVFReader) parseFileHeader() (*IVFFileHeader, error) {
}
if header.signature != ivfFileHeaderSignature {
return nil, fmt.Errorf("IVF signature mismatch")
return nil, errSignatureMismatch
} else if header.version != uint16(0) {
errStr := fmt.Sprintf("IVF version unknown: %d,"+
" parser may not parse correctly", header.version)
return nil, fmt.Errorf(errStr)
return nil, fmt.Errorf("%w: expected(0) got(%d)", errUnknownIVFVersion, header.version)
}
i.bytesReadSuccesfully += int64(bytesRead)

View File

@@ -2,7 +2,7 @@ package ivfreader
import (
"bytes"
"fmt"
"io"
"testing"
"github.com/stretchr/testify/assert"
@@ -127,7 +127,7 @@ func TestIVFReader_ParseIncompleteFrameHeader(t *testing.T) {
assert.Nil(payload, "Payload should be nil")
assert.Nil(header, "Incomplete header should be nil")
assert.Equal(fmt.Errorf("incomplete frame header"), err)
assert.Equal(errIncompleteFrameHeader, err)
}
func TestIVFReader_ParseIncompleteFramePayload(t *testing.T) {
@@ -150,7 +150,7 @@ func TestIVFReader_ParseIncompleteFramePayload(t *testing.T) {
assert.Nil(payload, "Incomplete payload should be nil")
assert.Nil(header, "Header should be nil")
assert.Equal(fmt.Errorf("incomplete frame data"), err)
assert.Equal(errIncompleteFrameData, err)
}
func TestIVFReader_EOFWhenNoFramesLeft(t *testing.T) {
@@ -163,5 +163,5 @@ func TestIVFReader_EOFWhenNoFramesLeft(t *testing.T) {
_, _, err = reader.ParseNextFrame()
assert.Equal(fmt.Errorf("EOF"), err)
assert.Equal(io.EOF, err)
}

View File

@@ -3,7 +3,7 @@ package ivfwriter
import (
"encoding/binary"
"fmt"
"errors"
"io"
"os"
@@ -11,6 +11,11 @@ import (
"github.com/pion/rtp/codecs"
)
var (
errFileNotOpened = errors.New("file not opened")
errInvalidNilPacket = errors.New("invalid nil packet")
)
// IVFWriter is used to take RTP packets and write them to an IVF on disk
type IVFWriter struct {
ioWriter io.Writer
@@ -36,7 +41,7 @@ func New(fileName string) (*IVFWriter, error) {
// NewWith initialize a new IVF writer with an io.Writer output
func NewWith(out io.Writer) (*IVFWriter, error) {
if out == nil {
return nil, fmt.Errorf("file not opened")
return nil, errFileNotOpened
}
writer := &IVFWriter{
@@ -51,10 +56,10 @@ func NewWith(out io.Writer) (*IVFWriter, error) {
func (i *IVFWriter) writeHeader() error {
header := make([]byte, 32)
copy(header[0:], []byte("DKIF")) // DKIF
copy(header[0:], "DKIF") // DKIF
binary.LittleEndian.PutUint16(header[4:], 0) // Version
binary.LittleEndian.PutUint16(header[6:], 32) // Header size
copy(header[8:], []byte("VP80")) // FOURCC
copy(header[8:], "VP80") // FOURCC
binary.LittleEndian.PutUint16(header[12:], 640) // Width in pixels
binary.LittleEndian.PutUint16(header[14:], 480) // Height in pixels
binary.LittleEndian.PutUint32(header[16:], 30) // Framerate denominator
@@ -69,7 +74,7 @@ func (i *IVFWriter) writeHeader() error {
// WriteRTP adds a new packet and writes the appropriate headers for it
func (i *IVFWriter) WriteRTP(packet *rtp.Packet) error {
if i.ioWriter == nil {
return fmt.Errorf("file not opened")
return errFileNotOpened
}
vp8Packet := codecs.VP8Packet{}

View File

@@ -2,7 +2,6 @@ package ivfwriter
import (
"bytes"
"fmt"
"io"
"testing"
@@ -125,7 +124,7 @@ func TestIVFWriter_AddPacketAndClose(t *testing.T) {
message: "IVFWriter shouldn't be able to write something to a closed file",
messageClose: "IVFWriter should be able to close an already closed file",
packet: nil,
err: fmt.Errorf("file not opened"),
err: errFileNotOpened,
closeErr: nil,
},
{
@@ -133,7 +132,7 @@ func TestIVFWriter_AddPacketAndClose(t *testing.T) {
message: "IVFWriter shouldn't be able to write something an empty packet",
messageClose: "IVFWriter should be able to close the file",
packet: &rtp.Packet{},
err: fmt.Errorf("invalid nil packet"),
err: errInvalidNilPacket,
closeErr: nil,
},
{
@@ -149,7 +148,7 @@ func TestIVFWriter_AddPacketAndClose(t *testing.T) {
message: "IVFWriter shouldn't be able to write something to a closed file",
messageClose: "IVFWriter should be able to close an already closed file",
packet: nil,
err: fmt.Errorf("file not opened"),
err: errFileNotOpened,
closeErr: nil,
},
{

View File

@@ -3,11 +3,11 @@ package oggwriter
import (
"encoding/binary"
"fmt"
"errors"
"io"
"math/rand"
"os"
"github.com/pion/randutil"
"github.com/pion/rtp"
"github.com/pion/rtp/codecs"
)
@@ -22,6 +22,11 @@ const (
pageHeaderSignature = "OggS"
)
var (
errFileNotOpened = errors.New("file not opened")
errInvalidNilPacket = errors.New("invalid nil packet")
)
// OggWriter is used to take RTP packets and write them to an OGG on disk
type OggWriter struct {
stream io.Writer
@@ -53,14 +58,14 @@ func New(fileName string, sampleRate uint32, channelCount uint16) (*OggWriter, e
// NewWith initialize a new OGG Opus writer with an io.Writer output
func NewWith(out io.Writer, sampleRate uint32, channelCount uint16) (*OggWriter, error) {
if out == nil {
return nil, fmt.Errorf("file not opened")
return nil, errFileNotOpened
}
writer := &OggWriter{
stream: out,
sampleRate: sampleRate,
channelCount: channelCount,
serial: rand.Uint32(),
serial: randutil.NewMathRandomGenerator().Uint32(),
checksumTable: generateChecksumTable(),
// Timestamp and Granule MUST start from 1
@@ -102,7 +107,7 @@ func (i *OggWriter) writeHeaders() error {
// ID Header
oggIDHeader := make([]byte, 19)
copy(oggIDHeader[0:], []byte(idPageSignature)) // Magic Signature 'OpusHead'
copy(oggIDHeader[0:], idPageSignature) // Magic Signature 'OpusHead'
oggIDHeader[8] = 1 // Version
oggIDHeader[9] = uint8(i.channelCount) // Channel count
binary.LittleEndian.PutUint16(oggIDHeader[10:], defaultPreSkip) // pre-skip
@@ -120,9 +125,9 @@ func (i *OggWriter) writeHeaders() error {
// Comment Header
oggCommentHeader := make([]byte, 21)
copy(oggCommentHeader[0:], []byte(commentPageSignature)) // Magic Signature 'OpusTags'
copy(oggCommentHeader[0:], commentPageSignature) // Magic Signature 'OpusTags'
binary.LittleEndian.PutUint32(oggCommentHeader[8:], 5) // Vendor Length
copy(oggCommentHeader[12:], []byte("pion")) // Vendor name 'pion'
copy(oggCommentHeader[12:], "pion") // Vendor name 'pion'
binary.LittleEndian.PutUint32(oggCommentHeader[17:], 0) // User Comment List Length
// RFC specifies that the page where the CommentHeader completes should have a granule position of 0
@@ -143,7 +148,7 @@ func (i *OggWriter) createPage(payload []uint8, headerType uint8, granulePos uin
i.lastPayloadSize = len(payload)
page := make([]byte, pageHeaderSize+1+i.lastPayloadSize)
copy(page[0:], []byte(pageHeaderSignature)) // page headers starts with 'OggS'
copy(page[0:], pageHeaderSignature) // page headers starts with 'OggS'
page[4] = 0 // Version
page[5] = headerType // 1 = continuation, 2 = beginning of stream, 4 = end of stream
binary.LittleEndian.PutUint64(page[6:], granulePos) // granule position
@@ -165,7 +170,7 @@ func (i *OggWriter) createPage(payload []uint8, headerType uint8, granulePos uin
// WriteRTP adds a new packet and writes the appropriate headers for it
func (i *OggWriter) WriteRTP(packet *rtp.Packet) error {
if packet == nil {
return fmt.Errorf("packet must not be nil")
return errInvalidNilPacket
}
opusPacket := codecs.OpusPacket{}
@@ -230,7 +235,7 @@ func (i *OggWriter) Close() error {
// so we can set values for EOS
func (i *OggWriter) writeToStream(p []byte) error {
if i.stream == nil {
return fmt.Errorf("file not opened")
return errFileNotOpened
}
_, err := i.stream.Write(p)

View File

@@ -2,7 +2,6 @@ package oggwriter
import (
"bytes"
"fmt"
"io"
"testing"
@@ -54,7 +53,7 @@ func TestOggWriter_AddPacketAndClose(t *testing.T) {
message: "OggWriter shouldn't be able to write something to a closed file",
messageClose: "OggWriter should be able to close an already closed file",
packet: validPacket,
err: fmt.Errorf("file not opened"),
err: errFileNotOpened,
closeErr: nil,
},
{
@@ -62,7 +61,7 @@ func TestOggWriter_AddPacketAndClose(t *testing.T) {
message: "OggWriter shouldn't be able to write an empty packet",
messageClose: "OggWriter should be able to close the file",
packet: &rtp.Packet{},
err: fmt.Errorf("invalid nil packet"),
err: errInvalidNilPacket,
closeErr: nil,
},
{
@@ -78,7 +77,7 @@ func TestOggWriter_AddPacketAndClose(t *testing.T) {
message: "OggWriter shouldn't be able to write something to a closed file",
messageClose: "OggWriter should be able to close an already closed file",
packet: nil,
err: fmt.Errorf("file not opened"),
err: errFileNotOpened,
closeErr: nil,
},
}

View File

@@ -2,6 +2,7 @@ package rtpdump
import (
"bufio"
"errors"
"io"
"regexp"
"sync"
@@ -30,7 +31,7 @@ func NewReader(r io.Reader) (*Reader, Header, error) {
}
// The file starts with #!rtpplay1.0 address/port\n
var preambleRegexp = regexp.MustCompile(`#\!rtpplay1\.0 \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,5}\n`)
preambleRegexp := regexp.MustCompile(`#\!rtpplay1\.0 \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,5}\n`)
if !preambleRegexp.Match(peek) {
return nil, hdr, errMalformed
}
@@ -46,7 +47,7 @@ func NewReader(r io.Reader) (*Reader, Header, error) {
hBuf := make([]byte, headerLen)
_, err = io.ReadFull(bio, hBuf)
if err == io.ErrUnexpectedEOF || err == io.EOF {
if errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, io.EOF) {
return nil, hdr, errMalformed
}
if err != nil {
@@ -70,7 +71,7 @@ func (r *Reader) Next() (Packet, error) {
hBuf := make([]byte, pktHeaderLen)
_, err := io.ReadFull(r.reader, hBuf)
if err == io.ErrUnexpectedEOF {
if errors.Is(err, io.ErrUnexpectedEOF) {
return Packet{}, errMalformed
}
if err != nil {
@@ -88,7 +89,7 @@ func (r *Reader) Next() (Packet, error) {
payload := make([]byte, h.Length-pktHeaderLen)
_, err = io.ReadFull(r.reader, payload)
if err == io.ErrUnexpectedEOF {
if errors.Is(err, io.ErrUnexpectedEOF) {
return Packet{}, errMalformed
}
if err != nil {

View File

@@ -2,6 +2,7 @@ package rtpdump
import (
"bytes"
"errors"
"io"
"net"
"reflect"
@@ -247,7 +248,7 @@ func TestReader(t *testing.T) {
} {
r, hdr, err := NewReader(bytes.NewReader(test.Data))
if err != nil {
if got, want := err, test.WantErr; got != want {
if got, want := err, test.WantErr; !errors.Is(got, want) {
t.Fatalf("NewReader(%s) err=%v want %v", test.Name, got, want)
}
continue
@@ -272,7 +273,7 @@ func TestReader(t *testing.T) {
packets = append(packets, pkt)
}
if got, want := nextErr, test.WantErr; got != want {
if got, want := nextErr, test.WantErr; !errors.Is(got, want) {
t.Fatalf("%s err=%v want %v", test.Name, got, want)
}
if got, want := packets, test.WantPackets; !reflect.DeepEqual(got, want) {

View File

@@ -1,6 +1,7 @@
package rtpdump
import (
"errors"
"net"
"reflect"
"testing"
@@ -65,7 +66,7 @@ func TestMarshalHeader(t *testing.T) {
},
} {
data, err := test.Header.Marshal()
if got, want := err, test.WantErr; got != want {
if got, want := err, test.WantErr; !errors.Is(got, want) {
t.Fatalf("Marshal(%q) err=%v, want %v", test.Name, got, want)
}

View File

@@ -8,7 +8,6 @@ import (
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"errors"
"strings"
"sync"
"time"
@@ -155,13 +154,13 @@ func (t *QUICTransport) validateFingerPrint(remoteParameters QUICParameters, rem
}
}
return errors.New("no matching fingerprint")
return errQuickTransportFingerprintNoMatch
}
func (t *QUICTransport) ensureICEConn() error {
if t.iceTransport == nil ||
t.iceTransport.State() == ICETransportStateNew {
return errors.New("ICE connection not started")
return errQuickTransportICEConnectionNotStarted
}
return nil

View File

@@ -1,19 +1,19 @@
package webrtc
const (
//TypeRTCPFBTransportCC ..
// TypeRTCPFBTransportCC ..
TypeRTCPFBTransportCC = "transport-cc"
//TypeRTCPFBGoogREMB ..
// TypeRTCPFBGoogREMB ..
TypeRTCPFBGoogREMB = "goog-remb"
//TypeRTCPFBACK ..
// TypeRTCPFBACK ..
TypeRTCPFBACK = "ack"
//TypeRTCPFBCCM ..
// TypeRTCPFBCCM ..
TypeRTCPFBCCM = "ccm"
//TypeRTCPFBNACK ..
// TypeRTCPFBNACK ..
TypeRTCPFBNACK = "nack"
)

View File

@@ -36,7 +36,7 @@ type RTPReceiver struct {
// NewRTPReceiver constructs a new RTPReceiver
func (api *API) NewRTPReceiver(kind RTPCodecType, transport *DTLSTransport) (*RTPReceiver, error) {
if transport == nil {
return nil, fmt.Errorf("DTLSTransport must not be nil")
return nil, errRTPReceiverDTLSTransportNil
}
return &RTPReceiver{
@@ -87,7 +87,7 @@ func (r *RTPReceiver) Receive(parameters RTPReceiveParameters) error {
defer r.mu.Unlock()
select {
case <-r.received:
return fmt.Errorf("Receive has already been called")
return errRTPReceiverReceiveAlreadyCalled
default:
}
defer close(r.received)
@@ -197,7 +197,7 @@ func (r *RTPReceiver) readRTP(b []byte, reader *Track) (n int, err error) {
return t.rtpReadStream.Read(b)
}
return 0, fmt.Errorf("unable to find stream for Track with SSRC(%d)", reader.SSRC())
return 0, fmt.Errorf("%w: %d", errRTPReceiverWithSSRCTrackStreamNotFound, reader.SSRC())
}
// receiveForRid is the sibling of Receive expect for RIDs instead of SSRCs
@@ -224,7 +224,7 @@ func (r *RTPReceiver) receiveForRid(rid string, codec *RTPCodec, ssrc uint32) (*
}
}
return nil, fmt.Errorf("no trackStreams found for SSRC(%d)", ssrc)
return nil, fmt.Errorf("%w: %d", errRTPReceiverForSSRCTrackStreamNotFound, ssrc)
}
func (r *RTPReceiver) streamsForSSRC(ssrc uint32) (*srtp.ReadStreamSRTP, *srtp.ReadStreamSRTCP, error) {

View File

@@ -3,7 +3,6 @@
package webrtc
import (
"fmt"
"io"
"sync"
@@ -19,6 +18,7 @@ type RTPSender struct {
transport *DTLSTransport
// nolint:godox
// TODO(sgotti) remove this when in future we'll avoid replacing
// a transceiver sender since we can just check the
// transceiver negotiation status
@@ -34,15 +34,15 @@ type RTPSender struct {
// NewRTPSender constructs a new RTPSender
func (api *API) NewRTPSender(track *Track, transport *DTLSTransport) (*RTPSender, error) {
if track == nil {
return nil, fmt.Errorf("Track must not be nil")
return nil, errRTPSenderTrackNil
} else if transport == nil {
return nil, fmt.Errorf("DTLSTransport must not be nil")
return nil, errRTPSenderDTLSTransportNil
}
track.mu.Lock()
defer track.mu.Unlock()
if track.receiver != nil {
return nil, fmt.Errorf("RTPSender can not be constructed with remote track")
return nil, errRTPSenderCannotConstructRemoteTrack
}
track.totalSenderCount++
@@ -94,7 +94,7 @@ func (r *RTPSender) Send(parameters RTPSendParameters) error {
defer r.mu.Unlock()
if r.hasSent() {
return fmt.Errorf("Send has already been called")
return errRTPSenderSendAlreadyCalled
}
srtcpSession, err := r.transport.getSRTCPSession()
@@ -176,7 +176,7 @@ func (r *RTPSender) ReadRTCP() ([]rtcp.Packet, error) {
func (r *RTPSender) SendRTP(header *rtp.Header, payload []byte) (int, error) {
select {
case <-r.stopCalled:
return 0, fmt.Errorf("RTPSender has been stopped")
return 0, errRTPSenderStopped
case <-r.sendCalled:
srtpSession, err := r.transport.getSRTPSession()
if err != nil {

View File

@@ -46,7 +46,7 @@ func (t *RTPTransceiver) Receiver() *RTPReceiver {
// setMid sets the RTPTransceiver's mid. If it was already set, will return an error.
func (t *RTPTransceiver) setMid(mid string) error {
if currentMid := t.Mid(); currentMid != "" {
return fmt.Errorf("cannot change transceiver mid from: %s to %s", currentMid, mid)
return fmt.Errorf("%w: %s to %s", errRTPTransceiverCannotChangeMid, currentMid, mid)
}
t.mid.Store(mid)
return nil
@@ -111,7 +111,7 @@ func (t *RTPTransceiver) setSendingTrack(track *Track) error {
case track == nil && t.Direction() == RTPTransceiverDirectionSendonly:
t.setDirection(RTPTransceiverDirectionInactive)
default:
return fmt.Errorf("invalid state change in RTPTransceiver.setSending")
return errRTPTransceiverSetSendingInvalidState
}
return nil
}
@@ -138,9 +138,10 @@ func satisfyTypeAndDirection(remoteKind RTPCodecType, remoteDirection RTPTransce
return []RTPTransceiverDirection{RTPTransceiverDirectionRecvonly, RTPTransceiverDirectionSendrecv}
case RTPTransceiverDirectionRecvonly:
return []RTPTransceiverDirection{RTPTransceiverDirectionSendonly, RTPTransceiverDirectionSendrecv}
}
default:
return []RTPTransceiverDirection{}
}
}
for _, possibleDirection := range getPreferredDirections() {
for i := range localTransceivers {

View File

@@ -68,6 +68,7 @@ func (t RTPTransceiverDirection) Revers() RTPTransceiverDirection {
return RTPTransceiverDirectionRecvonly
case RTPTransceiverDirectionRecvonly:
return RTPTransceiverDirectionSendonly
}
default:
return t
}
}

View File

@@ -1,8 +1,10 @@
package webrtc
// RtpTransceiverInit dictionary is used when calling the WebRTC function addTransceiver() to provide configuration options for the new transceiver.
type RtpTransceiverInit struct {
// RTPTransceiverInit dictionary is used when calling the WebRTC function addTransceiver() to provide configuration options for the new transceiver.
type RTPTransceiverInit struct {
Direction RTPTransceiverDirection
SendEncodings []RTPEncodingParameters
// Streams []*Track
}
type RtpTransceiverInit = RTPTransceiverInit //nolint: stylecheck

View File

@@ -3,7 +3,6 @@
package webrtc
import (
"errors"
"io"
"math"
"sync"
@@ -141,7 +140,7 @@ func (r *SCTPTransport) Stop() error {
func (r *SCTPTransport) ensureDTLS() error {
dtlsTransport := r.Transport()
if dtlsTransport == nil || dtlsTransport.conn == nil {
return errors.New("DTLS not established")
return errSCTPTransportDTLS
}
return nil
@@ -160,10 +159,12 @@ func (r *SCTPTransport) acceptDataChannels(a *sctp.Association) {
return
}
var ordered = true
var maxRetransmits *uint16
var maxPacketLifeTime *uint16
var val = uint16(dc.Config.ReliabilityParameter)
var (
maxRetransmits *uint16
maxPacketLifeTime *uint16
)
val := uint16(dc.Config.ReliabilityParameter)
ordered := true
switch dc.Config.ChannelType {
case datachannel.ChannelTypeReliable:
@@ -195,7 +196,6 @@ func (r *SCTPTransport) acceptDataChannels(a *sctp.Association) {
MaxPacketLifeTime: maxPacketLifeTime,
MaxRetransmits: maxRetransmits,
}, r.api.settingEngine.LoggerFactory.NewLogger("ortc"))
if err != nil {
r.log.Errorf("Failed to accept data channel: %v", err)
r.onError(err)

12
sdp.go
View File

@@ -54,7 +54,7 @@ const (
)
// extract all trackDetails from an SDP.
func trackDetailsFromSDP(log logging.LeveledLogger, s *sdp.SessionDescription) []trackDetails {
func trackDetailsFromSDP(log logging.LeveledLogger, s *sdp.SessionDescription) []trackDetails { // nolint:gocognit
incomingTracks := []trackDetails{}
rtxRepairFlows := map[uint32]bool{}
@@ -285,7 +285,7 @@ func populateLocalCandidates(sessionDescription *SessionDescription, i *ICEGathe
func addTransceiverSDP(d *sdp.SessionDescription, isPlanB bool, dtlsFingerprints []DTLSFingerprint, mediaEngine *MediaEngine, midValue string, iceParams ICEParameters, candidates []ICECandidate, dtlsRole sdp.ConnectionRole, iceGatheringState ICEGatheringState, extMaps map[SDPSectionType][]sdp.ExtMap, mediaSection mediaSection) (bool, error) {
transceivers := mediaSection.transceivers
if len(transceivers) < 1 {
return false, fmt.Errorf("addTransceiverSDP() called with 0 transceivers")
return false, errSDPZeroTransceivers
}
// Use the first transceiver to generate the section attributes
t := transceivers[0]
@@ -385,9 +385,9 @@ func populateSDP(d *sdp.SessionDescription, isPlanB bool, dtlsFingerprints []DTL
for _, m := range mediaSections {
if m.data && len(m.transceivers) != 0 {
return nil, fmt.Errorf("invalid Media Section. Media + DataChannel both enabled")
return nil, errSDPMediaSectionMediaDataChanInvalid
} else if !isPlanB && len(m.transceivers) > 1 {
return nil, fmt.Errorf("invalid Media Section. Can not have multiple tracks in one MediaSection in UnifiedPlan")
return nil, errSDPMediaSectionMultipleTrackInvalid
}
shouldAddID := true
@@ -593,11 +593,11 @@ func remoteExts(session *sdp.SessionDescription) (map[SDPSectionType]map[int]sdp
}
em := &sdp.ExtMap{}
if err := em.Unmarshal("extmap:" + attr.Value); err != nil {
return fmt.Errorf("failed to parse ExtMap: %v", err)
return fmt.Errorf("%w: %v", errSDPParseExtMap, err)
}
if remoteExtMap, ok := remoteExtMaps[mediaType][em.Value]; ok {
if remoteExtMap.Value != em.Value {
return fmt.Errorf("RemoteDescription changed some extmaps values")
return errSDPRemoteDescriptionChangedExtMap
}
} else {
remoteExtMaps[mediaType][em.Value] = *em

View File

@@ -9,7 +9,6 @@ import (
"github.com/pion/sdp/v3"
"github.com/pion/transport/test"
"github.com/stretchr/testify/assert"
)

View File

@@ -3,7 +3,6 @@
package webrtc
import (
"errors"
"time"
"github.com/pion/ice/v2"
@@ -166,7 +165,7 @@ func (e *SettingEngine) SetNAT1To1IPs(ips []string, candidateType ICECandidateTy
// Act as DTLS Server, wait for ClientHello
func (e *SettingEngine) SetAnsweringDTLSRole(role DTLSRole) error {
if role != DTLSRoleClient && role != DTLSRoleServer {
return errors.New("SetAnsweringDTLSRole must DTLSRoleClient or DTLSRoleServer")
return errSettingEngineSetAnsweringDTLSRole
}
e.answeringDTLSRole = role

View File

@@ -114,16 +114,16 @@ func (t *SignalingState) Set(state SignalingState) {
atomic.StoreInt32((*int32)(t), int32(state))
}
func checkNextSignalingState(cur, next SignalingState, op stateChangeOp, sdpType SDPType) (SignalingState, error) {
func checkNextSignalingState(cur, next SignalingState, op stateChangeOp, sdpType SDPType) (SignalingState, error) { // nolint:gocognit
// Special case for rollbacks
if sdpType == SDPTypeRollback && cur == SignalingStateStable {
return cur, &rtcerr.InvalidModificationError{
Err: fmt.Errorf("can't rollback from stable state"),
Err: errSignalingStateCannotRollback,
}
}
// 4.3.1 valid state transitions
switch cur {
switch cur { // nolint:exhaustive
case SignalingStateStable:
switch op {
case stateChangeOpSetLocal:
@@ -139,7 +139,7 @@ func checkNextSignalingState(cur, next SignalingState, op stateChangeOp, sdpType
}
case SignalingStateHaveLocalOffer:
if op == stateChangeOpSetRemote {
switch sdpType {
switch sdpType { // nolint:exhaustive
// have-local-offer->SetRemote(answer)->stable
case SDPTypeAnswer:
if next == SignalingStateStable {
@@ -161,7 +161,7 @@ func checkNextSignalingState(cur, next SignalingState, op stateChangeOp, sdpType
}
case SignalingStateHaveRemoteOffer:
if op == stateChangeOpSetLocal {
switch sdpType {
switch sdpType { // nolint:exhaustive
// have-remote-offer->SetLocal(answer)->stable
case SDPTypeAnswer:
if next == SignalingStateStable {
@@ -182,8 +182,7 @@ func checkNextSignalingState(cur, next SignalingState, op stateChangeOp, sdpType
}
}
}
return cur, &rtcerr.InvalidModificationError{
Err: fmt.Errorf("invalid proposed signaling state transition %s->%s(%s)->%s", cur, op, sdpType, next),
Err: fmt.Errorf("%w: %s->%s(%s)->%s", errSignalingStateProposedTransitionInvalid, cur, op, sdpType, next),
}
}

View File

@@ -4,7 +4,6 @@ import (
"testing"
"github.com/pion/webrtc/v3/pkg/rtcerr"
"github.com/stretchr/testify/assert"
)

View File

@@ -1192,9 +1192,7 @@ func toStatsICECandidatePairState(state ice.CandidatePairState) (StatsICECandida
return StatsICECandidatePairStateSucceeded, nil
default:
// NOTE: this should never happen[tm]
err := fmt.Errorf(
"cannot convert to StatsICECandidatePairStateSucceeded invalid ice candidate state: %s",
state.String())
err := fmt.Errorf("%w: %s", errStatsICECandidateStateInvalid, state.String())
return StatsICECandidatePairState("Unknown"), err
}
}

View File

@@ -75,7 +75,6 @@ func (r StatsReport) GetCertificateStats(c *Certificate) (CertificateStats, bool
return CertificateStats{}, false
}
return certificateStats, true
}
// GetCodecStats is a helper method to return the associated stats for a given Codec

View File

@@ -5,15 +5,17 @@ package webrtc
import (
"encoding/json"
"fmt"
"github.com/stretchr/testify/require"
"math/rand"
"sync"
"testing"
"time"
"github.com/pion/randutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
var errReceiveOfferTimeout = fmt.Errorf("timed out waiting to receive offer")
func TestStatsTimestampTime(t *testing.T) {
for _, test := range []struct {
Timestamp StatsTimestamp
@@ -38,7 +40,6 @@ func TestStatsTimestampTime(t *testing.T) {
}
}
// TODO(maxhawkins): replace with a more meaningful test
func TestStatsMarshal(t *testing.T) {
for _, test := range []Stats{
AudioReceiverStats{},
@@ -176,7 +177,7 @@ func signalPairForStats(pcOffer *PeerConnection, pcAnswer *PeerConnection) error
timeout := time.After(3 * time.Second)
select {
case <-timeout:
return fmt.Errorf("timed out waiting to receive offer")
return errReceiveOfferTimeout
case offer := <-offerChan:
if err := pcAnswer.SetRemoteDescription(offer); err != nil {
return err
@@ -203,7 +204,7 @@ func TestPeerConnection_GetStats(t *testing.T) {
offerPC, answerPC, err := newPair()
assert.NoError(t, err)
track1, err := offerPC.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion1")
track1, err := offerPC.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion1")
require.NoError(t, err)
_, err = offerPC.AddTrack(track1)
@@ -324,9 +325,8 @@ func TestPeerConnection_GetStats(t *testing.T) {
certificates := offerPC.configuration.Certificates
for _, certificate := range certificates {
certificateStats := getCertificateStats(t, reportPCOffer, &certificate)
assert.NotEmpty(t, certificateStats)
for i := range certificates {
assert.NotEmpty(t, getCertificateStats(t, reportPCOffer, &certificates[i]))
}
assert.NoError(t, offerPC.Close())

View File

@@ -3,7 +3,6 @@
package webrtc
import (
"fmt"
"io"
"sync"
@@ -108,7 +107,7 @@ func (t *Track) Read(b []byte) (n int, err error) {
if t.totalSenderCount != 0 || r == nil {
t.mu.RUnlock()
return 0, fmt.Errorf("this is a local track and must not be read from")
return 0, errTrackLocalTrackRead
}
t.mu.RUnlock()
@@ -164,7 +163,7 @@ func (t *Track) WriteRTP(p *rtp.Packet) error {
t.mu.RLock()
if t.receiver != nil {
t.mu.RUnlock()
return fmt.Errorf("this is a remote track and must not be written to")
return errTrackLocalTrackWrite
}
senders := t.activeSenders
totalSenderCount := t.totalSenderCount
@@ -187,7 +186,7 @@ func (t *Track) WriteRTP(p *rtp.Packet) error {
// NewTrack initializes a new *Track
func NewTrack(payloadType uint8, ssrc uint32, id, label string, codec *RTPCodec) (*Track, error) {
if ssrc == 0 {
return nil, fmt.Errorf("SSRC supplied to NewTrack() must be non-zero")
return nil, errTrackSSRCNewTrackZero
}
packetizer := rtp.NewPacketizer(

View File

@@ -3,9 +3,9 @@
package webrtc
import (
"math/rand"
"testing"
"github.com/pion/randutil"
"github.com/stretchr/testify/assert"
)
@@ -23,7 +23,7 @@ func TestNewVideoTrack(t *testing.T) {
peer, _ := api.NewPeerConnection(peerConfig)
_, err := peer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion")
_, err := peer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion")
if err != nil {
t.Error("Failed to new video track")
}
@@ -43,7 +43,7 @@ func TestNewAudioTrack(t *testing.T) {
peer, _ := api.NewPeerConnection(peerConfig)
_, err := peer.NewTrack(DefaultPayloadTypeOpus, rand.Uint32(), "audio", "pion")
_, err := peer.NewTrack(DefaultPayloadTypeOpus, randutil.NewMathRandomGenerator().Uint32(), "audio", "pion")
if err != nil {
t.Error("Failed to new audio track")
}
@@ -64,12 +64,12 @@ func TestNewTracks(t *testing.T) {
peer, _ := api.NewPeerConnection(peerConfig)
_, err := peer.NewTrack(DefaultPayloadTypeOpus, rand.Uint32(), "audio", "pion")
_, err := peer.NewTrack(DefaultPayloadTypeOpus, randutil.NewMathRandomGenerator().Uint32(), "audio", "pion")
if err != nil {
t.Error("Failed to new audio track")
}
_, err = peer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion")
_, err = peer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion")
if err != nil {
t.Error("Failed to new video track")
}
@@ -90,12 +90,12 @@ func TestNewTracksWrite(t *testing.T) {
peer, _ := api.NewPeerConnection(peerConfig)
videoTrack, err := peer.NewTrack(DefaultPayloadTypeOpus, rand.Uint32(), "audio", "pion")
videoTrack, err := peer.NewTrack(DefaultPayloadTypeOpus, randutil.NewMathRandomGenerator().Uint32(), "audio", "pion")
if err != nil {
t.Error("Failed to new video track")
}
audioTrack, err := peer.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion")
audioTrack, err := peer.NewTrack(DefaultPayloadTypeVP8, randutil.NewMathRandomGenerator().Uint32(), "video", "pion")
if err != nil {
t.Error("Failed to new audio track")
}
@@ -122,7 +122,7 @@ func TestTrackReadWhenNotAdded(t *testing.T) {
peerConnection, err := NewPeerConnection(Configuration{})
assert.NoError(t, err)
track, err := peerConnection.NewTrack(DefaultPayloadTypeOpus, rand.Uint32(), "audio", "pion")
track, err := peerConnection.NewTrack(DefaultPayloadTypeOpus, randutil.NewMathRandomGenerator().Uint32(), "audio", "pion")
assert.NoError(t, err)
_, err = track.Read([]byte{})