1.基本线程
webrtc中拥有有两个全局线程,使用webrtc时可以提供这两个线程,也可以使用内部创建好的线程:
- signaling_thread-->信令线程。要求此线程内的方法都必须快速返回
- worker_thread-->工作者线程。此线程内的方法可能会处理很长时间
其中,所有API调用都会被代理到信令线程,所有回调函数都在信令线程调用,所以回调函数不能执行长时间阻塞操作。应当将严重小号资源的过程放在工作者线程执行,如数据流传输。
2.线程实现
webrtc的线程中包含一个消息队列,当需要在此线程中运行逻辑时,只需要向线程中发送一个消息,线程部分类图如下:
可以看到线程类继承了消息队列类,也就拥有消息队列的所有特性,而消息又包含有消息需要传递的数据和消息处理函数。
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++代码中,整体类用指针来保存部分类,当整体类析构的时候,部分类并不会析构