Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The package can be installed by adding `membrane_webrtc_plugin` to your list of
```elixir
def deps do
[
{:membrane_webrtc_plugin, "~> 0.23.2"}
{:membrane_webrtc_plugin, "~> 0.23.3"}
]
end
```
Expand Down
62 changes: 61 additions & 1 deletion lib/membrane_webrtc/ex_webrtc/sink.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ defmodule Membrane.WebRTC.ExWebRTCSink do
def_input_pad :input,
accepted_format: Membrane.RTP,
availability: :on_request,
options: [kind: []]
options: [kind: [], codec: [default: nil]]

@max_rtp_timestamp 2 ** 32 - 1
@max_rtp_seq_num 2 ** 16 - 1
Expand Down Expand Up @@ -114,6 +114,66 @@ defmodule Membrane.WebRTC.ExWebRTCSink do
{[], state}
end

@impl true
def handle_start_of_stream(pad, ctx, state) do
case ctx.pads[pad].options do
%{kind: :audio} ->
:ok

%{kind: :video, codec: nil} ->
supported_video_codecs = get_transceiver(state, pad)

if length(supported_video_codecs) > 1 do
raise """
Cannot determine the video codec of the stream. It's necessary, as multiple video codecs \
have been negotiated. This error might be caused by passing `Membrane.RTP` to \
`Membrane.WebRTC.Sink` and allowing to negotiate more than one video codec at the same \
time.
Negotiated video codecs: #{inspect(supported_video_codecs, pretty: true)}
"""
end

:ok

%{kind: :video, codec: codec} ->
:ok = set_pc_sender_video_codec(state, pad, codec)
end

{[], state}
end

defp set_pc_sender_video_codec(state, pad, codec) when codec in [:vp8, :h264] do
mime_type = if codec == :vp8, do: "video/VP8", else: "video/H264"
transceiver = get_transceiver(state, pad)

if transceiver == nil do
raise """
Pad with `kind: :video` was linked, but #{inspect(PeerConnection)} doesn't have any video \
transceiver.
"""
end

selected_codec =
transceiver.codecs
|> Enum.find(&(&1.mime_type == mime_type))

if selected_codec == nil do
raise """
Cannot select codec #{inspect(codec)} with video transceiver #{inspect(transceiver)}
"""
end

:ok = PeerConnection.set_sender_codec(state.pc, transceiver.sender.id, selected_codec)
end

defp get_transceiver(state, pad) do
{track_id, _params} = state.input_tracks[pad]

state.pc
|> PeerConnection.get_transceivers()
|> Enum.find(&(&1.sender.track.id == track_id))
end

@impl true
def handle_buffer(pad, buffer, _ctx, state) do
state = send_buffer(pad, buffer, state)
Expand Down
2 changes: 1 addition & 1 deletion lib/membrane_webrtc/ex_webrtc/utils.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ defmodule Membrane.WebRTC.ExWebRTCUtils do
clock_rate: codec_clock_rate(:h264),
sdp_fmtp_line: %ExSDP.Attribute.FMTP{
pt: 96,
level_asymmetry_allowed: 1,
level_asymmetry_allowed: true,
packetization_mode: 1,
profile_level_id: 0x42E01F
}
Expand Down
22 changes: 14 additions & 8 deletions lib/membrane_webrtc/sink.ex
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ defmodule Membrane.WebRTC.Sink do
WebRTC peer.

