how to remove a track/replace during a call with the native api

2,188 views
Skip to first unread message

silviu.cpp

unread,
Dec 4, 2015, 4:13:24 AM12/4/15
to discuss-webrtc
Hello,

How you can remove the video track during a video call using the native c++ api ? I want to implement a feature to transform an audio call into a video one and vice versa.

I tried using :

rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track = stream->FindVideoTrack(kVideoLabel);
stream->RemoveTrack(video_track);

And then :

peer_connection_->CreateOffer(this, NULL);

But seems doesn't work.

I also tried using removing the stream and added it back and then on the OnRenegotiationNeeded calling:

void Conductor::OnRenegotiationNeeded()
{
    peer_connection_->CreateOffer(this, NULL);
}

And seems no luck.

Any idea what's the proper way to implement such a feature ?

Silviu

Taylor Brandstetter

unread,
Dec 4, 2015, 1:19:11 PM12/4/15
to discuss...@googlegroups.com
It looks like you're running into a recent issue: https://bugs.chromium.org/p/webrtc/issues/detail?id=5265

We plan to fix this soon. In the meantime, you can try using a slightly older version of the native library (prior to commit 10790).

Or for a workaround, you could try the following sequence:

1. RemoveStream
2. RemoveTrack
3. AddStream
4. CreateOffer

--

---
You received this message because you are subscribed to the Google Groups "discuss-webrtc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrt...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/discuss-webrtc/c785b10b-14a2-4f56-b2c7-e9920f680674%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Caragea Silviu

unread,
Dec 5, 2015, 4:07:11 AM12/5/15
to discuss-webrtc
Hello thanks for you reply,

I tested and seems is not working as expected. For example in the peerconnectionclient example I added the following function:

bool Conductor::MuteVideo(bool value)
{
    if (video_muted_ == value)
        return false;

    std::map<std::string, rtc::scoped_refptr<webrtc::MediaStreamInterface> >::const_iterator stream_it = active_streams_.find(kStreamLabel);

    if (stream_it == active_streams_.end())
        return false;

    rtc::scoped_refptr<webrtc::MediaStreamInterface> stream = stream_it->second;
    peer_connection_->RemoveStream(stream);

    if (value)
    {
        //do mute

        rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track = stream->FindVideoTrack(kVideoLabel);

        if (video_track)
        {
            main_wnd_->StopLocalRenderer();
            stream->RemoveTrack(video_track);
        }
    }
    else
    {
        rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
            peer_connection_factory_->CreateVideoTrack(kVideoLabel, peer_connection_factory_->CreateVideoSource(OpenVideoCaptureDevice(), NULL)));
        main_wnd_->StartLocalRenderer(video_track);
        stream->AddTrack(video_track);
    }

    if (!peer_connection_->AddStream(stream))
    {
        LOG(LS_ERROR) << "Remove stream to PeerConnection failed";
    }

    video_muted_ = value;
    peer_connection_->CreateOffer(this, NULL);
    return true;
}

When the function is called I can see the camera stopping and also the local stream disappearing but on the remote side the behavior is odd The on OnRemoveStream/OnAddStream is not called

I'm using the last webrtc version from master.

Silviu


Caragea Silviu

unread,
Dec 5, 2015, 4:17:41 AM12/5/15
to discuss-webrtc
I'm not sure if that signal should be triggered because in fact the stream was not removed. It's only changing to recvonly.
But when I resume I can see the stream being moved to sendrecv but seems that on remote not image is rendered.

I will try to investigate more

Silviu

Caragea Silviu

unread,
Dec 5, 2015, 5:36:04 AM12/5/15
to discuss-webrtc
Ok I found the problem,
On the remote side you need to remove the video track object and setup the new one.

Caragea Silviu

unread,
Dec 18, 2015, 2:59:33 PM12/18/15
to discuss-webrtc
Hello,

I see this is fixed now. So what's now the best way to change the video capture device . Still you need to renegotiate the sdp's ?

Silviu

On Fri, Dec 4, 2015 at 8:19 PM, 'Taylor Brandstetter' via discuss-webrtc <discuss...@googlegroups.com> wrote:

Taylor Brandstetter

unread,
Dec 18, 2015, 4:24:33 PM12/18/15
to discuss...@googlegroups.com
If you need to replace the current video MediaStreamTrack with a new one, currently you need to use removeTrack/addTrack and then do renegotiation.

However, eventually we'll support the RTCRtpSender.replaceTrack method (http://w3c.github.io/webrtc-pc/#rtcrtpsender-interface), which can be used to replace a track without renegotiation. You can track the development of that feature in Chrome here: https://www.chromestatus.com/feature/5347809238712320

It's already available to some extent in the native API. But it's currently under development, so use at your own risk.

Caragea Silviu

unread,
Dec 19, 2015, 6:35:04 PM12/19/15
to discuss-webrtc
Hello,

I did the following:


std::vector<talk_base::scoped_refptr<webrtc::RtpSenderInterface>> senders = peer_connection_->GetSenders();

    if (senders.empty())
        return;

    webrtc::VideoTrackInterface* video_track = CreateNewVideoTrack();
    ASSERT(video_track != NULL);

    for (std::vector<talk_base::scoped_refptr<webrtc::RtpSenderInterface>>::const_iterator it = senders.begin(); it < senders.end(); ++it)
    {
        if (it->get()->track()->id() == kVideoTrack)
        {
            bool result = it->get()->SetTrack(video_track);
            ASSERT(result);
            break;
        }
    }

On the remote side I can see frames from the new track. But the replaced camera is not stopped :) I see both started and closed when peer connection is closed.
Seems there is another place that keeps a reference to the old track .

Silviu


Reply all
Reply to author
Forward
0 new messages