Pion WebRTC: Pure Go WebRTC Library Guide - Features and Examples

Libraries & Frameworks 4 minutes |
Pion WebRTC: Pure Go WebRTC Library Guide - Features and Examples

If you’ve ever tried to do WebRTC in Go, you know the pain - either deal with Cgo bindings to libwebrtc (slow builds, deployment hell) or stick to browser-only solutions. Pion WebRTC solves this by being a pure Go implementation that compiles fast and deploys easily.

Why Pion WebRTC is a Game Changer

Before Pion came along, Go developers had limited options for WebRTC. Now things are completely different:

  • Build speed: Example programs compile in 0.3 seconds, full test suite in just over a minute
  • Simple deployment: Single binary, no shared library headaches
  • Cross-platform: Works on Windows, Mac, Linux, even WASM
  • Readable code: Pure Go implementation, want to modify something? Just read the source

Real-World Development Experience

How does it compare to other options?

When we were doing WebRTC projects before, we basically had these choices:

Using libwebrtc + Cgo

  • Pros: Feature complete, Google maintains it
  • Cons: Takes forever to compile, cross-compilation is a nightmare, deployment means carrying around .so files

Browser APIs directly

  • Pros: Works out of the box, good compatibility
  • Cons: Frontend only, forget about server-side

Now with Pion WebRTC

  • Compile: Done in seconds
  • Deploy: Drop a binary and you’re good
  • Debug: It’s Go code, modify whatever you want
  • Performance: All the optimizations you need, hardware acceleration included

Core Features

PeerConnection API

  • Complete WebRTC-PC Implementation: Compliant with W3C standards
  • Data Channels: Support for ordered/unordered, reliable/unreliable transmission
  • Audio/Video Send/Receive: Support for multiple codecs
  • Renegotiation: Dynamic track addition/removal
  • Plan-B and Unified Plan: Support for both SDP formats
  • SettingEngine: Pion-specific extension configurations

Connectivity Features

  • Full ICE Agent: Support for ICE restart and Trickle ICE
  • STUN/TURN Support: UDP, TCP, DTLS, and TLS transport
  • mDNS Candidates: Local network discovery
  • Single Port Multiple Connections: Serve multiple connections from a single port

Media Processing

  • Direct RTP/RTCP Access: Low-level media control
  • Multi-codec Support: Opus, PCM, H264, VP8, VP9
  • Custom Packetizers: Allow developers to implement custom codecs
  • Multiple Container Formats: IVF, Ogg, H264, Matroska
  • Advanced Features:
    • Simulcast
    • SVC (Scalable Video Coding)
    • NACK (Negative Acknowledgment)
    • Sender/Receiver Reports
    • Bandwidth Estimation

Security

  • DTLS v1.2: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
  • SRTP Encryption: SRTP_AEAD_AES_256_GCM and SRTP_AES128_CM_HMAC_SHA1_80
  • Hardware Acceleration: GCM suite hardware acceleration support

Installation and Basic Usage

Installation Requirements

Pion WebRTC requires Go Modules, ensure you set:

export GO111MODULE=on

Installing Pion WebRTC

go mod init your-project
go get github.com/pion/webrtc/v4

Basic Usage Examples

1. Creating PeerConnection

package main

import (
    "fmt"
    "github.com/pion/webrtc/v4"
)

func main() {
    // Create PeerConnection configuration
    config := webrtc.Configuration{
        ICEServers: []webrtc.ICEServer{
            {
                URLs: []string{"stun:stun.l.google.com:19302"},
            },
        },
    }

    // Create new PeerConnection
    peerConnection, err := webrtc.NewPeerConnection(config)
    if err != nil {
        panic(err)
    }
    defer func() {
        if cErr := peerConnection.Close(); cErr != nil {
            fmt.Printf("Cannot close PeerConnection: %v\n", cErr)
        }
    }()

    // Set connection state handler
    peerConnection.OnConnectionStateChange(func(s webrtc.PeerConnectionState) {
        fmt.Printf("Connection state changed: %s\n", s.String())
    })

    fmt.Println("PeerConnection created successfully")
}

2. Data Channel Communication

func setupDataChannel(peerConnection *webrtc.PeerConnection) {
    // Create data channel
    dataChannel, err := peerConnection.CreateDataChannel("test", nil)
    if err != nil {
        panic(err)
    }

    // Set data channel event handlers
    dataChannel.OnOpen(func() {
        fmt.Println("Data channel opened")
        
        // Send message
        message := "Hello from Pion WebRTC!"
        err := dataChannel.SendText(message)
        if err != nil {
            fmt.Printf("Failed to send message: %v\n", err)
        } else {
            fmt.Printf("Sent message: %s\n", message)
        }
    })

    dataChannel.OnMessage(func(msg webrtc.DataChannelMessage) {
        fmt.Printf("Received message: %s\n", string(msg.Data))
    })

    dataChannel.OnClose(func() {
        fmt.Println("Data channel closed")
    })
}

3. Audio/Video Processing

import (
    "github.com/pion/webrtc/v4"
    "github.com/pion/webrtc/v4/pkg/media"
    "github.com/pion/webrtc/v4/pkg/media/ivfwriter"
)

