freeswitch1993 2022-06-28 14:39 采纳率: 33.3%
浏览 61
已结题

请问mediasoup 可以推流 ,但是拉流是哪里有问题呢

请问mediasoup 可以推流 ,但是拉流是哪里有问题呢
uint32_t msgId()
{
static std::default_random_engine e;
static std::uniform_int_distribution u(std::numeric_limits::min(), std::numeric_limits::max());
return u(e);
}

MediaCtroller::MediaCtroller(QObject* parent):QObject(parent)
{
    _websocket = new vi::WebsocketTransport;
    _websocket->addObserverV2(this);

    _networkThread = rtc::Thread::CreateWithSocketServer();
    _signalingThread = rtc::Thread::Create();
    _workerThread = rtc::Thread::Create();

    _networkThread->SetName("network_thread", nullptr);
    _signalingThread->SetName("signaling_thread", nullptr);
    _workerThread->SetName("worker_thread", nullptr);

    if (!_networkThread->Start() || !_signalingThread->Start() || !_workerThread->Start()) {
        qDebug("thread start errored");
    }

    _adm = _workerThread->Invoke<rtc::scoped_refptr<webrtc::AudioDeviceModule>>(RTC_FROM_HERE, [this]() {
        _taskQueueFactory = webrtc::CreateDefaultTaskQueueFactory();
        return webrtc::AudioDeviceModule::Create(webrtc::AudioDeviceModule::kPlatformDefaultAudio, _taskQueueFactory.get());
        });



    this->_peerConnectionFactory = webrtc::CreatePeerConnectionFactory(this->_networkThread.get(),
        this->_workerThread.get(),
        this->_signalingThread.get(),
        _adm,
        webrtc::CreateBuiltinAudioEncoderFactory(),
        webrtc::CreateBuiltinAudioDecoderFactory(),
        webrtc::CreateBuiltinVideoEncoderFactory(),
        webrtc::CreateBuiltinVideoDecoderFactory(),
        nullptr /*audio_mixer*/,
        nullptr /*audio_processing*/);

    _peerConnectionOptions.reset(new mediasoupclient::PeerConnection::Options());
    _peerConnectionOptions->config.set_dscp(true);
    _peerConnectionOptions->factory = _peerConnectionFactory;

    _mediasoupDevice = std::make_shared<mediasoupclient::Device>();
}

MediaCtroller::~MediaCtroller()
{
}

void MediaCtroller::connectServer()
{
    _websocket->connect("wss://v3demo.mediasoup.org:4443/?roomId=123&peerId=1", "protoo");
}

void MediaCtroller::enableVideo(bool enable)
{
    if (!_mediasoupDevice->CanProduce("video")) {
        return;
    }

    if (!_sendTransport) {
        return;
    }

        
    if (!_capturerSource) {
        //std::unique_ptr<VcmCapturer> capturer = absl::WrapUnique(VcmCapturer::Create(1280, 720, 30, 0));
        //_capturerSource = rtc::make_ref_counted<WindowsCapturerTrackSource>(std::move(capturer), false);

        _capturerSource = WindowsCapturerTrackSource::Create(_signalingThread.get());
    }

    if (_capturerSource) {
        _capturerSource->startCapture();
        rtc::scoped_refptr<webrtc::VideoTrackInterface> track = _peerConnectionFactory->CreateVideoTrack("camera-track", _capturerSource);
        track->set_enabled(true);
        nlohmann::json codecOptions = nlohmann::json::object();
        codecOptions["videoGoogleStartBitrate"] = 1000;

        mediasoupclient::Producer* producer = _sendTransport->Produce(this,
            track,
            nullptr,
            &codecOptions,
            nullptr);
        _camProducer.reset(producer);

    }

}

