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 .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
executor: machine_executor_amd64
steps:
- checkout
- run: docker compose run test
- run: docker compose -f docker-compose-integration.yaml run test
- codecov/upload

workflows:
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,17 @@ def deps do
end
```

## Testing

When calling `mix test` it will automatically start the Jellyfish container under the hood. But tests on CI are run with the use of docker-compose, to run it locally in the same way as on CI you can use command `mix integration_test`.

## Usage

Make API calls to Jellyfish (authentication required, for more information see [Jellyfish docs](https://jellyfish-dev.github.io/jellyfish-docs/getting_started/authentication))
and receive server notifications:

```elixir
# start process responsible for receiving notifications
{:ok, _pid} = Jellyfish.Notifier.start(server_address: "address-of-your-server.com", server_api_key: "your-jellyfish-token")
{:ok, _pid} = Jellyfish.Notifier.start(server_address: "localhost:5002", server_api_key: "your-jellyfish-token")

# create HTTP client instance
client = Jellyfish.Client.new(server_address: "address-of-your-server.com", server_api_key: "your-jellyfish-token")
client = Jellyfish.Client.new(server_address: "localhost:5002", server_api_key: "your-jellyfish-token")

# Create room
{:ok, %Jellyfish.Room{id: room_id}} = Jellyfish.Room.create(client, max_peers: 10)
Expand All @@ -49,7 +45,7 @@ room_id
{:ok, %Jellyfish.Peer{id: peer_id}, peer_token} = Jellyfish.Room.add_peer(client, room_id, Jellyfish.Peer.WebRTC)

