Skip to content

Commit fdbbf6f

Browse files
authored
Improve API and API docs (#57)
1 parent 528c056 commit fdbbf6f

21 files changed

+81
-69
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[![CI](https://img.shields.io/github/actions/workflow/status/elixir-webrtc/ex_webrtc/ci.yml?logo=github&label=CI)](https://github.com/elixir-webrtc/ex_webrtc/actions/workflows/ci.yml)
44
[![codecov](https://codecov.io/gh/elixir-webrtc/ex_webrtc/graph/badge.svg?token=PdnXfnnmNw)](https://codecov.io/gh/elixir-webrtc/ex_webrtc)
55

6-
Implementation of WebRTC in Elixir.
6+
Implementation of [the W3C WebRTC API](https://www.w3.org/TR/webrtc/) in Elixir.
77

88
## Installation
99

examples/echo/example.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ defmodule Peer do
99
require Logger
1010

1111
alias ExWebRTC.{
12-
IceCandidate,
12+
ICECandidate,
1313
PeerConnection,
1414
MediaStreamTrack,
1515
SessionDescription,
@@ -129,7 +129,7 @@ defmodule Peer do
129129
defp handle_ws_message(%{"type" => "ice", "data" => data}, state) do
130130
Logger.info("Received remote ICE candidate: #{inspect(data)}")
131131

132-
candidate = %IceCandidate{
132+
candidate = %ICECandidate{
133133
candidate: data["candidate"],
134134
sdp_mid: data["sdpMid"],
135135
sdp_m_line_index: data["sdpMLineIndex"],

examples/save_to_file/example.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ defmodule Peer do
99
require Logger
1010

1111
alias ExWebRTC.{
12-
IceCandidate,
12+
ICECandidate,
1313
MediaStreamTrack,
1414
PeerConnection,
1515
SessionDescription,
@@ -123,7 +123,7 @@ defmodule Peer do
123123
defp handle_ws_message(%{"type" => "ice", "data" => data}, state) do
124124
Logger.info("Received remote ICE candidate: #{inspect(data)}")
125125

126-
candidate = %IceCandidate{
126+
candidate = %ICECandidate{
127127
candidate: data["candidate"],
128128
sdp_mid: data["sdpMid"],
129129
sdp_m_line_index: data["sdpMLineIndex"],

examples/send_from_file/example.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ defmodule Peer do
1111
import Bitwise
1212

1313
alias ExWebRTC.{
14-
IceCandidate,
14+
ICECandidate,
1515
MediaStreamTrack,
1616
Media.IVF,
1717
Media.Ogg,
@@ -220,7 +220,7 @@ defmodule Peer do
220220
defp handle_ws_message(%{"type" => "ice", "data" => data}, state) do
221221
Logger.info("Received remote ICE candidate: #{inspect(data)}")
222222

223-
candidate = %IceCandidate{
223+
candidate = %ICECandidate{
224224
candidate: data["candidate"],
225225
sdp_mid: data["sdpMid"],
226226
sdp_m_line_index: data["sdpMLineIndex"],

lib/ex_webrtc/dtls_transport.ex

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
defmodule ExWebRTC.DTLSTransport do
2-
@moduledoc """
3-
DTLSTransport
4-
"""
2+
@moduledoc false
53

64
use GenServer
75

@@ -11,25 +9,30 @@ defmodule ExWebRTC.DTLSTransport do
119

1210
@type dtls_transport() :: pid()
1311

14-
# Messages sent by the DTLSTransport
15-
@typedoc false
16-
@type signal() :: {:dtls_transport, pid(), state_change() | rtp_data()}
12+
@typedoc """
13+
Messages sent by the DTLSTransport.
14+
"""
15+
@type signal() :: {:dtls_transport, pid(), state_change() | rtp_rtcp()}
1716

18-
# Message sent when DTLSTransport changes its state
19-
@typedoc false
17+
@typedoc """
18+
Message sent when DTLSTransport changes its state.
19+
"""
2020
@type state_change() :: {:state_change, dtls_state()}
2121

22-
# Message sent when a new RTP packet arrives.
23-
# Packet is decrypted.
24-
@typedoc false
25-
@type rtp_data() :: {:rtp_data, binary()}
22+
@typedoc """
23+
Message sent when a new RTP/RTCP packet arrives.
2624
27-
# Possible DTLSTransport states.
28-
# For the exact meaning, refer to the [WebRTC W3C, sec. 5.5.1](https://www.w3.org/TR/webrtc/#rtcdtlstransportstate-enum)
29-
@typedoc false
25+
Packet is decrypted.
26+
"""
27+
@type rtp_rtcp() :: {:rtp | :rtcp, binary()}
28+
29+
@typedoc """
30+
Possible DTLSTransport states.
31+
32+
For the exact meaning, refer to the [WebRTC W3C, sec. 5.5.1](https://www.w3.org/TR/webrtc/#rtcdtlstransportstate-enum)
33+
"""
3034
@type dtls_state() :: :new | :connecting | :connected | :closed | :failed
3135

32-
@doc false
3336
@spec start_link(ICETransport.t(), pid()) :: GenServer.on_start()
3437
def start_link(ice_transport \\ DefaultICETransport, ice_pid) do
3538
behaviour = ice_transport.__info__(:attributes)[:behaviour] || []
@@ -41,38 +44,32 @@ defmodule ExWebRTC.DTLSTransport do
4144
GenServer.start_link(__MODULE__, [ice_transport, ice_pid, self()])
4245
end
4346

44-
@doc false
4547
@spec set_ice_connected(dtls_transport()) :: :ok
4648
def set_ice_connected(dtls_transport) do
4749
GenServer.call(dtls_transport, :set_ice_connected)
4850
end
4951

50-
@doc false
5152
@spec get_fingerprint(dtls_transport()) :: binary()
5253
def get_fingerprint(dtls_transport) do
5354
GenServer.call(dtls_transport, :get_fingerprint)
5455
end
5556

56-
@doc false
5757
@spec start_dtls(dtls_transport(), :active | :passive, binary()) ::
5858
:ok | {:error, :already_started}
5959
def start_dtls(dtls_transport, mode, peer_fingerprint) do
6060
GenServer.call(dtls_transport, {:start_dtls, mode, peer_fingerprint})
6161
end
6262

63-
@doc false
6463
@spec send_rtp(dtls_transport(), binary()) :: :ok
6564
def send_rtp(dtls_transport, data) do
6665
GenServer.cast(dtls_transport, {:send_rtp, data})
6766
end
6867

69-
@doc false
7068
@spec send_rtcp(dtls_transport(), binary()) :: :ok
7169
def send_rtcp(dtls_transport, data) do
7270
GenServer.cast(dtls_transport, {:send_rtcp, data})
7371
end
7472

75-
@doc false
7673
@spec stop(dtls_transport()) :: :ok
7774
def stop(dtls_transport) do
7875
GenServer.stop(dtls_transport)

lib/ex_webrtc/ice_candidate.ex

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
defmodule ExWebRTC.IceCandidate do
1+
defmodule ExWebRTC.ICECandidate do
22
@moduledoc """
3-
ICE candidate
3+
Implementation of the [RTCIceCandidate](https://www.w3.org/TR/webrtc/#rtcicecandidate-interface).
44
"""
55

6-
# not exacly the same as W3 IceCandidate
76
@type t() :: %__MODULE__{
8-
candidate: term() | nil,
9-
sdp_mid: term() | nil,
10-
sdp_m_line_index: term() | nil,
11-
username_fragment: term() | nil
7+
candidate: binary(),
8+
sdp_mid: non_neg_integer() | nil,
9+
sdp_m_line_index: non_neg_integer() | nil,
10+
username_fragment: binary() | nil
1211
}
1312

1413
defstruct [:candidate, :username_fragment, :sdp_mid, :sdp_m_line_index]

lib/ex_webrtc/media_stream_track.ex

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
defmodule ExWebRTC.MediaStreamTrack do
22
@moduledoc """
3-
MediaStreamTrack
3+
Mimics [MediaStreamTrack](https://www.w3.org/TR/mediacapture-streams/#dom-mediastreamtrack).
44
"""
55

66
alias ExWebRTC.Utils
77

88
@type id() :: integer()
9+
@type kind() :: :audio | :video
910

1011
@type t() :: %__MODULE__{
11-
kind: :audio | :video,
12+
kind: kind(),
1213
id: id()
1314
}
1415

1516
@enforce_keys [:id, :kind]
1617
defstruct @enforce_keys
1718

18-
def new(kind) do
19+
@spec new(kind()) :: t()
20+
def new(kind) when kind in [:audio, :video] do
1921
%__MODULE__{kind: kind, id: Utils.generate_id()}
2022
end
2123
end

lib/ex_webrtc/peer_connection.ex

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
defmodule ExWebRTC.PeerConnection do
22
@moduledoc """
3-
PeerConnection
3+
Implementation of the [RTCPeerConnection](https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection).
44
"""
55

66
use GenServer
@@ -14,7 +14,7 @@ defmodule ExWebRTC.PeerConnection do
1414
alias ExWebRTC.{
1515
DefaultICETransport,
1616
DTLSTransport,
17-
IceCandidate,
17+
ICECandidate,
1818
MediaStreamTrack,
1919
RTPTransceiver,
2020
RTPSender,
@@ -36,7 +36,7 @@ defmodule ExWebRTC.PeerConnection do
3636
@type signal() ::
3737
{:ex_webrtc, pid(),
3838
:negotiation_needed
39-
| {:ice_candidate, IceCandidate.t()}
39+
| {:ice_candidate, ICECandidate.t()}
4040
| {:signaling_state_change, signaling_state()}
4141
| {:connection_state_change, connection_state()}
4242
| {:track, MediaStreamTrack.t()}
@@ -72,19 +72,19 @@ defmodule ExWebRTC.PeerConnection do
7272
end
7373

7474
@spec create_offer(peer_connection(), offer_options()) ::
75-
{:ok, SessionDescription.t()} | {:error, :TODO}
75+
{:ok, SessionDescription.t()} | {:error, :invalid_state}
7676
def create_offer(peer_connection, options \\ []) do
7777
GenServer.call(peer_connection, {:create_offer, options})
7878
end
7979

8080
@spec create_answer(peer_connection(), answer_options()) ::
81-
{:ok, SessionDescription.t()} | {:error, :TODO}
81+
{:ok, SessionDescription.t()} | {:error, :invalid_state}
8282
def create_answer(peer_connection, options \\ []) do
8383
GenServer.call(peer_connection, {:create_answer, options})
8484
end
8585

8686
@spec set_local_description(peer_connection(), SessionDescription.t()) ::
87-
:ok | {:error, :TODO}
87+
:ok | {:error, atom()}
8888
def set_local_description(peer_connection, description) do
8989
GenServer.call(peer_connection, {:set_local_description, description})
9090
end
@@ -95,7 +95,7 @@ defmodule ExWebRTC.PeerConnection do
9595
end
9696

9797
@spec set_remote_description(peer_connection(), SessionDescription.t()) ::
98-
:ok | {:error, :TODO}
98+
:ok | {:error, atom()}
9999
def set_remote_description(peer_connection, description) do
100100
GenServer.call(peer_connection, {:set_remote_description, description})
101101
end
@@ -105,8 +105,8 @@ defmodule ExWebRTC.PeerConnection do
105105
GenServer.call(peer_connection, :get_current_remote_description)
106106
end
107107

108-
@spec add_ice_candidate(peer_connection(), IceCandidate.t()) ::
109-
:ok | {:error, :TODO}
108+
@spec add_ice_candidate(peer_connection(), ICECandidate.t()) ::
109+
:ok | {:error, :no_remote_description}
110110
def add_ice_candidate(peer_connection, candidate) do
111111
GenServer.call(peer_connection, {:add_ice_candidate, candidate})
112112
end
@@ -157,16 +157,16 @@ defmodule ExWebRTC.PeerConnection do
157157
GenServer.call(peer_connection, {:remove_track, sender_id})
158158
end
159159

160-
@spec close(peer_connection()) :: :ok
161-
def close(peer_connection) do
162-
GenServer.stop(peer_connection)
163-
end
164-
165160
@spec send_rtp(peer_connection(), String.t(), ExRTP.Packet.t()) :: :ok
166161
def send_rtp(peer_connection, track_id, packet) do
167162
GenServer.cast(peer_connection, {:send_rtp, track_id, packet})
168163
end
169164

165+
@spec close(peer_connection()) :: :ok
166+
def close(peer_connection) do
167+
GenServer.stop(peer_connection)
168+
end
169+
170170
#### CALLBACKS ####
171171

172172
@impl true
@@ -617,7 +617,7 @@ defmodule ExWebRTC.PeerConnection do
617617

618618
@impl true
619619
def handle_info({:ex_ice, _from, {:new_candidate, candidate}}, state) do
620-
candidate = %IceCandidate{
620+
candidate = %ICECandidate{
621621
candidate: "candidate:" <> candidate,
622622
sdp_mid: 0,
623623
sdp_m_line_index: 0
@@ -795,7 +795,7 @@ defmodule ExWebRTC.PeerConnection do
795795

796796
defp apply_local_description(%SessionDescription{type: type}, _state)
797797
when type in [:rollback, :pranswer],
798-
do: {:error, :not_implemented}
798+
do: {:error, :"#{type}_not_implemented"}
799799

800800
defp apply_local_description(%SessionDescription{type: type, sdp: raw_sdp}, state) do
801801
with {:ok, next_sig_state} <- next_signaling_state(state.signaling_state, :local, type),
@@ -829,7 +829,7 @@ defmodule ExWebRTC.PeerConnection do
829829

830830
defp apply_remote_description(%SessionDescription{type: type}, _state)
831831
when type in [:rollback, :pranswer],
832-
do: {:error, :not_implemented}
832+
do: {:error, :"#{type}_not_implemented"}
833833

834834
defp apply_remote_description(%SessionDescription{type: type, sdp: raw_sdp}, state) do
835835
with {:ok, next_sig_state} <- next_signaling_state(state.signaling_state, :remote, type),

lib/ex_webrtc/peer_connection/configuration.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
defmodule ExWebRTC.PeerConnection.Configuration do
22
@moduledoc """
3-
PeerConnection configuration
3+
`ExWebRTC.PeerConnection` configuration.
44
"""
55

66
alias ExWebRTC.{RTPCodecParameters, SDPUtils}

lib/ex_webrtc/rtp/opus_depayloader.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
defmodule ExWebRTC.RTP.OpusDepayloader do
22
@moduledoc """
33
Decapsualtes Opus audio out of RTP packet.
4+
5+
Based on [RFC 7587: RTP Payload Format for the Opus Speech and Audio Codec](https://datatracker.ietf.org/doc/html/rfc7587).
46
"""
57

68
alias ExRTP.Packet

lib/ex_webrtc/rtp/opus_payloader.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
defmodule ExWebRTC.RTP.OpusPayloader do
22
@moduledoc """
33
Encapsulates Opus audio packet into an RTP packet.
4+
5+
Based on [RFC 7587: RTP Payload Format for the Opus Speech and Audio Codec](https://datatracker.ietf.org/doc/html/rfc7587).
46
"""
57

68
@doc """

lib/ex_webrtc/rtp/vp8_depayloader.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ defmodule ExWebRTC.RTP.VP8Depayloader do
22
@moduledoc """
33
Reassembles VP8 frames from RTP packets.
44
5-
Based on [RFC 7741: RTP Payload Format for VP8 Video](https://datatracker.ietf.org/doc/html/rfc7741)
5+
Based on [RFC 7741: RTP Payload Format for VP8 Video](https://datatracker.ietf.org/doc/html/rfc7741).
66
"""
77
require Logger
88

lib/ex_webrtc/rtp/vp8_payload.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ defmodule ExWebRTC.RTP.VP8Payload do
22
@moduledoc """
33
Defines VP8 payload structure stored in RTP packet payload.
44
5-
Based on [RFC 7741: RTP Payload Format for VP8 Video](https://datatracker.ietf.org/doc/html/rfc7741)
5+
Based on [RFC 7741: RTP Payload Format for VP8 Video](https://datatracker.ietf.org/doc/html/rfc7741).
66
"""
77

88
@type t() :: %__MODULE__{

lib/ex_webrtc/rtp/vp8_payloader.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ defmodule ExWebRTC.RTP.VP8Payloader do
22
@moduledoc """
33
Encapsulates VP8 video frames into RTP packets.
44
5-
Based on [RFC 7741: RTP Payload Format for VP8 Video](https://datatracker.ietf.org/doc/html/rfc7741)
5+
Based on [RFC 7741: RTP Payload Format for VP8 Video](https://datatracker.ietf.org/doc/html/rfc7741).
66
77
It does not support `X` bit right now, in particular it
88
does not pay attention to VP8 partion boundaries (see RFC 7741 sec. 4.4).

lib/ex_webrtc/rtp_codec_parameters.ex

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
defmodule ExWebRTC.RTPCodecParameters do
22
@moduledoc """
3-
RTPCodecParameters
3+
Implementation of the [RTCRtpCodecParameters](https://www.w3.org/TR/webrtc/#rtcrtpcodecparameters).
44
"""
55

6+
alias ExSDP.Attribute.{FMTP, RTPMapping, RTCPFeedback}
7+
68
@type t() :: %__MODULE__{
79
payload_type: non_neg_integer(),
810
mime_type: binary(),
@@ -15,6 +17,7 @@ defmodule ExWebRTC.RTPCodecParameters do
1517
@enforce_keys [:payload_type, :mime_type, :clock_rate]
1618
defstruct @enforce_keys ++ [:channels, :sdp_fmtp_line, rtcp_fbs: []]
1719

20+
@spec new(:audio | :video, RTPMapping.t(), FMTP.t() | nil, [RTCPFeedback.t()]) :: t()
1821
def new(type, rtp_mapping, fmtp, rtcp_fbs) do
1922
%__MODULE__{
2023
payload_type: rtp_mapping.payload_type,

0 commit comments

Comments
 (0)