1.基本線程
webrtc中擁有有兩個全局線程,使用webrtc時可以提供這兩個線程厉膀,也可以使用內(nèi)部創(chuàng)建好的線程:
- signaling_thread-->信令線程驼壶。要求此線程內(nèi)的方法都必須快速返回
- worker_thread-->工作者線程粟焊。此線程內(nèi)的方法可能會處理很長時間
其中付魔,所有API調(diào)用都會被代理到信令線程,所有回調(diào)函數(shù)都在信令線程調(diào)用肋坚,所以回調(diào)函數(shù)不能執(zhí)行長時間阻塞操作乡括。應當將嚴重小號資源的過程放在工作者線程執(zhí)行,如數(shù)據(jù)流傳輸智厌。
2.線程實現(xiàn)
webrtc的線程中包含一個消息隊列诲泌,當需要在此線程中運行邏輯時,只需要向線程中發(fā)送一個消息铣鹏,線程部分類圖如下:
20150623120430554.jpg
可以看到線程類繼承了消息隊列類敷扫,也就擁有消息隊列的所有特性,而消息又包含有消息需要傳遞的數(shù)據(jù)和消息處理函數(shù)诚卸。
3.MediaStream API(mediastreaminterface.h)
主要是MediaStreamTrack接口和MediaStream接口
- MediaStreamTrack接口葵第,代表來自瀏覽器的一種媒體資源,就像視屏資源或是音頻資源一樣
- MediaStream接口合溺,可以打包一系列媒體資源成為一個整體卒密,可以被記錄或者在媒體元素中渲染處理
其中,每一個MediaStream對象可以包含零個或者多個MediaStreamTrack對象棠赛,這些Track對象都會被同步渲染哮奇。
MediaStream對象有一個輸入和一個輸出,它可以合并所有輸入或輸出的Track媒體資源睛约,一個MediaStream對象也可以同時被關聯(lián)到多個輸出鼎俘。
3.1 MediaStream類
- MediaStream的構造函數(shù)可以合并一系列Track媒體資源,然后將這些媒體資源存儲在一個track set中痰腮,其中track的順序是瀏覽器定義的而芥,唯一能找到一個track對象的方法就是去查看它的id
- MediaStream對象的消費者就是去讀取這個對象數(shù)據(jù)的對象律罢,如媒體標簽<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對象有兩個狀態(tài):live和ended, 一個新創(chuàng)建的MediaStreamTrack對象的狀態(tài)依賴于它是怎么被創(chuàng)建的,當前的狀態(tài)反映在它的readyState屬性中砰苍,當track處于live狀態(tài)時潦匈,這個媒體資源是可以被消費者使用的阱高。
其接口定義如下:
class MediaStreamTrackInterface : public rtc::RefCountInterface,
public NotifierInterface {
public:
//傳輸軌道狀態(tài)
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;
// 讀取軌道當前狀態(tài)掂为,kLive或kEnded裕膀,軌道終止后將不能被重新激活
virtual TrackState state() const = 0;
protected:
//為多態(tài)基類聲明一個虛析構函數(shù)
virtual ~MediaStreamTrackInterface() {}
};
- VideoTrackInterface類
表示視頻軌道,繼承自類MediaStreamTrackInterface勇哗,可以設置和獲取視頻渲染器
其接口如下:
class VideoTrackInterface
: public MediaStreamTrackInterface,
public rtc::VideoSourceInterface<VideoFrame> {
public:
//視頻軌道內(nèi)容提示昼扛,如這個視頻是包含運動的視頻,還是包含細節(jié)的視頻
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;
//獲取視頻內(nèi)容提示
virtual ContentHint content_hint() const { return ContentHint::kNone; }
//設置視頻內(nèi)容
virtual void set_content_hint(ContentHint hint) {}
protected:
//為多態(tài)基類聲明一個虛析構函數(shù)
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++代碼中,部分類在整體類的構造函數(shù)中被構造殴边,在析構函數(shù)中被析構 - 聚合
部分和整體之間沒有相同的生命周期憎茂,當整體消亡后,部分也可以獨立存在锤岸。C++代碼中竖幔,整體類用指針來保存部分類,當整體類析構的時候是偷,部分類并不會析構