Pion WebRTC - go语言实现的webrtc框架库


MIT
跨平台
Google Go

软件简介

纯go语言实现的webrtc框架库。可以用于开发webrtc服务器和webrtc客户端。API接口与JavaScript类似,减少学习成本。

示例代码:

package main

import (
    "fmt"
    "math/rand"
    "time"

    "github.com/pion/rtcp"
    "github.com/pion/webrtc/v2"

    "github.com/pion/webrtc/v2/examples/internal/signal"
)

func main() {
    // Everything below is the Pion WebRTC API! Thanks for using it ❤️.

    // Prepare the configuration
    config := webrtc.Configuration{
        ICEServers: []webrtc.ICEServer{
            {
                URLs: []string{"stun:stun.l.google.com:19302"},
            },
        },
    }

    // Create a new RTCPeerConnection
    peerConnection, err := webrtc.NewPeerConnection(config)
    if err != nil {
        panic(err)
    }

    // Create Track that we send video back to browser on
    outputTrack, err := peerConnection.NewTrack(webrtc.DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion")
    if err != nil {
        panic(err)
    }

    // Add this newly created track to the PeerConnection
    if _, err = peerConnection.AddTrack(outputTrack); err != nil {
        panic(err)
    }

    // Set a handler for when a new remote track starts, this handler copies inbound RTP packets,
    // replaces the SSRC and sends them back
    peerConnection.OnTrack(func(track *webrtc.Track, receiver *webrtc.RTPReceiver) {
        // Send a PLI on an interval so that the publisher is pushing a keyframe every rtcpPLIInterval
        // This is a temporary fix until we implement incoming RTCP events, then we would push a PLI only when a viewer requests it
        go func() {
            ticker := time.NewTicker(time.Second * 3)
            for range ticker.C {
                errSend := peerConnection.WriteRTCP([]rtcp.Packet{&rtcp.PictureLossIndication{MediaSSRC: track.SSRC()}})
                if errSend != nil {
                    fmt.Println(errSend)
                }
            }
        }()

        fmt.Printf("Track has started, of type %d: %s \n", track.PayloadType(), track.Codec().Name)
        for {
            // Read RTP packets being sent to Pion
            rtp, readErr := track.ReadRTP()
            if readErr != nil {
                panic(readErr)
            }

            // Replace the SSRC with the SSRC of the outbound track.
            // The only change we are making replacing the SSRC, the RTP packets are unchanged otherwise
            rtp.SSRC = outputTrack.SSRC()
            rtp.PayloadType = webrtc.DefaultPayloadTypeVP8

            if writeErr := outputTrack.WriteRTP(rtp); writeErr != nil {
                panic(writeErr)
            }
        }
    })
    // Set the handler for ICE connection state
    // This will notify you when the peer has connected/disconnected
    peerConnection.OnICEConnectionStateChange(func(connectionState webrtc.ICEConnectionState) {
        fmt.Printf("Connection State has changed %s \n", connectionState.String())
    })

    // Wait for the offer to be pasted
    offer := webrtc.SessionDescription{}
    signal.Decode(signal.MustReadStdin(), &offer)

    // Set the remote SessionDescription
    err = peerConnection.SetRemoteDescription(offer)
    if err != nil {
        panic(err)
    }

    // Create an answer
    answer, err := peerConnection.CreateAnswer(nil)
    if err != nil {
        panic(err)
    }

    // Sets the LocalDescription, and starts our UDP listeners
    err = peerConnection.SetLocalDescription(answer)
    if err != nil {
        panic(err)
    }

    // Output the answer in base64 so we can paste it in browser
    fmt.Println(signal.Encode(answer))

    // Block forever
    select {}
}