webrtc

package
v1.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 4, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package webrtc 提供 WebRTC 的 WHIP(采集)/WHEP(分发)薄机制,基于纯 Go 的 pion/webrtc(零 cgo)。作为 pkg/hls(多秒级、面向 CDN 分发)之外,面向亚秒级、 交互式实时媒体的可选传输——和 pkg/quic + pkg/gameloop 同属「实时」家族。

延迟等级(选型要点):

  • RTMP→HLS/LL-HLS(pkg/media/rtmp + pkg/hls):多秒级,一对多、可过 CDN,直播/点播分发。
  • WebRTC WHIP/WHEP(本包):亚秒级、可双向,连麦/云游戏/实时协作。NAT 穿透靠 ICE/STUN/TURN。

WHIP/WHEP 本质相同——都是「HTTP 一发一答的 SDP 协商,服务端做 answerer」:

  • WHIP(Ingestion):推流端 POST 一个 offer,服务端收流。在回调里注册 pc.OnTrack 拿进来的轨道。
  • WHEP(Egress):播放端 POST 一个 offer,服务端发流。在回调里 pc.AddTrack 把要发的轨道挂上。

方向由回调对 PeerConnection 做什么决定,机制是同一个(见 Endpoint / NewWHIP / NewWHEP)。

边界(机制而非策略):本包只负责 HTTP+SDP+ICE 协商、WHIP 资源生命周期(DELETE 拆除、 断连自动回收),以及 RTP 转发原语(Pipe——纯 RTP 包转发,不转码、不做抖动缓冲)。谁能推/ 谁能看(鉴权)、转发拓扑(SFU/MCU)、编解码档位、STUN/TURN 选路、录制、CORS,全是 policy, 留给上层。Endpoint 是 http.Handler,用 beauty.WithWebServer 挂上即可,不自起监听(与 pkg/hls 一致)。

最小用法(把一路 WHIP 推流广播给多个 WHEP 播放端——最小 SFU):见 examples/webrtc-whip-whep。

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Answer

func Answer(ctx context.Context, pc *pion.PeerConnection, offer string) (string, error)

Answer 执行 WHIP/WHEP 服务端(answerer)一侧的协商:把远端 offer 应用到 pc、生成 answer、等待 ICE 收集完成(WHIP/WHEP 只有一次 SDP 交换、不 trickle,故须等齐候选), 返回 answer 的 SDP。协商前应先在 pc 上注册 OnTrack(WHIP)或 AddTrack(WHEP)。

func NewAPI

func NewAPI(opts ...APIOption) (*pion.API, error)

NewAPI 构造一个 *webrtc.API:注册默认编解码集(Opus / VP8 / VP9 / H264 等)与默认 拦截器(NACK 重传、RTCP 收发报告、TWCC)。多数场景直接用它;需要自定义编解码时用 WithMediaEngine 传入自行 RegisterCodec 过的 MediaEngine。

func NewLocalTrackFor

func NewLocalTrackFor(remote *pion.TrackRemote, id, streamID string) (*pion.TrackLocalStaticRTP, error)

NewLocalTrackFor 按远端轨道的编解码能力建一个可写的本地轨道,用于把收到的 RTP 转发出去(转发拓扑的核心:一路 WHIP 进来的 remote track → 一个 local track → 多个 WHEP 播放端 AddTrack 订阅)。id/streamID 是轨道标识(同一 streamID 下的音视频会被 播放端当作同一路媒体)。

func Pipe

func Pipe(ctx context.Context, remote *pion.TrackRemote, local *pion.TrackLocalStaticRTP) error

Pipe 把远端轨道的 RTP 包原样转发到本地轨道,直到远端轨道结束(对端停发 / 连接关闭) 或读到 EOF。纯包转发——不解码、不转码、不做抖动缓冲,是 SFU 转发的最小原语。 local.WriteRTP 会扇出给所有 AddTrack 了该 local 轨道的 PeerConnection。

注意:ReadRTP 会阻塞,ctx 取消不会立即中断它;Pipe 主要靠远端轨道结束来返回。要强制 停止,关闭承载 remote 的 PeerConnection 即可解除阻塞。

Types

type APIOption

type APIOption func(*apiConfig)

APIOption 配置 NewAPI。

func WithMediaEngine

func WithMediaEngine(me *pion.MediaEngine) APIOption

WithMediaEngine 用自定义 MediaEngine(自行 RegisterCodec / RegisterHeaderExtension) 替代默认编解码集——例如只保留 H264+Opus、或加私有 profile。