After SDP messages exchange, #{inspect(__MODULE__)} will send a parent
notification `{:new_tracks, tracks}`, where every track in `tracks`
contains info about supported codecs.
notification `{:negotiated_video_codecs, codecs}` where `codecs` is
a list of supported codecs.
"""
],
ice_servers: [
Expand Down Expand Up @@ -143,7 +143,7 @@ defmodule Membrane.WebRTC.Sink do
kind == :audio ->
bin_input(pad_ref)
|> child({:rtp_opus_payloader, pid}, Membrane.RTP.Opus.Payloader)
|> via_in(pad_ref, options: [kind: :audio])
|> via_in(pad_ref, options: [kind: :audio, codec: :opus])
|> get_child(:webrtc)

kind == :video ->
Expand Down Expand Up @@ -172,17 +172,23 @@ defmodule Membrane.WebRTC.Sink do
_ctx,
state
) do
payloader =
codec =
case stream_format do
%H264{} -> %Membrane.RTP.H264.Payloader{max_payload_size: 1000}
%VP8{} -> Membrane.RTP.VP8.Payloader
%RemoteStream{content_format: VP8} -> Membrane.RTP.VP8.Payloader
%H264{} -> :h264
%VP8{} -> :vp8
%RemoteStream{content_format: VP8} -> :vp8
end

payloader =
case codec do
:h264 -> %Membrane.RTP.H264.Payloader{max_payload_size: 1000}
:vp8 -> Membrane.RTP.VP8.Payloader
end

spec =
get_child({:forwarding_filter, pad_ref})
|> child({:rtp_payloader, pad_ref}, payloader)
|> via_in(pad_ref, options: [kind: :video])
|> via_in(pad_ref, options: [kind: :video, codec: codec])
|> get_child(:webrtc)

{[spec: spec], state}
Expand Down
4 changes: 2 additions & 2 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule Membrane.WebRTC.Plugin.Mixfile do
use Mix.Project

@version "0.23.2"
@version "0.23.3"
@github_url "https://github.com/membraneframework/membrane_webrtc_plugin"

def project do
Expand Down Expand Up @@ -38,7 +38,7 @@ defmodule Membrane.WebRTC.Plugin.Mixfile do
defp deps do
[
{:membrane_core, "~> 1.1"},
{:ex_webrtc, "~> 0.4.0"},
{:ex_webrtc, "~> 0.8.0"},
{:corsica, "~> 2.0"},
{:membrane_rtp_plugin, "~> 0.30.0"},
{:membrane_rtp_h264_plugin, "~> 0.20.1"},
Expand Down
10 changes: 5 additions & 5 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@
"elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"},
"erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"},
"ex_doc": {:hex, :ex_doc, "0.36.1", "4197d034f93e0b89ec79fac56e226107824adcce8d2dd0a26f5ed3a95efc36b1", [:mix], [{:earmark_parser, "~> 1.4.42", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "d7d26a7cf965dacadcd48f9fa7b5953d7d0cfa3b44fa7a65514427da44eafd89"},
"ex_dtls": {:hex, :ex_dtls, "0.15.2", "6c8c0f8eb67525216551bd3e0322ab33c9d851d56ef3e065efab4fd277a8fbb9", [:mix], [{:unifex, "~> 1.0", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm", "6b852bc926bbdc9c1b9c4ecc6cfc73a89d4e106042802cefea2c1503072a9f2a"},
"ex_ice": {:hex, :ex_ice, "0.8.5", "65de6fa7516f767a8eef4145d66cbd1ed0af10999ecfd1e4c698e90d3c2b7f86", [:mix], [{:elixir_uuid, "~> 1.0", [hex: :elixir_uuid, repo: "hexpm", optional: false]}, {:ex_stun, "~> 0.2.0", [hex: :ex_stun, repo: "hexpm", optional: false]}, {:ex_turn, "~> 0.1.0", [hex: :ex_turn, repo: "hexpm", optional: false]}], "hexpm", "cc52cdf531288959dc8a4353602079188d88319fe1635ea1619fa612d31b8b3b"},
"ex_dtls": {:hex, :ex_dtls, "0.16.0", "3ae38025ccc77f6db573e2e391602fa9bbc02253c137d8d2d59469a66cbe806b", [:mix], [{:bundlex, "~> 1.5.3", [hex: :bundlex, repo: "hexpm", optional: false]}, {:unifex, "~> 1.0", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm", "2a4e30d74c6ddf95cc5b796423293c06a0da295454c3823819808ff031b4b361"},
"ex_ice": {:hex, :ex_ice, "0.9.3", "46700963acaba72737032500b6ee298a4effa7ad7189ab48887be5e9f4fe2107", [:mix], [{:elixir_uuid, "~> 1.0", [hex: :elixir_uuid, repo: "hexpm", optional: false]}, {:ex_stun, "~> 0.2.0", [hex: :ex_stun, repo: "hexpm", optional: false]}, {:ex_turn, "~> 0.2.0", [hex: :ex_turn, repo: "hexpm", optional: false]}], "hexpm", "4fd98d20a39ab70a62dd301c44e87437d479292c528ec7f21522ebfe0654b9cb"},
"ex_libsrtp": {:hex, :ex_libsrtp, "0.7.2", "211bd89c08026943ce71f3e2c0231795b99cee748808ed3ae7b97cd8d2450b6b", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.3", [hex: :bundlex, repo: "hexpm", optional: false]}, {:membrane_precompiled_dependency_provider, "~> 0.1.0", [hex: :membrane_precompiled_dependency_provider, repo: "hexpm", optional: false]}, {:unifex, "~> 1.1", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm", "2e20645d0d739a4ecdcf8d4810a0c198120c8a2f617f2b75b2e2e704d59f492a"},
"ex_rtcp": {:hex, :ex_rtcp, "0.4.0", "f9e515462a9581798ff6413583a25174cfd2101c94a2ebee871cca7639886f0a", [:mix], [], "hexpm", "28956602cf210d692fcdaf3f60ca49681634e1deb28ace41246aee61ee22dc3b"},
"ex_rtp": {:hex, :ex_rtp, "0.4.0", "1f1b5c1440a904706011e3afbb41741f5da309ce251cb986690ce9fd82636658", [:mix], [], "hexpm", "0f72d80d5953a62057270040f0f1ee6f955c08eeae82ac659c038001d7d5a790"},
"ex_sdp": {:hex, :ex_sdp, "1.1.1", "1a7b049491e5ec02dad9251c53d960835dc5631321ae978ec331831f3e4f6d5f", [:mix], [{:bunch, "~> 1.3", [hex: :bunch, repo: "hexpm", optional: false]}, {:elixir_uuid, "~> 1.2", [hex: :elixir_uuid, repo: "hexpm", optional: false]}], "hexpm", "1b13a72ac9c5c695b8824dbdffc671be8cbb4c0d1ccb4ff76a04a6826759f233"},
"ex_stun": {:hex, :ex_stun, "0.2.0", "feb1fc7db0356406655b2a617805e6c712b93308c8ea2bf0ba1197b1f0866deb", [:mix], [], "hexpm", "1e01ba8290082ccbf37acaa5190d1f69b51edd6de2026a8d6d51368b29d115d0"},
"ex_turn": {:hex, :ex_turn, "0.1.1", "e796b6c27aaf39e24ab9bad2044b426ed41ecc5ee8515087fe64f8ec9967e41b", [:mix], [{:ex_stun, "~> 0.2.0", [hex: :ex_stun, repo: "hexpm", optional: false]}], "hexpm", "832f2bba6f200a859e14cb8658b0932f841b0cf290491cca10cccf5367152547"},
"ex_webrtc": {:hex, :ex_webrtc, "0.4.1", "834054e38630f91a1c62e5d77ecf3394c0be64e9fd94be45e3021ea53baef6f9", [:mix], [{:crc, "~> 0.10", [hex: :crc, repo: "hexpm", optional: false]}, {:ex_dtls, "~> 0.15.0", [hex: :ex_dtls, repo: "hexpm", optional: false]}, {:ex_ice, "~> 0.8.0", [hex: :ex_ice, repo: "hexpm", optional: false]}, {:ex_libsrtp, "~> 0.7.1", [hex: :ex_libsrtp, repo: "hexpm", optional: false]}, {:ex_rtcp, "~> 0.4.0", [hex: :ex_rtcp, repo: "hexpm", optional: false]}, {:ex_rtp, "~> 0.4.0", [hex: :ex_rtp, repo: "hexpm", optional: false]}, {:ex_sdp, "~> 1.0", [hex: :ex_sdp, repo: "hexpm", optional: false]}], "hexpm", "be81984cf1624ccd1b50fa257558829db967764786e47ecc3da0cacbdcf1448d"},
"ex_turn": {:hex, :ex_turn, "0.2.0", "4e1f9b089e9a5ee44928d12370cc9ea7a89b84b2f6256832de65271212eb80de", [:mix], [{:ex_stun, "~> 0.2.0", [hex: :ex_stun, repo: "hexpm", optional: false]}], "hexpm", "08e884f0af2c4a147e3f8cd4ffe33e3452a256389f0956e55a8c4d75bf0e74cd"},
"ex_webrtc": {:hex, :ex_webrtc, "0.8.0", "109f408e9a4e687018b365cbb94de554f184d31bb42623e2f7a93de06575fd30", [:mix], [{:crc, "~> 0.10", [hex: :crc, repo: "hexpm", optional: false]}, {:ex_dtls, "~> 0.16.0", [hex: :ex_dtls, repo: "hexpm", optional: false]}, {:ex_ice, "~> 0.9.0", [hex: :ex_ice, repo: "hexpm", optional: false]}, {:ex_libsrtp, "~> 0.7.1", [hex: :ex_libsrtp, repo: "hexpm", optional: false]}, {:ex_rtcp, "~> 0.4.0", [hex: :ex_rtcp, repo: "hexpm", optional: false]}, {:ex_rtp, "~> 0.4.0", [hex: :ex_rtp, repo: "hexpm", optional: false]}, {:ex_sctp, "0.1.2", [hex: :ex_sctp, repo: "hexpm", optional: true]}, {:ex_sdp, "~> 1.0", [hex: :ex_sdp, repo: "hexpm", optional: false]}], "hexpm", "ce5c1b2792589975c7d59d56bad367dbe7d7fab35195e3edd85bbc72dd3bd621"},
"file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"},
"finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"},
"heap": {:hex, :heap, "2.0.2", "d98cb178286cfeb5edbcf17785e2d20af73ca57b5a2cf4af584118afbcf917eb", [:mix], [], "hexpm", "ba9ea2fe99eb4bcbd9a8a28eaf71cbcac449ca1d8e71731596aace9028c9d429"},
Expand Down Expand Up @@ -61,7 +61,7 @@
"membrane_vp8_format": {:hex, :membrane_vp8_format, "0.5.0", "a589c20bb9d97ddc9b717684d00cefc84e2500ce63a0c33c4b9618d9b2f9b2ea", [:mix], [], "hexpm", "d29e0dae4bebc6838e82e031c181fe626d168c687e4bc617c1d0772bdeed19d5"},
"membrane_vp9_format": {:hex, :membrane_vp9_format, "0.5.0", "c6a4f2cbfc39dba5d80ad8287162c52b5cf6488676bd64435c1ac957bd16e66f", [:mix], [], "hexpm", "68752d8cbe7270ec222fc84a7d1553499f0d8ff86ef9d9e89f8955d49e20278e"},
"mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"},
"mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"},
"mint": {:hex, :mint, "1.7.1", "113fdb2b2f3b59e47c7955971854641c61f378549d73e829e1768de90fc1abf1", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "fceba0a4d0f24301ddee3024ae116df1c3f4bb7a563a731f45fdfeb9d39a231b"},
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
"nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"},
"nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"},
Expand Down
1 change: 0 additions & 1 deletion test/membrane_webrtc/integration_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,6 @@ defmodule Membrane.WebRTC.IntegrationTest do

import Utils

@tag :dupa
@tag :tmp_dir
test "dynamically add new tracks", %{tmp_dir: tmp_dir} do
signaling = SignalingChannel.new()
Expand Down