Skip to content

Commit 9842026

Browse files
authored
Add test for adding and removing tracks in a loop (#59)
1 parent fdbbf6f commit 9842026

File tree

3 files changed

+79
-7
lines changed

3 files changed

+79
-7
lines changed

guides/mastering_transceivers.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ There're also a couple of other notes worth mentioning before moving forward.
2929
When adding a transceiver, it is created with `sendrecv` direction by default.
3030
When applying a remote offer that contains new m-lines, a new transceiver is created with the `recvonly` direction,
3131
even when the offerer only wants to receive media.
32-
This direction can later be changed with `addTrack`, which sends media data on the first available transceiver,
33-
provided this transceiver wasn't initially created by `addTransceiver`.
32+
The `direction` can later be changed by `addTrack` or `removeTrack`.
33+
Specifically, `addTrack` sends media on the first available transceiver, provided this transceiver wasn't initially created by `addTransceiver`.
3434
See [Stealing Transceiver](#stealing-transceiver).
3535
* `currentDirection` is a direction negotiated between the local and remote side,
3636
and it changes when applying local or remote SDP.
@@ -438,8 +438,8 @@ the peer connection will attempt to find a transceiver it can use to associate w
438438
This is provided that the transceiver was created with `addTrack` and not with `addTransceiver`.
439439
But why is this so?
440440
The assumption is that when the user calls `addTrack` (and thereby creates a transceiver under the hood),
441-
they might not pay attention to how this track is sent to the other side.
442-
However, this is not the case when a user explicitly creates a transceiver with `addTransceiver`.
441+
they don't pay attention to how this track is sent to the other side.
442+
However, this is not the case when the user explicitly creates a transceiver with `addTransceiver`.
443443

444444
<!-- tabs-open -->
445445

lib/ex_webrtc/peer_connection.ex

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,6 @@ defmodule ExWebRTC.PeerConnection do
217217

218218
@impl true
219219
def handle_call({:create_offer, options}, _from, state) do
220-
# TODO: handle subsequent offers
221-
222220
if Keyword.get(options, :ice_restart, false) do
223221
:ok = state.ice_transport.restart(state.ice_pid)
224222
end

test/ex_webrtc/renegotiation_test.exs

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ defmodule ExWebRTC.RenegotiationTest do
33

44
import ExWebRTC.Support.TestUtils
55

6-
alias ExWebRTC.{PeerConnection, RTPTransceiver}
6+
alias ExWebRTC.{MediaStreamTrack, PeerConnection, RTPTransceiver}
77

88
test "stop two and add one with different kind" do
99
# 1. add audio and video transceiver
@@ -152,6 +152,80 @@ defmodule ExWebRTC.RenegotiationTest do
152152
assert tr3.id != pc2_tr1.id
153153
end
154154

155+
test "add and remove tracks in a loop" do
156+
# Simulate the most basic videoconference scenario
157+
# where both sides join with audio and video,
158+
# start screensharing and remove screensharing.
159+
# pc1 adds audio and video tracks
160+
# pc2 adds audio and video tracks
161+
# pc1 adds screenshare track
162+
# pc1 removes screenshare track
163+
# pc2 adds screenshare track
164+
# pc2 removes screenshare track
165+
166+
{:ok, pc1} = PeerConnection.start_link()
167+
{:ok, pc2} = PeerConnection.start_link()
168+
169+
pc1_audio_track = MediaStreamTrack.new(:audio)
170+
pc1_video_track = MediaStreamTrack.new(:video)
171+
172+
pc2_audio_track = MediaStreamTrack.new(:audio)
173+
pc2_video_track = MediaStreamTrack.new(:video)
174+
175+
{:ok, _} = PeerConnection.add_track(pc1, pc1_audio_track)
176+
{:ok, _} = PeerConnection.add_track(pc1, pc1_video_track)
177+
178+
:ok = negotiate(pc1, pc2)
179+
180+
{:ok, _} = PeerConnection.add_track(pc2, pc2_audio_track)
181+
{:ok, _} = PeerConnection.add_track(pc2, pc2_video_track)
182+
183+
:ok = negotiate(pc2, pc1)
184+
185+
assert [%{kind: :audio}, %{kind: :video}] = PeerConnection.get_transceivers(pc1)
186+
187+
assert [%{kind: :audio}, %{kind: :video}] = PeerConnection.get_transceivers(pc2)
188+
189+
for _i <- 0..5 do
190+
add_and_remove_screenshare(pc1, pc2)
191+
192+
assert [
193+
%{kind: :audio, direction: :sendrecv, current_direction: :sendrecv},
194+
%{kind: :video, direction: :sendrecv, current_direction: :sendrecv},
195+
%{kind: :video, direction: :recvonly, current_direction: :inactive}
196+
] =
197+
PeerConnection.get_transceivers(pc1)
198+
199+
assert [
200+
%{kind: :audio, direction: :sendrecv, current_direction: :sendrecv},
201+
%{kind: :video, direction: :sendrecv, current_direction: :sendrecv},
202+
%{kind: :video, direction: :recvonly, current_direction: :inactive}
203+
] =
204+
PeerConnection.get_transceivers(pc2)
205+
end
206+
end
207+
208+
defp add_and_remove_screenshare(pc1, pc2) do
209+
pc1_screenshare_track = MediaStreamTrack.new(:video)
210+
pc2_screenshare_track = MediaStreamTrack.new(:video)
211+
212+
{:ok, pc1_screenshare_sender} = PeerConnection.add_track(pc1, pc1_screenshare_track)
213+
214+
:ok = negotiate(pc1, pc2)
215+
216+
:ok = PeerConnection.remove_track(pc1, pc1_screenshare_sender.id)
217+
218+
:ok = negotiate(pc1, pc2)
219+
220+
{:ok, pc2_screenshare_sender} = PeerConnection.add_track(pc2, pc2_screenshare_track)
221+
222+
:ok = negotiate(pc2, pc1)
223+
224+
:ok = PeerConnection.remove_track(pc2, pc2_screenshare_sender.id)
225+
226+
:ok = negotiate(pc2, pc1)
227+
end
228+
155229
defp continue_negotiation(pc1, pc2, offer) do
156230
:ok = PeerConnection.set_local_description(pc1, offer)
157231
:ok = PeerConnection.set_remote_description(pc2, offer)

0 commit comments

Comments
 (0)