Skip to content

Commit 636c150

Browse files
authored
Add ci github action (#14)
* Add ci github action * refactor parse message payload * Bump min elixir version to 1.16
1 parent 74bd5ad commit 636c150

15 files changed

Lines changed: 150 additions & 91 deletions

File tree

.github/workflows/ci.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Elixir CI
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
9+
env:
10+
MIX_ENV: test
11+
12+
jobs:
13+
test:
14+
strategy:
15+
matrix:
16+
include:
17+
- otp_version: 25.3
18+
elixir_version: 1.16
19+
20+
- otp_version: 27.2
21+
elixir_version: 1.18
22+
runs-on: ubuntu-latest
23+
24+
steps:
25+
- uses: actions/checkout@v3
26+
27+
- uses: erlef/setup-beam@v1
28+
with:
29+
elixir-version: ${{ matrix.elixir_version }}
30+
otp-version: ${{ matrix.otp_version }}
31+
32+
- name: Install dependencies
33+
run: mix deps.get
34+
- name: Compile dependencies
35+
run: mix deps.compile
36+
- name: Run tests
37+
run: mix test --warnings-as-errors
38+
- name: Run Credo
39+
run: mix credo --strict
40+
41+
format:
42+
runs-on: ubuntu-latest
43+
name: mix format
44+
steps:
45+
- uses: actions/checkout@v4
46+
- uses: erlef/setup-beam@v1
47+
with:
48+
otp-version: 27.2
49+
elixir-version: 1.18
50+
- run: mix format --check-formatted

examples/publish_mp4.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ defmodule Publisher do
9191

9292
defp init_tag(%{media: :h264} = track) do
9393
<<_::binary-size(8), dcr::binary>> = ExMP4.Box.serialize(track.priv_data)
94-
VideoData.AVC.new(dcr, :sequence_header, 0) |> VideoData.new(:avc, :keyframe)
94+
VideoData.AVC.new(dcr, :sequence_header, 0) |> VideoData.new(:h264, :keyframe)
9595
end
9696

9797
defp init_tag(%{media: :h265} = track) do
@@ -116,7 +116,7 @@ defmodule Publisher do
116116
defp video_tag(:h264, sample, ct) do
117117
sample.payload
118118
|> VideoData.AVC.new(:nalu, ct)
119-
|> VideoData.new(:avc, if(sample.sync?, do: :keyframe, else: :interframe))
119+
|> VideoData.new(:h264, if(sample.sync?, do: :keyframe, else: :interframe))
120120
end
121121

122122
defp video_tag(:h265, sample, ct) do

examples/read_to_flv.exs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ defmodule StreamWriter do
3939
end
4040

4141
@impl true
42-
def handle_info({:video, pid, _stream_id, {:codec, :avc, dcr}}, %{client: pid} = state) do
42+
def handle_info({:video, pid, _stream_id, {:codec, :h264, dcr}}, %{client: pid} = state) do
4343
payload =
4444
dcr
4545
|> Tag.AVCVideoPacket.new(:sequence_header, 0)
46-
|> Tag.VideoData.new(:avc, :keyframe)
46+
|> Tag.VideoData.new(:h264, :keyframe)
4747

4848
tag = Tag.serialize(%Tag{type: :video, data: payload, timestamp: 0})
4949
IO.binwrite(state.writer, [tag, <<IO.iodata_length(tag)::32>>])
@@ -73,7 +73,7 @@ defmodule StreamWriter do
7373
payload
7474
|> Enum.map(&<<byte_size(&1)::32, &1::binary>>)
7575
|> Tag.AVCVideoPacket.new(:nalu, pts - dts)
76-
|> Tag.VideoData.new(:avc, if(sync?, do: :keyframe, else: :interframe))
76+
|> Tag.VideoData.new(:h264, if(sync?, do: :keyframe, else: :interframe))
7777

7878
tag = Tag.serialize(%Tag{type: :video, data: payload, timestamp: dts})
7979
IO.binwrite(state.writer, [tag, <<IO.iodata_length(tag)::32>>])

examples/send_mp4.exs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ defmodule Publisher do
3030
video_reducer: video_reducer,
3131
audio_track: audio_track,
3232
audio_reducer: audio_reducer,
33-
stream_id: opts[:stream_id],
33+
stream_id: opts[:stream_id]
3434
}, {:continue, :send_init_data}}
3535
end
3636