void MediaCtroller::createNewConsumer(std::string msg)
{
    auto notification = nlohmann::json::parse(msg.begin(), msg.end());
    std::string kind = notification["data"]["kind"].get<std::string>();

    if (kind == "audio"){
        return;
    }
    else if (kind == "video")
    {
        std::string id = notification["data"]["id"].get<std::string>();
        std::string producerId = notification["data"]["producerId"].get<std::string>();
        std::string peerId = notification["data"]["peerId"].get<std::string>();

        nlohmann::json appData = notification["data"]["appData"];

        mediasoupclient::Consumer* consumer = _recvTransport->Consume(this,
            id,
            producerId,
            kind,
            &notification["data"]["rtpParameters"]
        );
        m_vTrack = static_cast<webrtc::VideoTrackInterface*>(consumer->GetTrack());
        rtc::VideoSinkWants wants;
        m_vTrack->AddOrUpdateSink(m_render, wants);
    }
    
}

void MediaCtroller::regiestRender(VideoRenderer* render)
{
    m_render = render;
}

void MediaCtroller::startMediasoup()
{
    std::thread* th = new std::thread([=] {
        
        nlohmann::json extendedRtpCapabilities;
    
        nlohmann::json request;

        //getRouterRtpCapabilities
        {
            request["id"] = msgId();
            request["method"] = "getRouterRtpCapabilities";
            request["request"] = true;
            _promise = std::unique_ptr<std::promise<std::string> >(new std::promise<std::string>);
            _websocket->send(request.dump());
            std::string res = _promise->get_future().get();

            auto response = nlohmann::json::parse(res.begin(), res.end());

            _mediasoupDevice->Load(response["data"]);
        }



        //CreateSendTransport
        {
            request["id"] = msgId();
            request["method"] = "createWebRtcTransport";
            request["request"] = true;
            request["data"] = {
                {"forceTcp", false},
                {"producing", true},
                {"consuming", false},
            };
            _promise = std::unique_ptr<std::promise<std::string> >(new std::promise<std::string>);
            _websocket->send(request.dump());
            std::string res = _promise->get_future().get();

            if (!_mediasoupDevice) {
                return;
            }
            auto response = nlohmann::json::parse(res.begin(), res.end());

            RTC_LOG(LS_INFO) << "wss recv " << res;
            std::string transportId = response["data"]["id"].get<std::string>();
            nlohmann::json iceParameters = response["data"]["iceParameters"];
            nlohmann::json iceCandidates = response["data"]["iceCandidates"];
            nlohmann::json dtlsParameters = response["data"]["dtlsParameters"];
            nlohmann::json sctpParameters = response["data"]["sctpParameters"];

            auto sendTransport = _mediasoupDevice->CreateSendTransport(this, transportId.c_str(), iceParameters, iceCandidates, dtlsParameters, sctpParameters, _peerConnectionOptions.get());
            _sendTransport.reset(sendTransport);
        
        }

        {
            //createRecvTransprot
            request["id"] = msgId();
            request["method"] = "createWebRtcTransport";
            request["request"] = true;
            request["data"] = {
                {"forceTcp", false},
                {"producing", false},
                {"consuming", true},
            };
            _promise = std::unique_ptr<std::promise<std::string> >(new std::promise<std::string>);
            _websocket->send(request.dump());
            auto res = _promise->get_future().get();
            auto response = nlohmann::json::parse(res.begin(), res.end());
            m_recvTransportId = response["data"]["id"].get<std::string>();
            nlohmann::json iceParameters = response["data"]["iceParameters"];
            nlohmann::json iceCandidates = response["data"]["iceCandidates"];
            nlohmann::json dtlsParameters = response["data"]["dtlsParameters"];
            nlohmann::json sctpParameters = response["data"]["sctpParameters"];

            auto recvTransport = _mediasoupDevice->CreateRecvTransport(this, m_recvTransportId.c_str(), iceParameters, iceCandidates, dtlsParameters, sctpParameters, _peerConnectionOptions.get());
            _recvTransport.reset(recvTransport);
        }

        //join
        {
            request["id"] = msgId();
            request["method"] = "join";
            request["request"] = true;
            request["data"] = {
                {"displayName", "xlc"},
                {"device", "device"},
            };

            request["data"]["rtpCapabilities"] = _mediasoupDevice->GetRtpCapabilities();

            _promise = std::unique_ptr<std::promise<std::string> >(new std::promise<std::string>);
            _websocket->send(request.dump());
            std::string res = _promise->get_future().get();

            auto response = nlohmann::json::parse(res.begin(), res.end());

        }

        //enableVideo();
        
    });

}
void MediaCtroller::onOpened()
{
    startMediasoup();
}
void MediaCtroller::onClosed()
{
}
void MediaCtroller::onFailed(int errorCode, const std::string& reason)
{
}
void MediaCtroller::onMessage(const std::string& msg)
{
    qDebug() << "onMessage:" << msg.c_str();
    auto notification = nlohmann::json::parse(msg.begin(), msg.end());
    if (notification.find("notification") != notification.end()){
        return;
    }
    else if (notification.find("request") != notification.end())
    {
        std::string method = notification["method"].get<std::string>();
        auto n = notification.dump();
        if ("newConsumer" == method){
            createNewConsumer(msg);
        
        }
        nlohmann::json response = {
            {"response", true},
            {"ok", true},
            {"id", notification["id"]},
            {"data", nlohmann::json()},
        };
        return;
    }
    try{
        _promise->set_value(msg);
    }
    catch (...)
    {    
    }

}
std::future<std::string> MediaCtroller::OnProduce(mediasoupclient::SendTransport* transport, const std::string& kind, nlohmann::json rtpParameters, const nlohmann::json& appData)
{
    nlohmann::json request;
    request["id"] = msgId();
    request["method"] = "produce";
    request["request"] = true;
    request["data"] = {
        {"transportId", transport->GetId()},
        {"kind", kind},
        {"rtpParameters", rtpParameters},
    };
    _promise = std::unique_ptr<std::promise<std::string> >(new std::promise<std::string>);
    _websocket->send(request.dump());
    return _promise->get_future();
}
std::future<std::string> MediaCtroller::OnProduceData(mediasoupclient::SendTransport* transport, const nlohmann::json& sctpStreamParameters, const std::string& label, const std::string& protocol, const nlohmann::json& appData)
{
    return std::future<std::string>();
}
void MediaCtroller::OnTransportClose(mediasoupclient::Producer* producer)
{
}
void MediaCtroller::OnTransportClose(mediasoupclient::Consumer* consumer)
{
}
std::future<void> MediaCtroller::OnConnect(mediasoupclient::Transport* transport, const nlohmann::json& dtlsParameters)
{
    //connectWebRtcTransport
    nlohmann::json request;
    request["id"] = msgId();
    request["method"] = "connectWebRtcTransport";
    request["request"] = true;
    request["data"] = {
        {"transportId", transport->GetId()},
        {"dtlsParameters", dtlsParameters}
    };
    _promise = std::unique_ptr<std::promise<std::string> >(new std::promise<std::string>);
    _websocket->send(request.dump());
    qDebug() << "OnConnect" << request.dump().c_str();
    //std::string res = _promise->get_future().get();

    _promise2 = std::unique_ptr<std::promise<void> >(new std::promise<void>);
    _promise2->set_value();
    return _promise2->get_future();
}
void MediaCtroller::OnConnectionStateChange(mediasoupclient::Transport* transport, const std::string& connectionState)
{
    qDebug() << "OnConnectionStateChange id:"<< transport->GetId().c_str() <<",state:"<< connectionState.c_str();
}

}

  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 7月6日
    • 创建了问题 6月28日

    悬赏问题

    • ¥300 寻抓云闪付tn组成网页付款链接
    • ¥15 请问Ubuntu要怎么安装chrome呀?
    • ¥15 视频编码 十六进制问题
    • ¥15 Xsheii7我安装这个文件的时候跳出来另一个文件已锁定文件的无一部分进程无法访问。这个该怎么解决
    • ¥15 unity terrain打包后地形错位,跟建筑不在同一个位置,怎么办
    • ¥15 FileNotFoundError 解决方案
    • ¥15 uniapp实现如下图的图表功能
    • ¥15 u-subsection如何修改相邻两个节点样式
    • ¥30 vs2010开发 WFP(windows filtering platform)
    • ¥15 服务端控制goose报文控制块的发布问题