func setupVideoTrack(peerConnection *webrtc.PeerConnection) {
    // Create video track
    videoTrack, err := webrtc.NewTrackLocalStaticSample(
        webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeVP8},
        "video",
        "pion",
    )
    if err != nil {
        panic(err)
    }

    // Add track to PeerConnection
    rtpSender, err := peerConnection.AddTrack(videoTrack)
    if err != nil {
        panic(err)
    }

    // Handle RTCP packets
    go func() {
        rtcpBuf := make([]byte, 1500)
        for {
            if _, _, rtcpErr := rtpSender.Read(rtcpBuf); rtcpErr != nil {
                return
            }
        }
    }()

    // Send video frames example
    go func() {
        // Add logic to read video frames from file or camera
        // Then use videoTrack.WriteSample() to send
    }()
}

Official Examples Explained

Pion WebRTC provides rich example code covering various use cases:

Media API Examples

1. Reflect Example

cd examples/reflect
go run main.go
  • Function: Sends back exactly what it receives to the sender
  • Use: Testing WebRTC connections and media transmission
  • Scenario: Echo testing, connection validation

2. Play from Disk Example

cd examples/play-from-disk
go run main.go
  • Function: Send video from disk file to browser
  • Supported Formats: IVF, H.264, Matroska
  • Application: Video on demand, media servers

3. Save to Disk Example

cd examples/save-to-disk
go run main.go
  • Function: Record browser webcam and save to server
  • Output Format: IVF video files
  • Application: Video recording, surveillance systems

4. Broadcast Example

cd examples/broadcast
go run main.go
  • Function: One-to-many video broadcasting
  • Feature: Single upload source, multiple receivers
  • Application: Live streaming, conference systems

5. Simulcast Example

cd examples/simulcast
go run main.go
  • Function: Receive and demux multiple quality video streams
  • Feature: Adaptive bitrate, quality switching
  • Application: Video conferencing, streaming platforms

Data Channel API Examples

1. Data Channels Example

cd examples/data-channels
go run main.go
  • Function: Data channel communication with browser
  • Feature: Bidirectional message transmission
  • Application: Real-time chat, game data

2. Data Channels Detach Example

cd examples/data-channels-detach
go run main.go
  • Function: Direct use of underlying data channel implementation
  • Advantage: More idiomatic Go API
  • Application: High-performance data transmission

3. Pion to Pion Example

cd examples/pion-to-pion
go run main.go
  • Function: Direct communication between two Pion instances
  • Feature: No browser involvement required
  • Application: Server-to-server communication, IoT

Advanced Feature Examples

ICE Restart:

cd examples/ice-restart
go run main.go
  • Demonstrates network roaming and ICE restart

ICE Single Port:

cd examples/ice-single-port
go run main.go
  • Serve multiple connections from a single port

ICE TCP:

cd examples/ice-tcp
go run main.go
  • Use TCP instead of UDP for WebRTC connections

2. RTP Processing Examples

RTP Forwarder:

cd examples/rtp-forwarder
go run main.go
  • Forward audio/video streams using RTP

RTP to WebRTC:

cd examples/rtp-to-webrtc
go run main.go
  • Convert RTP packets to WebRTC streams

Complete Application Example

package main

import (
    "bufio"
    "encoding/base64"
    "encoding/json"
    "fmt"
    "os"
    "strings"

    "github.com/pion/webrtc/v4"
)

func main() {
    // Create PeerConnection
    peerConnection, err := webrtc.NewPeerConnection(webrtc.Configuration{
        ICEServers: []webrtc.ICEServer{
            {
                URLs: []string{"stun:stun.l.google.com:19302"},
            },
        },
    })
    if err != nil {
        panic(err)
    }
    defer peerConnection.Close()

    // Create data channel
    dataChannel, err := peerConnection.CreateDataChannel("test", nil)
    if err != nil {
        panic(err)
    }

    // Set data channel handlers
    dataChannel.OnOpen(func() {
        fmt.Println("Data channel opened, ready to send messages")
    })

    dataChannel.OnMessage(func(msg webrtc.DataChannelMessage) {
        fmt.Printf("Received message: %s\n", string(msg.Data))
    })

    // Set ICE connection state handler
    peerConnection.OnICEConnectionStateChange(func(connectionState webrtc.ICEConnectionState) {
        fmt.Printf("ICE connection state: %s\n", connectionState.String())
    })

    // Create Offer
    offer, err := peerConnection.CreateOffer(nil)
    if err != nil {
        panic(err)
    }

    // Set local description
    err = peerConnection.SetLocalDescription(offer)
    if err != nil {
        panic(err)
    }

    // Output Offer (in real applications, exchange via signaling server)
    fmt.Println("Please send the following Offer to remote peer:")
    fmt.Println(encode(offer))

    // Wait for Answer (in real applications, receive from signaling server)
    fmt.Println("Please enter the remote peer's Answer:")
    answer := webrtc.SessionDescription{}
    decode(readUntilNewline(), &answer)

    // Set remote description
    err = peerConnection.SetRemoteDescription(answer)
    if err != nil {
        panic(err)
    }

    // Keep program running
    select {}
}