@@ -55,7 +55,7 @@ defmodule Publisher do
5555

5656
dcr
5757
|> AVCVideoPacket.new(:sequence_header, 0)
58-
|> VideoData.new(:avc, :keyframe)
58+
|> VideoData.new(:h264, :keyframe)
5959
|> ExFLV.Tag.Serializer.serialize()
6060
|> then(&ClientSession.send_video_data(state.rtmp_sender, state.stream_id, 0, &1))
6161

@@ -83,7 +83,7 @@ defmodule Publisher do
8383
data =
8484
sample.payload
8585
|> AVCVideoPacket.new(:nalu, sample.pts - sample.dts)
86-
|> VideoData.new(:avc, frame_type)
86+
|> VideoData.new(:h264, frame_type)
8787
|> ExFLV.Tag.Serializer.serialize()
8888

8989
ClientSession.send_video_data(state.rtmp_sender, state.stream_id, timestamp, data)

lib/ex_rtmp/chunk.ex

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,8 @@ defmodule ExRTMP.Chunk do
3232
@spec parse_header(binary()) :: {:ok, t(), binary()} | :more
3333
def parse_header(data) do
3434
with {:ok, chunk, rest} <- parse_stream_id(data),
35-
{:ok, chunk, rest} <- parse_message_header(chunk, rest),
36-
{:ok, chunk, rest} <- parse_extended_timestamp(chunk, rest) do
37-
{:ok, chunk, rest}
35+
{:ok, chunk, rest} <- parse_message_header(chunk, rest) do
36+
parse_extended_timestamp(chunk, rest)
3837
end
3938
end
4039

lib/ex_rtmp/chunk_parser.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ defmodule ExRTMP.ChunkParser do
1212

1313
defstruct [:unprocessed_data, :messages, :message_first_chunk, chunk_size: 128]
1414

