Yin的笔记本

vuePress-theme-reco Howard Yin    2021 - 2025
Yin的笔记本 Yin的笔记本

Choose mode

  • dark
  • auto
  • light
Home
Category
  • CNCF
  • Docker
  • namespaces
  • Kubernetes
  • Kubernetes对象
  • Linux
  • MyIdeas
  • Revolution
  • WebRTC
  • 云计算
  • 人工智能
  • 分布式
  • 图像处理
  • 图形学
  • 微服务
  • 数学
  • OJ笔记
  • 博弈论
  • 形式语言与自动机
  • 数据库
  • 服务器运维
  • 编程语言
  • C
  • Git
  • Go
  • Java
  • JavaScript
  • Python
  • Nvidia
  • Rust
  • Tex
  • Shell
  • Vue
  • 视频编解码
  • 计算机网络
  • SDN
  • 论文笔记
  • 讨论
  • 边缘计算
  • 量子信息技术
Tag
TimeLine
About
查看源码
author-avatar

Howard Yin

303

Article

153

Tag

Home
Category
  • CNCF
  • Docker
  • namespaces
  • Kubernetes
  • Kubernetes对象
  • Linux
  • MyIdeas
  • Revolution
  • WebRTC
  • 云计算
  • 人工智能
  • 分布式
  • 图像处理
  • 图形学
  • 微服务
  • 数学
  • OJ笔记
  • 博弈论
  • 形式语言与自动机
  • 数据库
  • 服务器运维
  • 编程语言
  • C
  • Git
  • Go
  • Java
  • JavaScript
  • Python
  • Nvidia
  • Rust
  • Tex
  • Shell
  • Vue
  • 视频编解码
  • 计算机网络
  • SDN
  • 论文笔记
  • 讨论
  • 边缘计算
  • 量子信息技术