type Endpoint

type Endpoint struct {
	// contains filtered or unexported fields
}

Endpoint 是 WHIP/WHEP 的服务端 http.Handler:

  • POST(application/sdp):协商一路会话,回 201 + answer + Location(资源地址);
  • DELETE <Location>:拆除该会话;
  • 断连(ICE Failed/Closed)自动回收。

挂载到任意路由前缀即可,streamKey = 前缀之后的路径。例如 mux.Handle("/whip/", http.StripPrefix("/whip/", ep)) 则 POST /whip/room1 的 streamKey="room1"。 零值不可用,用 NewEndpoint / NewWHIP / NewWHEP 构造。

func NewEndpoint

func NewEndpoint(api *pion.API, negotiate NegotiateFunc, opts ...EndpointOption) *Endpoint

NewEndpoint 构造一个 WHIP/WHEP 端点。api 由 NewAPI 得到;negotiate 决定每路会话怎么接。

func NewWHEP

func NewWHEP(api *pion.API, onSubscribe NegotiateFunc, opts ...EndpointOption) *Endpoint

NewWHEP 构造一个 WHEP(分发)端点——语义上「发流」,请在 onSubscribe 里 pc.AddTrack。 与 NewEndpoint 机制相同,仅默认名字不同,便于识别。

func NewWHIP

func NewWHIP(api *pion.API, onPublish NegotiateFunc, opts ...EndpointOption) *Endpoint

NewWHIP 构造一个 WHIP(采集)端点——语义上「收流」,请在 onPublish 里注册 pc.OnTrack。 与 NewEndpoint 机制相同,仅默认名字不同,便于识别。

func (*Endpoint) Close

func (e *Endpoint) Close() error

Close 关闭所有活跃会话(用于优雅停机)。

func (*Endpoint) Count

func (e *Endpoint) Count() int

Count 返回当前活跃会话数。

func (*Endpoint) ServeHTTP

func (e *Endpoint) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP 实现 http.Handler。

type EndpointOption

type EndpointOption func(*Endpoint)

EndpointOption 配置 Endpoint。

func WithBasePath

func WithBasePath(p string) EndpointOption

WithBasePath 告知 Endpoint 自己的挂载前缀(如 "/whip"),这样:

  • streamKey = 请求路径去掉该前缀后的部分;
  • Location 头是绝对路径(<basePath>/<streamKey>/<id>),DELETE 能直接路由回来。

用法:mux.Handle("/whip/", NewWHIP(api, fn, WithBasePath("/whip")))。不设时按相对 路径处理(适配 http.StripPrefix 挂载,但 Location 为相对引用)。

func WithConfiguration

func WithConfiguration(c pion.Configuration) EndpointOption

WithConfiguration 直接覆盖 PeerConnection 配置(ICEServers、ICETransportPolicy 等)。

func WithEndpointName

func WithEndpointName(name string) EndpointOption

WithEndpointName 设置名字(日志标识用)。

func WithICEServers

func WithICEServers(servers ...pion.ICEServer) EndpointOption

WithICEServers 设置 STUN/TURN 服务器(NAT 穿透)。不设则只用主机候选(仅同网段/本机可达)。

type NegotiateFunc

type NegotiateFunc func(streamKey string, pc *pion.PeerConnection) error

NegotiateFunc 在收到一次 WHIP/WHEP offer 时被调用:streamKey 取自请求路径(挂载点 之后的部分),pc 是本次会话新建的 PeerConnection。在此:

  • 做鉴权/准入:返回非 nil error 即拒绝(关闭 pc,回 403);
  • WHIP(收流):注册 pc.OnTrack 拿进来的轨道;
  • WHEP(发流):pc.AddTrack 把要发送的本地轨道挂上。

返回 nil 后本包生成 answer 并回 201。回调应尽快返回(不要在里面阻塞读 RTP—— 用 OnTrack 回调里另起 goroutine)。

Directories

Path Synopsis
Package sfu 在 pkg/media/webrtc 之上提供一个「会议室」SFU 原语:多人实时音视频, 每个参会者推自己的轨道、订阅其他所有人的轨道,服务端做选择性转发(Selective Forwarding Unit,不混流不转码)。
Package sfu 在 pkg/media/webrtc 之上提供一个「会议室」SFU 原语:多人实时音视频, 每个参会者推自己的轨道、订阅其他所有人的轨道,服务端做选择性转发(Selective Forwarding Unit,不混流不转码)。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
⌂ 换网址