15-
@spec new() :: t()
16-
def new() do
15+
@spec new :: t()
16+
def new do
1717
%__MODULE__{
1818
unprocessed_data: <<>>,
1919
messages: %{},

lib/ex_rtmp/client/media_processor.ex

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ defmodule ExRTMP.Client.MediaProcessor do
1010
@type codec ::
1111
AudioData.source_format()
1212
| VideoData.codec_id()
13-
| ExVideoData.fourcc()
14-
| ExAudioData.fourcc()
13+
| ExVideoData.codec_id()
14+
| ExAudioData.codec_id()
1515

1616
@type track :: {:codec, codec(), binary()}
1717
@type video_sample ::
@@ -31,8 +31,8 @@ defmodule ExRTMP.Client.MediaProcessor do
3131

3232
defstruct [:nalu_prefix_size, video?: false, audio?: false]
3333

34-
@spec new() :: t()
35-
def new(), do: %__MODULE__{}
34+
@spec new :: t()
35+
def new, do: %__MODULE__{}
3636

3737
@spec push_video(Message.t(), t()) :: {video_return(), t()}
3838
def push_video(message, processor) do
@@ -56,7 +56,7 @@ defmodule ExRTMP.Client.MediaProcessor do
5656
defp parse_audio_tag(<<9::4, _::bitstring>> = data), do: ExAudioData.parse!(data)
5757
defp parse_audio_tag(data), do: AudioData.parse!(data)
5858

59-
defp handle_video_tag(%VideoData{codec_id: :avc} = tag, timestamp, processor) do
59+
defp handle_video_tag(%VideoData{codec_id: :h264} = tag, timestamp, processor) do
6060
packet_type = tag.data.packet_type
6161

6262
cond do
@@ -67,11 +67,11 @@ defmodule ExRTMP.Client.MediaProcessor do
6767
packet_type == :sequence_header ->
6868
processor = %{
6969
processor
70-
| nalu_prefix_size: nalu_prefix_size(:avc, tag.data.data),
70+
| nalu_prefix_size: nalu_prefix_size(:h264, tag.data.data),
7171
video?: true
7272
}
7373

74-
{{:codec, :avc, tag.data.data}, processor}
74+
{{:codec, :h264, tag.data.data}, processor}
7575

7676
packet_type == :end_of_sequence ->
7777
{nil, processor}
@@ -101,11 +101,11 @@ defmodule ExRTMP.Client.MediaProcessor do
101101
packet_type == :sequence_start ->
102102
processor = %{
103103
processor
104-
| nalu_prefix_size: nalu_prefix_size(tag.fourcc, tag.data),
104+
| nalu_prefix_size: nalu_prefix_size(tag.codec_id, tag.data),
105105
video?: true
106106
}
107107

108-
{{:codec, tag.fourcc, tag.data}, processor}
108+
{{:codec, tag.codec_id, tag.data}, processor}
109109

110110
packet_type in [:sequence_end, :metadata] ->
111111
{nil, processor}
@@ -149,7 +149,7 @@ defmodule ExRTMP.Client.MediaProcessor do
149149
{{:sample, tag.data, timestamp}, processor}
150150

151151
tag.packet_type == :sequence_start ->
152-
{{:codec, tag.fourcc, tag.data}, %{processor | audio?: true}}
152+
{{:codec, tag.codec_id, tag.data}, %{processor | audio?: true}}
153153

154154
true ->
155155
{nil, processor}
@@ -165,12 +165,12 @@ defmodule ExRTMP.Client.MediaProcessor do
165165
{{:sample, tag.data, timestamp}, processor}
166166
end
167167

168-
defp nalu_prefix_size(:hvc1, <<_::binary-size(21), _::6, nalu_prefix_size::2, _::binary>>) do
168+
defp nalu_prefix_size(:h265, <<_::binary-size(21), _::6, nalu_prefix_size::2, _::binary>>) do
169169
nalu_prefix_size + 1
170170
end
171171

172172
defp nalu_prefix_size(codec, <<_::38, nalu_prefix_size::2, _::binary>>)
173-
when codec == :avc or codec == :avc1 do
173+
when codec == :h264 or codec == :h265 do
174174
nalu_prefix_size + 1
175175
end
176176

lib/ex_rtmp/message.ex

Lines changed: 44 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ defmodule ExRTMP.Message do
99
alias __MODULE__.Command.NetStream.{DeleteStream, FCPublish, OnStatus, Play, Publish}
1010
alias __MODULE__.Metadata
1111
alias __MODULE__.UserControl.Event
12-
alias ExRTMP.Chunk
12+
alias ExRTMP.{Chunk, Message}
1313

1414
@type stream_id :: non_neg_integer()
1515

@@ -149,7 +149,7 @@ defmodule ExRTMP.Message do
149149

150150
payload =
151151
if is_struct(message.payload),
152-
do: ExRTMP.Message.Serializer.serialize(message.payload),
152+
do: Message.Serializer.serialize(message.payload),
153153
else: message.payload
154154

155155
payload = IO.iodata_to_binary(payload)
@@ -221,51 +221,57 @@ defmodule ExRTMP.Message do
221221
@doc false
222222
defp parse_payload(%__MODULE__{type: 20, payload: payload} = msg) do
223223
payload =
224-
case ExRTMP.AMF0.parse(IO.iodata_to_binary(payload)) do
225-
["connect", transaction_id, properties | _rest] ->
226-
%Connect{transaction_id: transaction_id, properties: properties}
227-
228-
["createStream", transaction_id | _rest] ->
229-
%CreateStream{transaction_id: transaction_id}
230-
231-
[result, transaction_id, command_object, data] when result in ["_result", "_error"] ->
232-
%Response{
233-
result: result,
234-
transaction_id: trunc(transaction_id),
235-
command_object: command_object,
236-
data: data
237-
}
224+
payload
225+
|> IO.iodata_to_binary()
226+
|> ExRTMP.AMF0.parse()
227+
|> handle_message_payload()
238228

239-
["publish", _txid, nil, name, type] ->
240-
Publish.new(name, type)
229+
%{msg | payload: payload}
230+
end
241231

242-
["FCPublish", transaction_id, nil, name] ->
243-
FCPublish.new(transaction_id, name)
232+
defp parse_payload(msg), do: msg
244233

245-
["deleteStream", _txid, nil, stream_id] ->
246-
DeleteStream.new(stream_id)
234+
defp handle_message_payload(["connect", transaction_id, properties | _rest]) do
235+
%Connect{transaction_id: transaction_id, properties: properties}
236+
end
247237

248-
["play", _txid, nil, stream_name | opts] ->
249-
play_opts =
250-
case opts do
251-
[] -> []
252-
[start] -> [start: start]
253-
[start, duration] -> [start: start, duration: duration]
254-
[start, duration, reset] -> [start: start, duration: duration, reset: reset]
255-
end
238+
defp handle_message_payload(["createStream", transaction_id | _rest]) do
239+
%CreateStream{transaction_id: transaction_id}
240+
end
256241

257-
Play.new(stream_name, play_opts)
242+
defp handle_message_payload([result, transaction_id, command_object, data])
243+
when result in ["_result", "_error"] do
244+
%Response{
245+
result: result,
246+
transaction_id: trunc(transaction_id),
247+
command_object: command_object,
248+
data: data
249+
}
250+
end
258251

259-
["onStatus", _ts_id, nil, info] ->
260-
%OnStatus{info: info}
252+
defp handle_message_payload(["publish", _txid, nil, name, type]), do: Publish.new(name, type)
253+
defp handle_message_payload(["onStatus", _txid, nil, info]), do: %OnStatus{info: info}
261254

262-
other ->
263-
Logger.warning("Unknown command: #{inspect(List.first(other))}")
264-
payload
255+
defp handle_message_payload(["play", _txid, nil, name | opts]) do
256+
play_opts =
257+
case opts do
258+
[] -> []
259+
[start] -> [start: start]
260+
[start, duration] -> [start: start, duration: duration]
261+
[start, duration, reset] -> [start: start, duration: duration, reset: reset]
265262
end
266263

267-
%{msg | payload: payload}
264+
Play.new(name, play_opts)
268265
end
269266

270-
defp parse_payload(msg), do: msg
267+
defp handle_message_payload(["deleteStream", _txid, nil, stream_id]),
268+
do: DeleteStream.new(stream_id)
269+
270+
defp handle_message_payload(["FCPublish", transaction_id, nil, name]),
271+
do: FCPublish.new(transaction_id, name)
272+
273+
defp handle_message_payload(other) do
274+
Logger.warning("Unknown command: #{inspect(other)}")
275+
other
276+
end
271277
end

lib/ex_rtmp/message/command/net_stream/on_status.ex

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ defmodule ExRTMP.Message.Command.NetStream.OnStatus do
1818
%__MODULE__{info: info}
1919
end
2020

21-
@spec publish_ok() :: t()
22-
def publish_ok(), do: new("NetStream.Publish.Start")
21+
@spec publish_ok :: t()
22+
def publish_ok, do: new("NetStream.Publish.Start")
2323

24-
@spec publish_bad_stream() :: t()
25-
def publish_bad_stream() do
24+
@spec publish_bad_stream :: t()
25+
def publish_bad_stream do
2626
new("NetStream.Publish.BadStream", :error, "Unknown stream")
2727
end
2828

@@ -31,11 +31,11 @@ defmodule ExRTMP.Message.Command.NetStream.OnStatus do
3131
new("NetStream.Publish.Failed", :error, reason)
3232
end
3333

34-
@spec play_ok() :: t()
35-
def play_ok(), do: new("NetStream.Play.Start")
34+
@spec play_ok :: t()
35+
def play_ok, do: new("NetStream.Play.Start")
3636

37-
@spec play_bad_stream() :: t()
38-
def play_bad_stream() do
37+
@spec play_bad_stream :: t()
38+
def play_bad_stream do
3939
new("NetStream.Play.BadStream", :error, "Unknown stream")
4040
end
4141

lib/ex_rtmp/server/client_session.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ defmodule ExRTMP.Server.ClientSession do
1212
alias ExRTMP.Message
1313
alias ExRTMP.Message.Command.NetConnection
1414
alias ExRTMP.Message.Command.NetConnection.{CreateStream, Response}
15-
alias ExRTMP.Message.Command.NetStream.{DeleteStream, FCPublish, Play, Publish, OnStatus}
15+
alias ExRTMP.Message.Command.NetStream.{DeleteStream, FCPublish, OnStatus, Play, Publish}
1616
alias ExRTMP.Message.Metadata
1717

1818
@default_acknowledgement_size 3_000_000

0 commit comments

Comments
 (0)