// Encode SessionDescription to base64
func encode(obj *webrtc.SessionDescription) string {
    b, err := json.Marshal(obj)
    if err != nil {
        panic(err)
    }
    return base64.StdEncoding.EncodeToString(b)
}

// Decode SessionDescription from base64
func decode(in string, obj *webrtc.SessionDescription) {
    b, err := base64.StdEncoding.DecodeString(in)
    if err != nil {
        panic(err)
    }
    err = json.Unmarshal(b, obj)
    if err != nil {
        panic(err)
    }
}

// Read user input
func readUntilNewline() string {
    reader := bufio.NewReader(os.Stdin)
    text, _ := reader.ReadString('\n')
    return strings.TrimSpace(text)
}

Advanced Use Cases

1. Media Server

// Implement a simple media server
type MediaServer struct {
    peerConnections []*webrtc.PeerConnection
    videoTrack      *webrtc.TrackLocalStaticSample
}

func (s *MediaServer) AddPeer(pc *webrtc.PeerConnection) {
    s.peerConnections = append(s.peerConnections, pc)
    
    // Add video track for new peer
    if s.videoTrack != nil {
        pc.AddTrack(s.videoTrack)
    }
}

func (s *MediaServer) BroadcastFrame(frame []byte) {
    if s.videoTrack != nil {
        s.videoTrack.WriteSample(media.Sample{
            Data:     frame,
            Duration: time.Second / 30, // 30 FPS
        })
    }
}

2. IoT Applications

// IoT device data transmission
func setupIoTDataChannel(pc *webrtc.PeerConnection) {
    dataChannel, _ := pc.CreateDataChannel("sensor-data", nil)
    
    dataChannel.OnOpen(func() {
        // Send sensor data periodically
        ticker := time.NewTicker(time.Second)
        go func() {
            for range ticker.C {
                sensorData := getSensorData()
                dataChannel.SendText(sensorData)
            }
        }()
    })
}

func getSensorData() string {
    // Simulate sensor data
    return fmt.Sprintf(`{"temperature": %f, "humidity": %f, "timestamp": %d}`,
        rand.Float64()*40, rand.Float64()*100, time.Now().Unix())
}

3. Game Server

// Game state synchronization
type GameServer struct {
    players map[string]*webrtc.DataChannel
}

func (g *GameServer) BroadcastGameState(state GameState) {
    stateJSON, _ := json.Marshal(state)
    
    for playerID, channel := range g.players {
        if channel.ReadyState() == webrtc.DataChannelStateOpen {
            channel.Send(stateJSON)
        }
    }
}

Performance Optimization and Best Practices

1. Connection Pool Management

type ConnectionPool struct {
    connections chan *webrtc.PeerConnection
    config      webrtc.Configuration
}

func NewConnectionPool(size int, config webrtc.Configuration) *ConnectionPool {
    pool := &ConnectionPool{
        connections: make(chan *webrtc.PeerConnection, size),
        config:      config,
    }
    
    // Pre-create connections
    for i := 0; i < size; i++ {
        pc, _ := webrtc.NewPeerConnection(config)
        pool.connections <- pc
    }
    
    return pool
}

func (p *ConnectionPool) Get() *webrtc.PeerConnection {
    return <-p.connections
}

func (p *ConnectionPool) Put(pc *webrtc.PeerConnection) {
    select {
    case p.connections <- pc:
    default:
        pc.Close() // Close connection when pool is full
    }
}

2. Memory Optimization

// Use object pools to reduce GC pressure
var bufferPool = sync.Pool{
    New: func() interface{} {
        return make([]byte, 1500) // MTU size
    },
}

func processRTPPacket() {
    buffer := bufferPool.Get().([]byte)
    defer bufferPool.Put(buffer)
    
    // Process RTP packet
}

Community and Support

Extension Projects

License

Pion WebRTC is released under the MIT License, allowing free use in both commercial and non-commercial projects.

Summary

Pion WebRTC provides Go developers with a feature-complete, high-performance WebRTC implementation. Its main advantages include:

  • Pure Go Implementation: No Cgo dependencies, simple deployment
  • Complete Feature Support: Covers all WebRTC core features
  • Excellent Performance: Fast build and runtime
  • Broad Platform Support: Strong cross-platform compatibility
  • Rich Examples: Covering various application scenarios
  • Active Community: Continuous updates and support
  • Enterprise Features: Support for large-scale deployment

Whether building media servers, IoT applications, game servers, or real-time communication systems, Pion WebRTC is the preferred WebRTC library for Go developers. We recommend starting with the official examples and combining them with the complete documentation to master its powerful capabilities.

Tags

#Pion WebRTC #Go #WebRTC #Real-time Communication #Pure Go

Copyright Notice

This article is created by WebRTC.link and licensed under CC BY-NC-SA 4.0. This site repost articles will cite the source and author. If you need to repost, please cite the source and author.

Comments

Giscus

Comments powered by Giscus, based on GitHub Discussions

Related Articles

Explore more related content to deepen your understanding of WebRTC technology