Skip to content

Commit ab533fe

Browse files
authored
Add CLI (#14)
* add CLI * add comment to build_binary.sh
1 parent 4ade6ed commit ab533fe

File tree

10 files changed

+143
-11
lines changed

10 files changed

+143
-11
lines changed

.circleci/config.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,20 @@ workflows:
77
build:
88
jobs:
99
- elixir/build_test:
10-
cache-version: 6
10+
cache-version: 7
1111
filters: &filters
1212
tags:
1313
only: /v.*/
1414
- elixir/test:
15-
cache-version: 6
15+
cache-version: 7
1616
filters:
1717
<<: *filters
1818
- elixir/lint:
19-
cache-version: 6
19+
cache-version: 7
2020
filters:
2121
<<: *filters
2222
- elixir/hex_publish:
23-
cache-version: 6
23+
cache-version: 7
2424
requires:
2525
- elixir/build_test
2626
- elixir/test

.formatter.exs

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
inputs = [
2+
"{lib,test,config}/**/*.{ex,exs}",
3+
".formatter.exs",
4+
"*.exs"
5+
]
6+
17
[
2-
inputs: [
3-
"{lib,test,config}/**/*.{ex,exs}",
4-
".formatter.exs",
5-
"*.exs"
6-
],
8+
inputs: inputs ++ Enum.map(inputs, &"boombox_burrito/#{&1}"),
79
import_deps: [:membrane_core]
810
]

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/boombox
12
compile_commands.json
23
.gdb_history
34
bundlex.sh

README.md

+25
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,31 @@ end
2222

2323
See `examples.livemd` for usage examples.
2424

25+
## CLI app
26+
27+
To build a CLI app, clone the repo and run
28+
29+
```
30+
mix deps.get
31+
./build_binary.sh
32+
```
33+
34+
It should generate a single executable called `boombox`, which you can run.
35+
36+
The CLI API is similar to the Elixir API, for example:
37+
38+
```elixir
39+
Boombox.run(input: "file.mp4", output: {:webrtc, "ws://localhost:8830"})
40+
```
41+
42+
is equivalent to:
43+
44+
```
45+
./boombox -i file.mp4 -o -webrtc ws://localhost:8830
46+
```
47+
48+
The first run of the CLI may take longer than usual, as the necessary artifacts are installed in the system.
49+
2550
## Copyright and License
2651

2752
Copyright 2020, [Software Mansion](https://swmansion.com/?utm_source=git&utm_medium=readme&utm_campaign=boombox)

build_binary.sh

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
MIX_ENV=prod BOOMBOX_BURRITO=true mix release --overwrite && \
2+
mv burrito_out/boombox_current boombox && \
3+
rm -r burrito_out && \
4+
# Burrito extracts the compressed artifacts into a common
5+
# location in the system on a first run, and then reuses
6+
# those artifacts and checks the version in mix.exs to
7+
# know whether it car reuse them. So we need to uninstall
8+
# the artifacts to force burrito to extract them again
9+
# even if the version in mix.exs didn't change
10+
yes | ./boombox maintenance uninstall

config/config.exs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import Config
2+
3+
if config_env() == :prod do
4+
config :logger, level: :warning
5+
end

lib/boombox.ex

+22
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,26 @@ defmodule Boombox do
3030
{:DOWN, _monitor, :process, ^supervisor, _reason} -> :ok
3131
end
3232
end
33+
34+
@spec run_cli([String.t()]) :: :ok
35+
def run_cli(args \\ System.argv()) do
36+
args =
37+
Enum.map(args, fn
38+
"-" <> value -> String.to_atom(value)
39+
value -> value
40+
end)
41+
42+
run(input: parse_cli_io(:i, args), output: parse_cli_io(:o, args))
43+
end
44+
45+
defp parse_cli_io(type, args) do
46+
args
47+
|> Enum.drop_while(&(&1 != type))
48+
|> Enum.drop(1)
49+
|> Enum.take_while(&(&1 not in [:i, :o]))
50+
|> case do
51+
[value] -> value
52+
[_h | _t] = values -> List.to_tuple(values)
53+
end
54+
end
3355
end

lib/boombox/utils/burrito_app.ex

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
defmodule Boombox.Utils.BurritoApp do
2+
@moduledoc false
3+
4+
use Application
5+
6+
@dialyzer {:no_return, {:start, 2}}
7+
@impl true
8+
def start(_type, _args) do
9+
Boombox.run_cli(Burrito.Util.Args.argv())
10+
System.halt()
11+
end
12+
end

mix.exs

+54-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ defmodule Boombox.Mixfile do
1313
start_permanent: Mix.env() == :prod,
1414
deps: deps(),
1515
dialyzer: dialyzer(),
16+
releases: releases(),
1617

1718
# hex
1819
description: "Boombox",
@@ -27,10 +28,18 @@ defmodule Boombox.Mixfile do
2728

2829
def application do
2930
[
30-
extra_applications: []
31+
extra_applications: [],
32+
mod:
33+
if burrito?() do
34+
{Boombox.Utils.BurritoApp, []}
35+
else
36+
[]
37+
end
3138
]
3239
end
3340

41+
defp burrito?, do: System.get_env("BOOMBOX_BURRITO") != nil
42+
3443
defp elixirc_paths(:test), do: ["lib", "test/support"]
3544
defp elixirc_paths(_env), do: ["lib"]
3645

@@ -48,6 +57,7 @@ defmodule Boombox.Mixfile do
4857
{:membrane_rtmp_plugin, github: "membraneframework/membrane_rtmp_plugin"},
4958
{:membrane_ffmpeg_swresample_plugin, "~> 0.20.0"},
5059
{:membrane_hackney_plugin, "~> 0.11.0"},
60+
{:burrito, "~> 1.0", runtime: burrito?()},
5161
{:ex_doc, ">= 0.0.0", only: :dev, runtime: false},
5262
{:dialyxir, ">= 0.0.0", only: :dev, runtime: false},
5363
{:credo, ">= 0.0.0", only: :dev, runtime: false}
@@ -87,4 +97,47 @@ defmodule Boombox.Mixfile do
8797
nest_modules_by_prefix: [Boombox]
8898
]
8999
end
100+
101+
defp releases() do
102+
if burrito?() do
103+
burrito_releases()
104+
else
105+
[]
106+
end
107+
end
108+
109+
defp burrito_releases() do
110+
current_os =
111+
case :os.type() do
112+
{:win32, _} -> :windows
113+
{:unix, :darwin} -> :darwin
114+
{:unix, :linux} -> :linux
115+
end
116+
117+
arch_string =
118+
:erlang.system_info(:system_architecture)
119+
|> to_string()
120+
|> String.downcase()
121+
|> String.split("-")
122+
|> List.first()
123+
124+
current_cpu =
125+
case arch_string do
126+
"x86_64" -> :x86_64
127+
"arm64" -> :aarch64
128+
"aarch64" -> :aarch64
129+
_ -> :unknown
130+
end
131+
132+
[
133+
boombox: [
134+
steps: [:assemble, &Burrito.wrap/1],
135+
burrito: [
136+
targets: [
137+
current: [os: current_os, cpu: current_cpu]
138+
]
139+
]
140+
]
141+
]
142+
end
90143
end

mix.lock

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"bunch_native": {:hex, :bunch_native, "0.5.0", "8ac1536789a597599c10b652e0b526d8833348c19e4739a0759a2bedfd924e63", [:mix], [{:bundlex, "~> 1.0", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "24190c760e32b23b36edeb2dc4852515c7c5b3b8675b1a864e0715bdd1c8f80d"},
66
"bundlex": {:hex, :bundlex, "1.5.3", "35d01e5bc0679510dd9a327936ffb518f63f47175c26a35e708cc29eaec0890b", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:elixir_uuid, "~> 1.2", [hex: :elixir_uuid, repo: "hexpm", optional: false]}, {:qex, "~> 0.5", [hex: :qex, repo: "hexpm", optional: false]}, {:req, ">= 0.4.0", [hex: :req, repo: "hexpm", optional: false]}, {:zarex, "~> 1.0", [hex: :zarex, repo: "hexpm", optional: false]}], "hexpm", "debd0eac151b404f6216fc60222761dff049bf26f7d24d066c365317650cd118"},
77
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
8+
"burrito": {:hex, :burrito, "1.1.0", "4f26919234e144be9c3f5eb3fbd01e63395816376cf742b3570433167e46ede4", [:mix], [{:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}, {:req, "0.4.0", [hex: :req, repo: "hexpm", optional: false]}, {:typed_struct, "~> 0.2.0 or ~> 0.3.0", [hex: :typed_struct, repo: "hexpm", optional: false]}], "hexpm", "decda65f57271d38c84a34e262b40636414f9f58b2b22f243e782938bfc2a414"},
89
"castore": {:hex, :castore, "1.0.8", "dedcf20ea746694647f883590b82d9e96014057aff1d44d03ec90f36a5c0dc6e", [:mix], [], "hexpm", "0b2b66d2ee742cb1d9cb8c8be3b43c3a70ee8651f37b75a8b982e036752983f1"},
910
"certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"},
1011
"coerce": {:hex, :coerce, "1.0.1", "211c27386315dc2894ac11bc1f413a0e38505d808153367bd5c6e75a4003d096", [:mix], [], "hexpm", "b44a691700f7a1a15b4b7e2ff1fa30bebd669929ac8aa43cffe9e2f8bf051cf1"},
@@ -82,13 +83,14 @@
8283
"plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"},
8384
"qex": {:hex, :qex, "0.5.1", "0d82c0f008551d24fffb99d97f8299afcb8ea9cf99582b770bd004ed5af63fd6", [:mix], [], "hexpm", "935a39fdaf2445834b95951456559e9dc2063d0a055742c558a99987b38d6bab"},
8485
"ratio": {:hex, :ratio, "4.0.1", "3044166f2fc6890aa53d3aef0c336f84b2bebb889dc57d5f95cc540daa1912f8", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:numbers, "~> 5.2.0", [hex: :numbers, repo: "hexpm", optional: false]}], "hexpm", "c60cbb3ccdff9ffa56e7d6d1654b5c70d9f90f4d753ab3a43a6bf40855b881ce"},
85-
"req": {:hex, :req, "0.5.6", "8fe1eead4a085510fe3d51ad854ca8f20a622aae46e97b302f499dfb84f726ac", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "cfaa8e720945d46654853de39d368f40362c2641c4b2153c886418914b372185"},
86+
"req": {:hex, :req, "0.4.0", "1c759054dd64ef1b1a0e475c2d2543250d18f08395d3174c371b7746984579ce", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.9", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "f53eadc32ebefd3e5d50390356ec3a59ed2b8513f7da8c6c3f2e14040e9fe989"},
8687
"shmex": {:hex, :shmex, "0.5.1", "81dd209093416bf6608e66882cb7e676089307448a1afd4fc906c1f7e5b94cf4", [:mix], [{:bunch_native, "~> 0.5.0", [hex: :bunch_native, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.0", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "c29f8286891252f64c4e1dac40b217d960f7d58def597c4e606ff8fbe71ceb80"},
8788
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},
8889
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
8990
"telemetry_metrics": {:hex, :telemetry_metrics, "0.6.2", "2caabe9344ec17eafe5403304771c3539f3b6e2f7fb6a6f602558c825d0d0bfb", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9b43db0dc33863930b9ef9d27137e78974756f5f198cae18409970ed6fa5b561"},
9091
"thousand_island": {:hex, :thousand_island, "1.3.5", "6022b6338f1635b3d32406ff98d68b843ba73b3aa95cfc27154223244f3a6ca5", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2be6954916fdfe4756af3239fb6b6d75d0b8063b5df03ba76fd8a4c87849e180"},
9192
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
93+
"typed_struct": {:hex, :typed_struct, "0.3.0", "939789e3c1dca39d7170c87f729127469d1315dcf99fee8e152bb774b17e7ff7", [:mix], [], "hexpm", "c50bd5c3a61fe4e198a8504f939be3d3c85903b382bde4865579bc23111d1b6d"},
9294
"unifex": {:hex, :unifex, "1.2.0", "90d1ec5e6d788350e07e474f7bd8b0ee866d6606beb9ca4e20dbb26328712a84", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.4", [hex: :bundlex, repo: "hexpm", optional: false]}, {:shmex, "~> 0.5.0", [hex: :shmex, repo: "hexpm", optional: false]}], "hexpm", "7a8395aabc3ba6cff04bbe5b995de7f899a38eb57f189e49927d6b8b6ccb6883"},
9395
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
9496
"websock_adapter": {:hex, :websock_adapter, "0.5.6", "0437fe56e093fd4ac422de33bf8fc89f7bc1416a3f2d732d8b2c8fd54792fe60", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "e04378d26b0af627817ae84c92083b7e97aca3121196679b73c73b99d0d133ea"},

0 commit comments

Comments
 (0)