snapshot of https://github.com/pion/webrtc.git (main, 2026-09-15; blobs > 131072B omitted)
Some checks failed
REUSE Compliance Check / lint (push) Failing after 0s
Browser E2E / Test (push) Failing after 3s
Test / test (1.24) (push) Failing after 0s
Test / test-i386 (1.25) (push) Failing after 0s
Test / test-i386 (1.24) (push) Failing after 0s
Test / test-windows (1.25) (push) Failing after 0s
Test / test-windows (1.24) (push) Failing after 0s
Test / test (1.25) (push) Failing after 0s
Examples Tests / Test (push) Failing after 3s
Test / test-macos (1.25) (push) Failing after 0s
Test / test-macos (1.24) (push) Failing after 0s
Go mod tidy / tidy (push) Failing after 0s
Test / test-wasm (push) Failing after 0s
CodeQL / analyze (push) Failing after 1s
Fuzz / fuzz (push) Failing after 0s

This commit is contained in:
upstream-mirror
2026-09-15 20:06:07 +05:00
commit 8acb1a3a29
394 changed files with 78746 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
# rtcp-processing
rtcp-processing demonstrates the Public API for processing RTCP packets in Pion WebRTC.
This example is only processing messages for a RTPReceiver. A RTPReceiver is used for accepting
media from a remote peer. These APIs also exist on the RTPSender when sending media to a remote peer.
RTCP is used for statistics and control information for media in WebRTC. Using these messages
you can get information about the quality of the media, round trip time and packet loss. You can
also craft messages to influence the media quality.
## Instructions
### Download rtcp-processing
```
go install github.com/pion/webrtc/v4/examples/rtcp-processing@latest
```
### Open rtcp-processing example page
[jsfiddle.net](https://jsfiddle.net/zurq6j7x/) you should see two text-areas, 'Start Session' button and 'Copy browser SessionDescription to clipboard'
### Run rtcp-processing with your browsers Session Description as stdin
In the jsfiddle press 'Copy browser Session Description to clipboard' or copy the base64 string manually.
Now use this value you just copied as the input to `rtcp-processing`
#### Linux/macOS
Run `echo $BROWSER_SDP | rtcp-processing`
#### Windows
1. Paste the SessionDescription into a file.
1. Run `rtcp-processing < my_file`
### Input rtcp-processing's Session Description into your browser
Copy the text that `rtcp-processing` just emitted and copy into the second text area in the jsfiddle
### Hit 'Start Session' in jsfiddle
You will see console messages for each inbound RTCP message from the remote peer.
Congrats, you have used Pion WebRTC! Now start building something cool

View File

@@ -0,0 +1,8 @@
/*
SPDX-FileCopyrightText: 2026 The Pion community <https://pion.ly>
SPDX-License-Identifier: MIT
*/
textarea {
width: 500px;
min-height: 75px;
}

View File

@@ -0,0 +1,8 @@
---
# SPDX-FileCopyrightText: 2026 The Pion community <https://pion.ly>
# SPDX-License-Identifier: MIT
name: rtcp-processing
description: play-from-disk demonstrates how to process RTCP messages from Pion WebRTC
authors:
- Sean DuBois

View File

@@ -0,0 +1,29 @@
<!--
SPDX-FileCopyrightText: 2026 The Pion community <https://pion.ly>
SPDX-License-Identifier: MIT
-->
Browser Session Description
<br/>
<textarea id="localSessionDescription" readonly="true"></textarea>
<br/>
<button onclick="window.copySessionDescription()">Copy browser Session Description to clipboard</button>
<br/>
<br/>
<br/>
Remote Session Description
<br/>
<textarea id="remoteSessionDescription"></textarea>
<br/>
<button onclick="window.startSession()">Start Session</button>
<br/>
<br/>
Video<br />
<video id="video1" width="160" height="120" autoplay muted></video> <br />
Logs
<br/>
<div id="div"></div>

View File

@@ -0,0 +1,65 @@
/* eslint-env browser */
// SPDX-FileCopyrightText: 2026 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT
const pc = new RTCPeerConnection({
iceServers: [{
urls: 'stun:stun.l.google.com:19302'
}]
})
const log = msg => {
document.getElementById('div').innerHTML += msg + '<br>'
}
pc.ontrack = function (event) {
const el = document.createElement(event.track.kind)
el.srcObject = event.streams[0]
el.autoplay = true
el.controls = true
document.getElementById('remoteVideos').appendChild(el)
}
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState)
pc.onicecandidate = event => {
if (event.candidate === null) {
document.getElementById('localSessionDescription').value = btoa(JSON.stringify(pc.localDescription))
}
}
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(stream => {
document.getElementById('video1').srcObject = stream
stream.getTracks().forEach(track => pc.addTrack(track, stream))
pc.createOffer().then(d => pc.setLocalDescription(d)).catch(log)
}).catch(log)
window.startSession = () => {
const sd = document.getElementById('remoteSessionDescription').value
if (sd === '') {
return alert('Session Description must not be empty')
}
try {
pc.setRemoteDescription(JSON.parse(atob(sd)))
} catch (e) {
alert(e)
}
}
window.copySessionDescription = () => {
const browserSessionDescription = document.getElementById('localSessionDescription')
browserSessionDescription.focus()
browserSessionDescription.select()
try {
const successful = document.execCommand('copy')
const msg = successful ? 'successful' : 'unsuccessful'
log('Copying SessionDescription was ' + msg)
} catch (err) {
log('Oops, unable to copy SessionDescription ' + err)
}
}

