p2p audio ok
parent
492bcca9b5
commit
489c84d85b
|
@ -8,6 +8,9 @@
|
||||||
#include <Lmcons.h>
|
#include <Lmcons.h>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
|
||||||
|
const char kCandidateSdpMidName[] = "sdpMid";
|
||||||
|
const char kCandidateSdpMlineIndexName[] = "sdpMLineIndex";
|
||||||
|
const char kCandidateSdpName[] = "candidate";
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent)
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
: QMainWindow(parent)
|
: QMainWindow(parent)
|
||||||
|
@ -55,6 +58,11 @@ const char kAudioLabel[] = "audio_label";
|
||||||
const char kVideoLabel[] = "video_label";
|
const char kVideoLabel[] = "video_label";
|
||||||
const char kStreamId[] = "stream_id";
|
const char kStreamId[] = "stream_id";
|
||||||
|
|
||||||
|
void WebrtcHanlder::SetRemotePeerName(QString remote)
|
||||||
|
{
|
||||||
|
this->mRemoteName = remote;
|
||||||
|
}
|
||||||
|
|
||||||
int WebrtcHanlder::InitWebrtc()
|
int WebrtcHanlder::InitWebrtc()
|
||||||
{
|
{
|
||||||
m_peer_connection_factory_ = webrtc::CreatePeerConnectionFactory(
|
m_peer_connection_factory_ = webrtc::CreatePeerConnectionFactory(
|
||||||
|
@ -100,8 +108,7 @@ int WebrtcHanlder::InitWebrtc()
|
||||||
qDebug() << "Failed to add audio track to PeerConnection: "
|
qDebug() << "Failed to add audio track to PeerConnection: "
|
||||||
<< result_or_error.error().message();
|
<< result_or_error.error().message();
|
||||||
}
|
}
|
||||||
//rtc::scoped_refptr<CapturerTrackSource> video_device =
|
|
||||||
// CapturerTrackSource::Create();
|
|
||||||
rtc::scoped_refptr<MyCapturer> video_device = new rtc::RefCountedObject<MyCapturer>();
|
rtc::scoped_refptr<MyCapturer> video_device = new rtc::RefCountedObject<MyCapturer>();
|
||||||
if (video_device) {
|
if (video_device) {
|
||||||
video_device->startCapturer();
|
video_device->startCapturer();
|
||||||
|
@ -154,7 +161,6 @@ int WebrtcHanlder::AddTrack()
|
||||||
RTC_LOG(LS_ERROR) << "OpenVideoCaptureDevice failed";
|
RTC_LOG(LS_ERROR) << "OpenVideoCaptureDevice failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
webrtc::DataChannelInit config;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,6 +171,7 @@ void WebrtcHanlder::SetSignalClient(SignalClient * cli)
|
||||||
|
|
||||||
void WebrtcHanlder::CreateOffer()
|
void WebrtcHanlder::CreateOffer()
|
||||||
{
|
{
|
||||||
|
qDebug()<<"CreateOffer";
|
||||||
if(nullptr != m_peer_connection_){
|
if(nullptr != m_peer_connection_){
|
||||||
m_peer_connection_->CreateOffer(this,
|
m_peer_connection_->CreateOffer(this,
|
||||||
webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
|
webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
|
||||||
|
@ -190,10 +197,18 @@ void WebrtcHanlder::SetRemoteSdp(QString sdp)
|
||||||
qDebug()<<"recv" << sdp;
|
qDebug()<<"recv" << sdp;
|
||||||
auto doc = QJsonDocument::fromJson(sdp.toUtf8());
|
auto doc = QJsonDocument::fromJson(sdp.toUtf8());
|
||||||
auto obj = doc.object();
|
auto obj = doc.object();
|
||||||
|
auto ssdp = obj["sdp"].toString();
|
||||||
|
auto type = obj["type"].toString();
|
||||||
|
webrtc::SdpType ktype;
|
||||||
webrtc::SdpParseError error;
|
webrtc::SdpParseError error;
|
||||||
|
if(type == "answer"){
|
||||||
|
ktype = webrtc::SdpType::kAnswer;
|
||||||
|
}
|
||||||
|
if(type == "offer"){
|
||||||
|
ktype = webrtc::SdpType::kOffer;
|
||||||
|
}
|
||||||
std::unique_ptr<webrtc::SessionDescriptionInterface> session_description =
|
std::unique_ptr<webrtc::SessionDescriptionInterface> session_description =
|
||||||
webrtc::CreateSessionDescription(webrtc::SdpType::kOffer, sdp.toStdString(), &error);
|
webrtc::CreateSessionDescription(ktype, ssdp.toStdString(), &error);
|
||||||
|
|
||||||
if (!session_description) {
|
if (!session_description) {
|
||||||
RTC_LOG(WARNING) << "Can't parse received session description message. "
|
RTC_LOG(WARNING) << "Can't parse received session description message. "
|
||||||
|
@ -210,8 +225,31 @@ void WebrtcHanlder::SetRemoteSdp(QString sdp)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebrtcHanlder::SetRemoteCandidate(QString scandidate)
|
||||||
|
{
|
||||||
|
qDebug()<<scandidate;
|
||||||
|
|
||||||
|
auto doc = QJsonDocument::fromJson(scandidate.toUtf8());
|
||||||
|
auto obj = doc.object();
|
||||||
|
auto ssdp = obj["candidate"].toString();
|
||||||
|
std::string sdp_mid,sdps;
|
||||||
|
int sdp_mlineindex = 0;
|
||||||
|
|
||||||
|
sdp_mlineindex = obj[kCandidateSdpMlineIndexName].toInt();
|
||||||
|
sdp_mid = obj[kCandidateSdpMlineIndexName].toString().toStdString();
|
||||||
|
sdps = obj[kCandidateSdpName].toString().toStdString();
|
||||||
|
webrtc::SdpParseError error;
|
||||||
|
std::unique_ptr<webrtc::IceCandidateInterface> candidate(
|
||||||
|
webrtc::CreateIceCandidate(sdp_mid, sdp_mlineindex, sdps, &error));
|
||||||
|
|
||||||
|
if(nullptr != m_peer_connection_){
|
||||||
|
m_peer_connection_->AddIceCandidate(candidate.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WebrtcHanlder::CreateAnwer()
|
void WebrtcHanlder::CreateAnwer()
|
||||||
{
|
{
|
||||||
|
qDebug()<<"create answer";
|
||||||
m_peer_connection_->CreateAnswer(
|
m_peer_connection_->CreateAnswer(
|
||||||
this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
|
this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
|
||||||
}
|
}
|
||||||
|
@ -225,18 +263,20 @@ void WebrtcHanlder::OnSignalingChange(webrtc::PeerConnectionInterface::Signaling
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebrtcHanlder::OnAddTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver, const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface> > &streams)
|
void WebrtcHanlder::OnAddTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
|
||||||
|
const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface> > &streams)
|
||||||
{
|
{
|
||||||
|
qDebug()<<"OnAddTrack";
|
||||||
|
RTC_LOG(INFO) << __FUNCTION__ << " " << receiver->id();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebrtcHanlder::OnRemoveTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver)
|
void WebrtcHanlder::OnRemoveTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver)
|
||||||
{
|
{
|
||||||
|
qDebug()<<"OnRemoveTrack";
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebrtcHanlder::OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface> channel) {
|
void WebrtcHanlder::OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface> channel) {
|
||||||
|
qDebug()<<"OnRemoveTrack";
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebrtcHanlder::OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state) {
|
void WebrtcHanlder::OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state) {
|
||||||
|
@ -246,14 +286,9 @@ void WebrtcHanlder::OnIceConnectionChange(webrtc::PeerConnectionInterface::IceCo
|
||||||
void WebrtcHanlder::OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state) {
|
void WebrtcHanlder::OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state) {
|
||||||
|
|
||||||
}
|
}
|
||||||
const char kCandidateSdpMidName[] = "sdpMid";
|
|
||||||
const char kCandidateSdpMlineIndexName[] = "sdpMLineIndex";
|
|
||||||
const char kCandidateSdpName[] = "candidate";
|
|
||||||
|
|
||||||
void WebrtcHanlder::OnIceCandidate(const webrtc::IceCandidateInterface *candidate)
|
void WebrtcHanlder::OnIceCandidate(const webrtc::IceCandidateInterface *candidate)
|
||||||
{
|
{
|
||||||
qDebug()<<"on condidate\r\n";
|
|
||||||
|
|
||||||
QJsonObject addr;
|
QJsonObject addr;
|
||||||
addr.insert(kCandidateSdpMidName, candidate->sdp_mid().c_str());
|
addr.insert(kCandidateSdpMidName, candidate->sdp_mid().c_str());
|
||||||
addr.insert(kCandidateSdpMlineIndexName,candidate->sdp_mline_index());
|
addr.insert(kCandidateSdpMlineIndexName,candidate->sdp_mline_index());
|
||||||
|
@ -263,7 +298,8 @@ void WebrtcHanlder::OnIceCandidate(const webrtc::IceCandidateInterface *candidat
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addr.insert(kCandidateSdpName,sdp.c_str());
|
addr.insert(kCandidateSdpName,sdp.c_str());
|
||||||
qDebug()<<"condidate:\r\n"<< QString(QJsonDocument(addr).toJson());
|
qDebug()<<"OnIceCandidate:\r\n"<< QString(QJsonDocument(addr).toJson());
|
||||||
|
this->mClient->SendICECandidate(mRemoteName,QString(QJsonDocument(addr).toJson()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebrtcHanlder::OnIceConnectionReceivingChange(bool receiving) {
|
void WebrtcHanlder::OnIceConnectionReceivingChange(bool receiving) {
|
||||||
|
@ -333,22 +369,41 @@ void MainWindow::signal_response(int type,QJsonObject data)
|
||||||
qDebug()<<type<<data;
|
qDebug()<<type<<data;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 2004:
|
case 2004:
|
||||||
this->mModel->clear();
|
{
|
||||||
for (auto itr = data.begin();itr != data.end();itr++){
|
qDebug()<<"2004";
|
||||||
auto item = new QStandardItem(itr.key());
|
this->mModel->clear();
|
||||||
item->setEditable(false);
|
for (auto itr = data.begin();itr != data.end();itr++){
|
||||||
mModel->appendRow(item);
|
auto item = new QStandardItem(itr.key());
|
||||||
|
item->setEditable(false);
|
||||||
|
mModel->appendRow(item);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
case 2005:
|
||||||
case 2005:
|
{
|
||||||
auto sdp = data["sdp"].toString();
|
qDebug()<<"2005";
|
||||||
auto remote_name = data["remote_name"].toString();
|
auto sdp = data["sdp"].toString();
|
||||||
|
auto remote_name = data["remote_name"].toString();
|
||||||
|
mHandler->SetRemotePeerName(remote_name);
|
||||||
|
|
||||||
this->mHandler.get()->SetRemoteSdp(sdp);
|
this->mHandler.get()->SetRemoteSdp(sdp);
|
||||||
mRemoteName = remote_name;
|
mRemoteName = remote_name;
|
||||||
if(!mCalling)
|
if(!mCalling)
|
||||||
mHandler->CreateAnwer();
|
mHandler->CreateAnwer();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case 2006:
|
||||||
|
{
|
||||||
|
qDebug()<<"2006";
|
||||||
|
auto candidate = data["candidate"].toString();
|
||||||
|
auto remote_names = data["remote_name"].toString();
|
||||||
|
mHandler->SetRemotePeerName(remote_names);
|
||||||
|
this->mHandler.get()->SetRemoteCandidate(candidate);
|
||||||
|
mRemoteName = remote_names;
|
||||||
|
qDebug()<<"recv candidate"<<candidate;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,6 +416,7 @@ void MainWindow::itemClicked(QModelIndex index)
|
||||||
//mSignalClient->SendSDPOffer();
|
//mSignalClient->SendSDPOffer();
|
||||||
qDebug()<<mModel->item(index.row())->text();
|
qDebug()<<mModel->item(index.row())->text();
|
||||||
mRemoteName = mModel->item(index.row())->text();
|
mRemoteName = mModel->item(index.row())->text();
|
||||||
|
mHandler->SetRemotePeerName(mRemoteName);
|
||||||
mCalling = true;
|
mCalling = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,20 +35,69 @@ namespace Ui { class MainWindow; }
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
class VideoRenderer : public rtc::VideoSinkInterface<webrtc::VideoFrame> {
|
||||||
|
|
||||||
|
public:
|
||||||
|
VideoRenderer(HWND wnd,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
webrtc::VideoTrackInterface* track_to_render);
|
||||||
|
virtual ~VideoRenderer();
|
||||||
|
|
||||||
|
void Lock() { ::EnterCriticalSection(&buffer_lock_); }
|
||||||
|
|
||||||
|
void Unlock() { ::LeaveCriticalSection(&buffer_lock_); }
|
||||||
|
|
||||||
|
// VideoSinkInterface implementation
|
||||||
|
void OnFrame(const webrtc::VideoFrame& frame) override;
|
||||||
|
|
||||||
|
const BITMAPINFO& bmi() const { return bmi_; }
|
||||||
|
const uint8_t* image() const { return image_.get(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void SetSize(int width, int height);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SET_SIZE,
|
||||||
|
RENDER_FRAME,
|
||||||
|
};
|
||||||
|
|
||||||
|
HWND wnd_;
|
||||||
|
BITMAPINFO bmi_;
|
||||||
|
std::unique_ptr<uint8_t[]> image_;
|
||||||
|
CRITICAL_SECTION buffer_lock_;
|
||||||
|
rtc::scoped_refptr<webrtc::VideoTrackInterface> rendered_track_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A little helper class to make sure we always to proper locking and
|
||||||
|
// unlocking when working with VideoRenderer buffers.
|
||||||
|
template <typename T>
|
||||||
|
class AutoLock {
|
||||||
|
public:
|
||||||
|
explicit AutoLock(T* obj) : obj_(obj) { obj_->Lock(); }
|
||||||
|
~AutoLock() { obj_->Unlock(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
T* obj_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class WebrtcHanlder :public QObject,
|
class WebrtcHanlder :public QObject,
|
||||||
public webrtc::PeerConnectionObserver,
|
public webrtc::PeerConnectionObserver,
|
||||||
public webrtc::CreateSessionDescriptionObserver{
|
public webrtc::CreateSessionDescriptionObserver{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void OnOfferSdp(QString);
|
void OnOfferSdp(QString);
|
||||||
void OnAnswerSdp(QString);
|
void OnAnswerSdp(QString);
|
||||||
public:
|
public:
|
||||||
|
void SetRemotePeerName(QString);
|
||||||
int InitWebrtc();
|
int InitWebrtc();
|
||||||
int AddTrack();
|
int AddTrack();
|
||||||
void SetSignalClient(SignalClient *);
|
void SetSignalClient(SignalClient *);
|
||||||
void CreateOffer();
|
void CreateOffer();
|
||||||
void SetRemoteSdp(QString);
|
void SetRemoteSdp(QString);
|
||||||
|
void SetRemoteCandidate(QString);
|
||||||
|
|
||||||
void CreateAnwer();
|
void CreateAnwer();
|
||||||
protected:
|
protected:
|
||||||
~WebrtcHanlder();
|
~WebrtcHanlder();
|
||||||
|
@ -80,6 +129,7 @@ private:
|
||||||
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
|
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
|
||||||
m_peer_connection_factory_;
|
m_peer_connection_factory_;
|
||||||
SignalClient *mClient;
|
SignalClient *mClient;
|
||||||
|
QString mRemoteName;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,19 @@ void SignalClient::SendSDPOffer(QString peer, QString sdp)
|
||||||
|
|
||||||
qDebug()<<QString(QJsonDocument(obj).toJson());
|
qDebug()<<QString(QJsonDocument(obj).toJson());
|
||||||
}
|
}
|
||||||
|
#define REQ_CANDIDATE 1006
|
||||||
|
void SignalClient::SendICECandidate(QString peer, QString candidate)
|
||||||
|
{
|
||||||
|
QJsonObject obj;
|
||||||
|
QJsonObject data;
|
||||||
|
data.insert("candidate",candidate);
|
||||||
|
data.insert("name",m_peer_name);
|
||||||
|
data.insert("remote_name",peer);
|
||||||
|
obj.insert("type",REQ_CANDIDATE);
|
||||||
|
obj.insert("data",data);
|
||||||
|
qDebug()<<QString(QJsonDocument(obj).toJson());
|
||||||
|
m_webSocket.sendTextMessage(QString(QJsonDocument(obj).toJson()));
|
||||||
|
}
|
||||||
|
|
||||||
QString SignalClient::PeerName()
|
QString SignalClient::PeerName()
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,6 +26,8 @@ public:
|
||||||
bool Connected();
|
bool Connected();
|
||||||
void SetURL(QString);
|
void SetURL(QString);
|
||||||
void SendSDPOffer(QString peer,QString sdp);
|
void SendSDPOffer(QString peer,QString sdp);
|
||||||
|
void SendICECandidate(QString peer,QString sdp);
|
||||||
|
|
||||||
QString PeerName();
|
QString PeerName();
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void onConnected();
|
void onConnected();
|
||||||
|
|
Loading…
Reference in New Issue