webrtc example peerconnect client 添加track

此次修改,主要是为了查看怎么在运行过程中添加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(msg->wParam),
                                reinterpret_cast(msg->lParam));
    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> remote_renderer_;  //修改成多个remote renderer

main_wnd.cc

void MainWnd::StartRemoteRenderer(webrtc::VideoTrackInterface* remote_video) {

    std::unique_ptr render;
    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 local_lock(local_renderer);
          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 remote_lock(remote_renderer.get());
          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,并在对方的程序中显示,如下图

webrtc example peerconnect client 添加track_第1张图片

 

你可能感兴趣的:(webrtc学习)