Tag
TimeLine
About
查看源码
  • interceptor寻踪:pion/interceptor在pion/webrtc里的用法解析

    • 初始化:NewPeerConnection
      • 在NewPeerConnection之前
      • 在NewPeerConnection里
    • 中场休息
      • 准备好,要开始加速了

      interceptor寻踪:`pion/interceptor`在`pion/webrtc`里的用法解析

      vuePress-theme-reco Howard Yin    2021 - 2025

      interceptor寻踪:pion/interceptor在pion/webrtc里的用法解析


      Howard Yin 2021-10-09 11:34:00 WebRTC编程框架pion概念

      # 初始化:NewPeerConnection

      本节主要讲解WebRTC标准接口NewPeerConnection内部和调用前所需要进行的interceptor初始化操作。在开始前,你首先需要去《用实例学习pion - rtp-forwarder》和《pion学习总结:等待传入track的一般流程》里看看NewPeerConnection的用法以及在调用NewPeerConnection前所需要进行的操作;然后你还需要理解《pion/interceptor浅析》中关于级联的思想和《用实例学习pion interceptor - nack》里出现的interceptor.NewChain是什么。

      # 在NewPeerConnection之前

      从《用实例学习pion - rtp-forwarder》中可以看到,在正式调用api.NewPeerConnection之前,与pion/interceptor有关的操作主要就是创建interceptor.Registry并调用webrtc.NewAPI创建WebRTC标准API。这个interceptor.Registry非常之简单:

      // Registry is a collector for interceptors.
      type Registry struct {
      	interceptors []Interceptor
      }
      
      // Add adds a new Interceptor to the registry.
      func (i *Registry) Add(icpr Interceptor) {
      	i.interceptors = append(i.interceptors, icpr)
      }
      
      // Build constructs a single Interceptor from a InterceptorRegistry
      func (i *Registry) Build() Interceptor {
      	if len(i.interceptors) == 0 {
      		return &NoOp{}
      	}
      
      	return NewChain(i.interceptors)
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18

      可以看到,类方法就两个,一个Add就是添加,然后一个Build生成一个interceptor.Chain。所以这个interceptor.Registry的用处很明显就是构造interceptor的调用链。

      从《用实例学习pion - rtp-forwarder》中还可以看到,这个interceptor.Registry并不是直接输入到webrtc.NewAPI里的,而是先经过了一个webrtc.WithInterceptorRegistry,这个webrtc.WithInterceptorRegistry更是简单:

      // WithInterceptorRegistry allows providing Interceptors to the API.
      // Settings should not be changed after passing the registry to an API.
      func WithInterceptorRegistry(interceptorRegistry *interceptor.Registry) func(a *API) {
      	return func(a *API) {
      		a.interceptor = interceptorRegistry.Build()
      	}
      }
      
      1
      2
      3
      4
      5
      6
      7

      直接就是调用上面那个interceptor.Registry里的Build函数。

      # 在NewPeerConnection里

      NewPeerConnection就是这个函数:

      func (api *API) NewPeerConnection(configuration Configuration) (*PeerConnection, error)
      
      1

      在这个函数里与interceptor相关的就一句:

      pc.interceptorRTCPWriter = api.interceptor.BindRTCPWriter(interceptor.RTCPWriterFunc(pc.writeRTCP))
      
      1

      显然这是给interceptor绑了一个实际进行RTCP写操作的函数pc.writeRTCP,这个函数显然是要负责把RTCP包发出去。返回的RTCPWriter被记录在了pc.interceptorRTCPWriter里。看看这个pc.interceptorRTCPWriter被调用的位置:

      // WriteRTCP sends a user provided RTCP packet to the connected peer. If no peer is connected the
      // packet is discarded. It also runs any configured interceptors.
      func (pc *PeerConnection) WriteRTCP(pkts []rtcp.Packet) error {
      	_, err := pc.interceptorRTCPWriter.Write(pkts, make(interceptor.Attributes))
      	return err
      }
      
      1
      2
      3
      4
      5
      6

      嗯,直接就是封装在WriteRTCP里,很符合直觉。看过《pion/interceptor浅析》和《用实例学习pion interceptor - nack》就能明白,系统需要的发送RTCP包的过程都已经封装在interceptor里了,不需要用户手动去调用,这里的WriteRTCP只是留给用户自定义RTCP发包过程调用的。

      最后当然也有关闭的操作,在PeerConnection.Close里,就是在关闭PeerConnection时要关闭interceptor,很好理解。

      # 中场休息

      截至目前,我们在NewPeerConnection找到了一堆初始化操作,我们看到:

      • BindRTCPWriter在NewPeerConnection里被调用,返回的RTCPWriter.Write在PeerConnection的WriteRTCP里调用,供用户发送一些自定义的RTCP包

      根据《pion/interceptor浅析》,还差BindRTCPReader、BindRemoteStream、BindLocalStream的相关操作没用找到。

      # 准备好,要开始加速了

      在PeerConnection里,与RTP包收发相关的操作当属AddTrack和OnTrack。

      其中,AddTrack接受一个TrackLocal,返回一个RTPSender:

      func (pc *PeerConnection) AddTrack(track TrackLocal) (*RTPSender, error)
      
      1

      而OnTrack回调的输入也是一个TrackRemote和一个RTPReceiver:

      func (pc *PeerConnection) OnTrack(f func(*TrackRemote, *RTPReceiver))
      
      1

      一眼看去,两个函数,AddTrack主发,OnTrack主收,其输入输出参数遥相呼应。显然,他们之间必有共通之处。

      顺着AddTrack和OnTrack深入一层,我们就来到了Track的领域,这里的主角是TrackLocal和TrackRemote,分别主导RTP发送和接收的过程。下面两篇文章分别从TrackLocal和TrackRemote入手,深挖interceptor在发送RTP包和接收RTP包的场景下的调用方式。在开始前,你首先需要去《pion中的TrackLocal》和《pion中的TrackRemote》里看看TrackLocal和TrackRemote是什么以及怎么用。

      • 《interceptor寻踪:从TrackLocal开始深入挖掘pion/interceptor的用法》

      • 《interceptor寻踪:从TrackRemote开始深入挖掘pion/interceptor的用法》

      • 《interceptor寻踪:总结》

      帮助我们改善此页面!
      创建于: 2021-09-21 03:23:37

      更新于: 2021-10-09 11:34:07