此次修改,主要是为了查看怎么在运行过程中添加track,例子比较小,大家看下就行
本次程序修改主要是在webrtc 的 peerconnect_client 中
1. 为了在运行时能够接收到空格键命令,在 main_wnd.cc
bool MainWnd::PreTranslateMessage(MSG* msg) {
bool ret = false;
if (msg->message == WM_CHAR) {
if (msg->wParam == VK_TAB) {
HandleTabbing();
ret = true;
} else if (msg->wParam == VK_RETURN) {
OnDefaultAction();
ret = true;
} else if (msg->wParam == VK_ESCAPE) {
if (callback_) {
if (ui_ == STREAMING) {
callback_->DisconnectFromCurrentPeer();
} else {
callback_->DisconnectFromServer();
}
}
}
else if (msg->wParam == VK_SPACE) {
// 如果是空格键,就addtrack
callback_->AddTrack();
}
} else if (msg->hwnd == NULL && msg->message == UI_THREAD_CALLBACK) {
callback_->UIThreadCallback(static_cast
reinterpret_cast
ret = true;
}
return ret;
}
2. 在callback_ 回调中添加AddTrack 函数
main_wnd.h
class MainWndCallback {
public:
virtual void StartLogin(const std::string& server, int port) = 0;
virtual void DisconnectFromServer() = 0;
virtual void ConnectToPeer(int peer_id) = 0;
virtual void DisconnectFromCurrentPeer() = 0;
virtual void UIThreadCallback(int msg_id, void* data) = 0;
virtual void Close() = 0;
virtual void AddTrack() = 0;
protected:
virtual ~MainWndCallback() {}
};
3. 在Conductor.cc 中实现
void Conductor::AddTrack() {
// 添加track
AddTracks();
// 并发送offer 消息,这里一定要发送,否则对方是不知道sdp的,无法知道新track的添加
peer_connection_->CreateOffer(
this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
}
4. 在AddTracks() 中有remote render 限制,要去掉
void Conductor::AddTracks() {
//if (!peer_connection_->GetSenders().empty()) {
// return; // Already added tracks.
//}
5. 以上对方就已经能够获取到新的track 了,限制我们要在新track 到达后建立新的render,进行渲染
main_wnd.h
std::vector
main_wnd.cc
void MainWnd::StartRemoteRenderer(webrtc::VideoTrackInterface* remote_video) {
std::unique_ptr
render.reset(new VideoRenderer(handle(), 1, 1, remote_video));
remote_renderer_.push_back(std::move(render));
}
渲染处,修改如下, 我这里主要是添加4个渲染,如果要添加多个,请自行参照修改
void MainWnd::OnPaint() {
PAINTSTRUCT ps;
::BeginPaint(handle(), &ps);
RECT rc;
::GetClientRect(handle(), &rc);
VideoRenderer* local_renderer = local_renderer_.get();
if (ui_ == STREAMING && remote_renderer_.size() && local_renderer) {
bool paintFlag = false;
for (auto &remote_renderer : remote_renderer_) {
const uint8_t* image = remote_renderer->image();
if (image != NULL) {
paintFlag = true;
}
}
if (paintFlag) {
int height = 1280;
int width = 1280;
HDC dc_mem = ::CreateCompatibleDC(ps.hdc);
::SetStretchBltMode(dc_mem, HALFTONE);
// Set the map mode so that the ratio will be maintained for us.
HDC all_dc[] = { ps.hdc, dc_mem };
for (int i = 0; i < arraysize(all_dc); ++i) {
SetMapMode(all_dc[i], MM_ISOTROPIC);
SetWindowExtEx(all_dc[i], width, height, NULL);
SetViewportExtEx(all_dc[i], rc.right, rc.bottom, NULL);
}
HBITMAP bmp_mem = ::CreateCompatibleBitmap(ps.hdc, rc.right, rc.bottom);
HGDIOBJ bmp_old = ::SelectObject(dc_mem, bmp_mem);
POINT logical_area = { rc.right, rc.bottom };
DPtoLP(ps.hdc, &logical_area, 1);
int thumb_width = logical_area.x / 2;
int thumb_height = logical_area.y / 2;
HBRUSH brush = ::CreateSolidBrush(RGB(0, 0, 0));
RECT logical_rect = { 0, 0, logical_area.x, logical_area.y };
::FillRect(dc_mem, &logical_rect, brush);
::DeleteObject(brush);
int x = 0;
int y = 0;
{
AutoLock
const BITMAPINFO& bmi = local_renderer->bmi();
const uint8_t* image = local_renderer->image();
StretchDIBits(dc_mem, x, y, thumb_width, thumb_height, 0, 0, bmi.bmiHeader.biWidth, -bmi.bmiHeader.biHeight, image,
&bmi, DIB_RGB_COLORS, SRCCOPY);
}
int index = 0;
for (auto &remote_renderer : remote_renderer_) {
AutoLock
const BITMAPINFO& bmi = remote_renderer->bmi();
const uint8_t* image = remote_renderer->image();
if (index == 0) {
x = x + thumb_width + 5;
}
else if (index == 1){
x = 0;
y = y + thumb_height + 5;
}
else if (index == 2) {
x = x + thumb_width + 5;
}
StretchDIBits(dc_mem, x, y, thumb_width, thumb_height, 0, 0, bmi.bmiHeader.biWidth, abs(bmi.bmiHeader.biHeight), image,
&bmi, DIB_RGB_COLORS, SRCCOPY);
index++;
}
BitBlt(ps.hdc, 0, 0, logical_area.x, logical_area.y, dc_mem, 0, 0,
SRCCOPY);
// Cleanup.
::SelectObject(dc_mem, bmp_old);
::DeleteObject(bmp_mem);
::DeleteDC(dc_mem);
} else {
// We're still waiting for the video stream to be initialized.
HBRUSH brush = ::CreateSolidBrush(RGB(0, 0, 0));
::FillRect(ps.hdc, &rc, brush);
::DeleteObject(brush);
HGDIOBJ old_font = ::SelectObject(ps.hdc, GetDefaultFont());
::SetTextColor(ps.hdc, RGB(0xff, 0xff, 0xff));
::SetBkMode(ps.hdc, TRANSPARENT);
const char kConnecting[] = "Connecting... ";
const char kNoVideoStreams[] = "(no video streams either way)";
const char kNoIncomingStream[] = "(no incoming video)";
std::string text(kConnecting);
if (!local_renderer->image()) {
text += kNoVideoStreams;
} else {
text += kNoIncomingStream;
}
::DrawTextA(ps.hdc, text.c_str(), -1, &rc,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
::SelectObject(ps.hdc, old_font);
}
} else {
HBRUSH brush = ::CreateSolidBrush(::GetSysColor(COLOR_WINDOW));
::FillRect(ps.hdc, &rc, brush);
::DeleteObject(brush);
}
::EndPaint(handle(), &ps);
}
按照上面就可以在运行时,按空格键,就添加track,并在对方的程序中显示,如下图