receive do
{:jellyfish, %Jellyfish.Server.ControlMessage.PeerConnected{room_id: ^room_id, peer_id: ^peer_id} ->
{:jellyfish, %Jellyfish.ServerMessage.PeerConnected{room_id: ^room_id, peer_id: ^peer_id}} ->
# handle the notification
end

Expand All @@ -59,6 +55,10 @@ end

List of structs representing server notifications can be found in [generated Protobuf file](lib/protos/jellyfish/server_notifications.pb.ex).

## Testing

When calling `mix test` it will automatically start the Jellyfish container under the hood. But tests on CI are run with the use of docker-compose, to run it locally in the same way as on CI you can use command `mix integration_test`.

## Copyright and License

Copyright 2023, [Software Mansion](https://swmansion.com/?utm_source=git&utm_medium=readme&utm_campaign=jellyfish)
Expand Down
2 changes: 1 addition & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Config

config :jellyfish_server_sdk,
divo: "docker-compose.yaml",
divo: "docker-compose-integration.yaml",
divo_wait: [dwell: 1_500, max_tries: 50]

import_config "#{config_env()}.exs"
17 changes: 6 additions & 11 deletions docker-compose.yaml → docker-compose-dev.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
version: "3"

services:
test:
image: membraneframeworklabs/docker_membrane:latest
command: bash -c "cd app/ && mix deps.get && mix coveralls.json --warnings-as-errors"
environment:
- MIX_ENV=integration_test
volumes:
- .:/app
links:
- jellyfish
jellyfish:
image: "ghcr.io/jellyfish-dev/jellyfish:${TAG:-edge}"
container_name: jellyfish
Expand All @@ -18,16 +9,20 @@ services:
test: >
curl --fail -H "authorization: Bearer development" http://localhost:5002/room || exit 1
interval: 3s
retries: 30
retries: 2
timeout: 2s
start_period: 30s
environment:
VIRTUAL_HOST: "localhost"
USE_INTEGRATED_TURN: "true"
INTEGRATED_TURN_IP: "${INTEGRATED_TURN_IP:-127.0.0.1}"
INTEGRATED_TURN_PORT_RANGE: "50000-65355"
INTEGRATED_TURN_LISTEN_IP: "0.0.0.0"
INTEGRATED_TURN_PORT_RANGE: "50000-50050"
INTEGRATED_TCP_TURN_PORT: "49999"
SERVER_API_TOKEN: "development"
PORT: 5002
SECRET_KEY_BASE: "super-secret-key"
ports:
- "5002:5002"
- "49999:49999"
- "50000-50050:50000-50050/udp"
25 changes: 25 additions & 0 deletions docker-compose-integration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
version: "3"

services:
test:
image: hexpm/elixir:1.14.4-erlang-25.3.2-alpine-3.16.5
command: sh -c "cd app/ && apk add git && mix local.hex --force && mix local.rebar --force && mix deps.get && mix coveralls.json --warnings-as-errors"
environment:
- MIX_ENV=integration_test
volumes:
- .:/app
networks:
- network
depends_on:
- jellyfish

jellyfish:
extends:
file: docker-compose-dev.yaml
service: jellyfish
networks:
- network

networks:
network:
driver: bridge
6 changes: 3 additions & 3 deletions lib/jellyfish/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@ defmodule Jellyfish.Client do
@typedoc """
Options needed to open connection to Jellyfish server.

* `:server_address` - url or IP address of the Jellyfish server instance.
* `:server_address` - address of the Jellyfish server instance.
* `:server_api_token` - token used for authorizing HTTP requests and WebSocket connection.
It's the same token as the one configured in Jellyfish.
* `:secure?` - if `true`, use HTTPS and WSS instead of HTTP and WS, `false` by default.

When an option is not explicily passed, value set in `config.exs` is used:
```
# in config.exs
config :jellyfish_server_sdk,
server_address: "you-jellyfish-server-address.com",
config :jellyfish_server_sdk,
server_address: "localhost:5002",
server_api_token: "your-jellyfish-token",
secure?: true
```
Expand Down
37 changes: 10 additions & 27 deletions lib/jellyfish/component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule Jellyfish.Component do
Defines `t:Jellyfish.Component.t/0`.

Component is a server-side entity that can publish, subscribe to and process tracks.
For more information refer to [Jellyfish documentation](https://www.membrane.stream)
For more information refer to [Jellyfish documentation](https://jellyfish-dev.github.io/jellyfish-docs/introduction/basic_concepts).
"""

alias Jellyfish.Component.{HLS, RTSP}
Expand All @@ -22,23 +22,14 @@ defmodule Jellyfish.Component do

@typedoc """
Type of the component.

For more information refer to [Jellyfish documentation](https://jellyfish-dev.github.io/jellyfish-docs/).
"""
@type type :: :hls | :rtsp
@type type :: HLS | RTSP

@typedoc """
Component-specific options.

For the list of available options, refer to [Jellyfish documentation](https://jellyfish-dev.github.io/jellyfish-docs/).
"""
@type options :: HLS.t() | RTSP.t()

@typedoc """
Component options module.
"""
@type options_module :: HLS | RTSP

@typedoc """
Stores information about the component.
"""
Expand All @@ -47,8 +38,6 @@ defmodule Jellyfish.Component do
type: type()
}

@valid_type_strings ["hls", "rtsp"]

@doc false
@spec from_json(map()) :: t()
def from_json(response) do
Expand All @@ -68,20 +57,14 @@ defmodule Jellyfish.Component do
end

@doc false
@spec type_from_options(struct()) :: type()
def type_from_options(component) do
case component do
%HLS{} -> :hls
%RTSP{} -> :rtsp
_other -> raise "Invalid component options struct"
end
end
@spec type_from_string(String.t()) :: type()
def type_from_string("hls"), do: HLS
def type_from_string("rtsp"), do: RTSP
def type_from_string(_type), do: raise("Invalid component type string")

@doc false
@spec type_from_string(String.t()) :: type()
def type_from_string(string) do
if string in @valid_type_strings,
do: String.to_atom(string),
else: raise("Invalid component type string")
end
@spec string_from_options(struct()) :: String.t()
def string_from_options(%HLS{}), do: "hls"
def string_from_options(%RTSP{}), do: "rtsp"
def string_from_options(_struct), do: raise("Invalid component options struct")
end
3 changes: 2 additions & 1 deletion lib/jellyfish/component/hls.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ defmodule Jellyfish.Component.HLS do
@moduledoc """
Options for the HLS component.

For the description of these options refer to [Jellyfish documentation](https://jellyfish-dev.github.io/jellyfish-docs/getting_started/components/hls)
For the description of these options refer to [Jellyfish
documentation](https://jellyfish-dev.github.io/jellyfish-docs/getting_started/components/hls).
"""

@enforce_keys []
Expand Down
3 changes: 2 additions & 1 deletion lib/jellyfish/component/rtsp.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ defmodule Jellyfish.Component.RTSP do
@moduledoc """
Options for the RTSP component.

For the description of these options refer to [Jellyfish documentation](https://jellyfish-dev.github.io/jellyfish-docs/getting_started/components/rtsp)
For the description of these options refer to [Jellyfish
documentation](https://jellyfish-dev.github.io/jellyfish-docs/getting_started/components/rtsp).
"""

@enforce_keys [:source_uri]
Expand Down
15 changes: 8 additions & 7 deletions lib/jellyfish/notifier.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ defmodule Jellyfish.Notifier do
WebSocket connection and receiving notifications form Jellyfish server.

```
iex> {:ok, pid} = Jellyfish.Notifier.start(server_address: "address-of-jellyfish-server.com", server_api_token: "your-jellyfish-token")
iex> {:ok, pid} = Jellyfish.Notifier.start(server_address: "localhost:5002", server_api_token: "your-jellyfish-token")
{:ok, #PID<0.301.0>}

# here add a room and a peer using functions from `Jellyfish.Room` module
# you should receive a notification after the peer established connection

iex> flush()
{:jellyfish,
{:peer_connected, "21604fbe-8ac8-44e6-8474-98b5f50f1863",
"ae07f94e-0887-44c3-81d5-bfa9eac96252"}}
{:jellyfish, %Jellyfish.ServerMessage.PeerConnected{
room_id: "21604fbe-8ac8-44e6-8474-98b5f50f1863",
peer_id: "ae07f94e-0887-44c3-81d5-bfa9eac96252"
}}
:ok
```
"""
Expand Down Expand Up @@ -48,9 +49,9 @@ defmodule Jellyfish.Notifier do
Starts the Notifier process and connects to Jellyfish.

Received notifications are send to the calling process in
a form of `{:jellyfish, msg}`, where `msg` is
`type` or `{type, room_id}` or `{type, room_id, (peer/component)_id}`.
Refer to [Jellyfish docs](https://jellyfish-dev.github.io/jellyfish-docs/) to learn more about server notifications.
a form of `{:jellyfish, msg}`, where `msg` is one of the structs defined in
`lib/proto/jellyfish/server_notifications.pb.ex`,
for example `{:jellyfish, %Jellyfish.ServerMessage.RoomCrashed{room_id: "some_id"}}`

For information about options, see `t:Jellyfish.Client.connection_options/0`.
"""
Expand Down
45 changes: 12 additions & 33 deletions lib/jellyfish/peer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule Jellyfish.Peer do

Peer is an entity that connects to the server to publish, subscribe to or publish and subscribe
to tracks published by components and other peers.
For more information refer to [Jellyfish documentation](https://www.membrane.stream)
For more information refer to [Jellyfish documentation](https://jellyfish-dev.github.io/jellyfish-docs/introduction/basic_concepts).
"""

alias Jellyfish.Exception.StructureError
Expand All @@ -24,34 +24,21 @@ defmodule Jellyfish.Peer do

@typedoc """
Type of the peer.

For more information refer to [Jellyfish documentation](https://jellyfish-dev.github.io/jellyfish-docs/).
"""
@type type :: :webrtc

@valid_type_strings ["webrtc"]
@type type :: WebRTC

@typedoc """
Status of the peer.

For more information refer to [Jellyfish documentation](https://jellyfish-dev.github.io/jellyfish-docs/).
"""
@type status :: :disconnected | :connected

@valid_status_strings ["disconnected", "connected"]

@typedoc """
Peer-specific options.

For the list of available options, refer to [Jellyfish documentation](https://jellyfish-dev.github.io/jellyfish-docs/).
"""
@type options :: WebRTC.t()

@typedoc """
Peer options module.
"""
@type options_module :: WebRTC

@typedoc """
Stores information about the peer.
"""
Expand Down Expand Up @@ -82,27 +69,19 @@ defmodule Jellyfish.Peer do
end

@doc false
@spec type_from_options(struct()) :: type()
def type_from_options(peer) do
case peer do
%WebRTC{} -> :webrtc
_other -> raise "Invalid peer options struct"
end
end
@spec type_from_string(String.t()) :: type()
def type_from_string("webrtc"), do: WebRTC
def type_from_string(_type), do: raise("Invalid peer type string")

@doc false
@spec type_from_string(String.t()) :: type()
def type_from_string(string) do
if string in @valid_type_strings,
do: String.to_atom(string),
else: raise("Invalid peer type string")
end
@spec string_from_options(struct()) :: String.t()
def string_from_options(%WebRTC{}), do: "webrtc"
def string_from_options(_struct), do: raise("Invalid peer options struct")

@doc false
@spec status_from_string(String.t()) :: status()
def status_from_string(string) do
if string in @valid_status_strings,
do: String.to_atom(string),
else: raise("Invalid peer status string")
end
def status_from_string(status) when status in @valid_status_strings,
do: String.to_atom(status)

def status_from_string(_status), do: raise("Invalid peer status string")
end
3 changes: 2 additions & 1 deletion lib/jellyfish/peer/webrtc.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ defmodule Jellyfish.Peer.WebRTC do
@moduledoc """
Options for the WebRTC peer.

For the description of these options refer to [Jellyfish documentation](https://jellyfish-dev.github.io/jellyfish-docs/getting_started/peers/webrtc)
For the description of these options refer to [Jellyfish
documentation](https://jellyfish-dev.github.io/jellyfish-docs/getting_started/peers/webrtc).
"""

@enforce_keys []
Expand Down
Loading