webRTC学习笔记(二)

1.基本线程

webrtc中拥有有两个全局线程,使用webrtc时可以提供这两个线程,也可以使用内部创建好的线程:

  • signaling_thread-->信令线程。要求此线程内的方法都必须快速返回
  • worker_thread-->工作者线程。此线程内的方法可能会处理很长时间
    其中,所有API调用都会被代理到信令线程,所有回调函数都在信令线程调用,所以回调函数不能执行长时间阻塞操作。应当将严重小号资源的过程放在工作者线程执行,如数据流传输。

2.线程实现

webrtc的线程中包含一个消息队列,当需要在此线程中运行逻辑时,只需要向线程中发送一个消息,线程部分类图如下:


20150623120430554.jpg

可以看到线程类继承了消息队列类,也就拥有消息队列的所有特性,而消息又包含有消息需要传递的数据和消息处理函数。

3.MediaStream API(mediastreaminterface.h)

主要是MediaStreamTrack接口和MediaStream接口

  • MediaStreamTrack接口,代表来自浏览器的一种媒体资源,就像视屏资源或是音频资源一样
  • MediaStream接口,可以打包一系列媒体资源成为一个整体,可以被记录或者在媒体元素中渲染处理

其中,每一个MediaStream对象可以包含零个或者多个MediaStreamTrack对象,这些Track对象都会被同步渲染。
MediaStream对象有一个输入和一个输出,它可以合并所有输入或输出的Track媒体资源,一个MediaStream对象也可以同时被关联到多个输出。

3.1 MediaStream类

  • MediaStream的构造函数可以合并一系列Track媒体资源,然后将这些媒体资源存储在一个track set中,其中track的顺序是浏览器定义的,唯一能找到一个track对象的方法就是去查看它的id
  • MediaStream对象的消费者就是去读取这个对象数据的对象,如媒体标签<video>和<audio>,RTCPeerConnection对象等。

其接口定义如下:

class MediaStreamInterface : public rtc::RefCountInterface,
                             public NotifierInterface {
 public:
  virtual std::string label() const = 0;

  virtual AudioTrackVector GetAudioTracks() = 0;
  virtual VideoTrackVector GetVideoTracks() = 0;
  virtual rtc::scoped_refptr<AudioTrackInterface>
      FindAudioTrack(const std::string& track_id) = 0;
  virtual rtc::scoped_refptr<VideoTrackInterface>
      FindVideoTrack(const std::string& track_id) = 0;

  virtual bool AddTrack(AudioTrackInterface* track) = 0;
  virtual bool AddTrack(VideoTrackInterface* track) = 0;
  virtual bool RemoveTrack(AudioTrackInterface* track) = 0;
  virtual bool RemoveTrack(VideoTrackInterface* track) = 0;

 protected:
  virtual ~MediaStreamInterface() {}
};

其实可以把这个类理解为MediaStreamTrack媒体资源类的容器,可以合并视频资源和音频资源,并可以对媒体资源进行增删改查操作,同时它也是一个观察者。

3.2 MediaStreamTrack类

MediaStreamTrack类代表了浏览器中的媒体通道。

  • 生命周期
    一个MediaStreamTrack对象有两个状态:live和ended, 一个新创建的MediaStreamTrack对象的状态依赖于它是怎么被创建的,当前的状态反映在它的readyState属性中,当track处于live状态时,这个媒体资源是可以被消费者使用的。
    其接口定义如下:
class MediaStreamTrackInterface : public rtc::RefCountInterface,
                                  public NotifierInterface {
 public:
  //传输轨道状态
  enum TrackState {
    kLive,   //媒体通道可用
    kEnded,   //媒体通道不可用
  };

  static const char kAudioKind[];
  static const char kVideoKind[];

  // 当传输音频轨道时返回kAudioKind,由浏览器定义
  // 当传输视频轨道时返回kVideoKind,由浏览器定义
  //通常可以用来将其父类对象转化为响应的子类对象
  virtual std::string kind() const = 0;

  // 读取轨道的唯一标识
  virtual std::string id() const = 0;

  //判断轨道是否可用,当音频轨道不可用时,将会静音;当视频轨道不可用时,将会黑屏
  virtual bool enabled() const = 0;

  //开启或关闭媒体轨道
  virtual bool set_enabled(bool enable) = 0;

  // 读取轨道当前状态,kLive或kEnded,轨道终止后将不能被重新激活
  virtual TrackState state() const = 0;

 protected:
  //为多态基类声明一个虚析构函数
  virtual ~MediaStreamTrackInterface() {}
};
  • VideoTrackInterface类
    表示视频轨道,继承自类MediaStreamTrackInterface,可以设置和获取视频渲染器
    其接口如下:
class VideoTrackInterface
    : public MediaStreamTrackInterface,
      public rtc::VideoSourceInterface<VideoFrame> {
 public:
  //视频轨道内容提示,如这个视频是包含运动的视频,还是包含细节的视频
  enum class ContentHint { kNone, kFluid, kDetailed };

  //设置视频接收器,来将视频通道和视频播放器连接起来
  void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
                       const rtc::VideoSinkWants& wants) override {}

  //移除视频接收器
  void RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink) override {}

  //获取视频来源对象
  virtual VideoTrackSourceInterface* GetSource() const = 0;

  //获取视频内容提示
  virtual ContentHint content_hint() const { return ContentHint::kNone; }

  //设置视频内容
  virtual void set_content_hint(ContentHint hint) {}

 protected:
  //为多态基类声明一个虚析构函数
  virtual ~VideoTrackInterface() {}
};
  • AudioTrackInterface类
    表示音频轨道,继承自类MediaStreamTrackInterface,可以设置和获取视频接收器
    其接口同VideoTrackInterface类
class AudioTrackInterface : public MediaStreamTrackInterface {
 public:
  virtual AudioSourceInterface* GetSource() const =  0;

  virtual void AddSink(AudioTrackSinkInterface* sink) = 0;
  virtual void RemoveSink(AudioTrackSinkInterface* sink) = 0;

  //获取信号电平(强度),这里有错误,修改后会返回int类型
  virtual bool GetSignalLevel(int* level) { return false; }

 //获取音频处理器
  virtual rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor() {
    return nullptr;
  }

 protected:
  virtual ~AudioTrackInterface() {}
};

PS:组合和聚合的关系

  • 组合
    部分和整体之间具有相同的生命周期,当整体消亡后,部分也将消亡。C++代码中,部分类在整体类的构造函数中被构造,在析构函数中被析构
  • 聚合
    部分和整体之间没有相同的生命周期,当整体消亡后,部分也可以独立存在。C++代码中,整体类用指针来保存部分类,当整体类析构的时候,部分类并不会析构
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容