View File

@@ -0,0 +1,144 @@
// SPDX-FileCopyrightText: 2026 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT
//go:build !js
// rtcp-processing demonstrates the Public API for processing RTCP packets in Pion WebRTC.
package main
import (
"bufio"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"os"
"strings"
"github.com/pion/webrtc/v4"
)
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)
}
// Set a handler for when a new remote track starts
peerConnection.OnTrack(func(track *webrtc.TrackRemote, receiver *webrtc.RTPReceiver) {
fmt.Printf("Track has started streamId(%s) id(%s) rid(%s) \n", track.StreamID(), track.ID(), track.RID())
for {
// Read the RTCP packets as they become available for our new remote track
rtcpPackets, _, rtcpErr := receiver.ReadRTCP()
if rtcpErr != nil {
panic(rtcpErr)
}
for _, r := range rtcpPackets {
// Print a string description of the packets
if stringer, canString := r.(fmt.Stringer); canString {
fmt.Printf("Received RTCP Packet: %v", stringer.String())
}
}
}
})
// 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{}
decode(readUntilNewline(), &offer)
// Set the remote SessionDescription
err = peerConnection.SetRemoteDescription(offer)
if err != nil {
panic(err)
}
// Create answer
answer, err := peerConnection.CreateAnswer(nil)
if err != nil {
panic(err)
}
// Create channel that is blocked until ICE Gathering is complete
gatherComplete := webrtc.GatheringCompletePromise(peerConnection)
// Sets the LocalDescription, and starts our UDP listeners
err = peerConnection.SetLocalDescription(answer)
if err != nil {
panic(err)
}
// Block until ICE Gathering is complete, disabling trickle ICE
// we do this because we only can exchange one signaling message
// in a production application you should exchange ICE Candidates via OnICECandidate
<-gatherComplete
// Output the answer in base64 so we can paste it in browser
fmt.Println(encode(peerConnection.LocalDescription()))
// Block forever
select {}
}
// Read from stdin until we get a newline.
func readUntilNewline() (in string) {
var err error
r := bufio.NewReader(os.Stdin)
for {
in, err = r.ReadString('\n')
if err != nil && !errors.Is(err, io.EOF) {
panic(err)
}
if in = strings.TrimSpace(in); len(in) > 0 {
break
}
}
fmt.Println("")
return
}
// JSON encode + base64 a SessionDescription.
func encode(obj *webrtc.SessionDescription) string {
b, err := json.Marshal(obj)
if err != nil {
panic(err)
}
return base64.StdEncoding.EncodeToString(b)
}
// Decode a base64 and unmarshal JSON into a SessionDescription.
func decode(in string, obj *webrtc.SessionDescription) {
b, err := base64.StdEncoding.DecodeString(in)
if err != nil {
panic(err)
}
if err = json.Unmarshal(b, obj); err != nil {
panic(err)
}
}