diff --git a/camera_to_hls_nerves/.formatter.exs b/camera_to_hls_nerves/.formatter.exs new file mode 100644 index 00000000..40ec48a7 --- /dev/null +++ b/camera_to_hls_nerves/.formatter.exs @@ -0,0 +1,9 @@ +# Used by "mix format" +[ + inputs: [ + "{mix,.formatter}.exs", + "{config,lib,test}/**/*.{ex,exs}", + "rootfs_overlay/etc/iex.exs" + ], + import_deps: [:membrane_core, :unifex] +] diff --git a/camera_to_hls_nerves/.gitignore b/camera_to_hls_nerves/.gitignore new file mode 100644 index 00000000..b03e8b8b --- /dev/null +++ b/camera_to_hls_nerves/.gitignore @@ -0,0 +1,17 @@ +# The directory Mix will write compiled artifacts to. +/_build/ + +# If you run "mix test --cover", coverage assets end up here. +/cover/ + +# The directory Mix downloads your dependencies sources to. +/deps/ + +# Where third-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch + +# If the VM crashes, it generates a dump, let's ignore it too. +erl_crash.dump diff --git a/camera_to_hls_nerves/README.md b/camera_to_hls_nerves/README.md new file mode 100644 index 00000000..23e12e27 --- /dev/null +++ b/camera_to_hls_nerves/README.md @@ -0,0 +1,32 @@ +# CameraToHlsNerves + +**TODO: Add description** + +## Targets + +Nerves applications produce images for hardware targets based on the +`MIX_TARGET` environment variable. If `MIX_TARGET` is unset, `mix` builds an +image that runs on the host (e.g., your laptop). This is useful for executing +logic tests, running utilities, and debugging. Other targets are represented by +a short name like `rpi3` that maps to a Nerves system image for that platform. +All of this logic is in the generated `mix.exs` and may be customized. For more +information about targets see: + +https://hexdocs.pm/nerves/targets.html#content + +## Getting Started + +To start your Nerves app: + * `export MIX_TARGET=my_target` or prefix every command with + `MIX_TARGET=my_target`. For example, `MIX_TARGET=rpi3` + * Install dependencies with `mix deps.get` + * Create firmware with `mix firmware` + * Burn to an SD card with `mix burn` + +## Learn more + + * Official docs: https://hexdocs.pm/nerves/getting-started.html + * Official website: https://nerves-project.org/ + * Forum: https://elixirforum.com/c/nerves-forum + * Discussion Slack elixir-lang #nerves ([Invite](https://elixir-slackin.herokuapp.com/)) + * Source: https://github.com/nerves-project/nerves diff --git a/camera_to_hls_nerves/config/config.exs b/camera_to_hls_nerves/config/config.exs new file mode 100644 index 00000000..1368acf9 --- /dev/null +++ b/camera_to_hls_nerves/config/config.exs @@ -0,0 +1,26 @@ +# This file is responsible for configuring your application and its +# dependencies. +# +# This configuration file is loaded before any dependency and is restricted to +# this project. +import Config + +# Enable the Nerves integration with Mix +Application.start(:nerves_bootstrap) + +config :camera_to_hls_nerves, target: Mix.target() + +# Customize non-Elixir parts of the firmware. See +# https://hexdocs.pm/nerves/advanced-configuration.html for details. + +config :nerves, :firmware, rootfs_overlay: "rootfs_overlay" + +# Set the SOURCE_DATE_EPOCH date for reproducible builds. +# See https://reproducible-builds.org/docs/source-date-epoch/ for more information + +config :nerves, source_date_epoch: "1698662793" +if Mix.target() == :host do + import_config "host.exs" +else + import_config "target.exs" +end diff --git a/camera_to_hls_nerves/config/host.exs b/camera_to_hls_nerves/config/host.exs new file mode 100644 index 00000000..166f24df --- /dev/null +++ b/camera_to_hls_nerves/config/host.exs @@ -0,0 +1,21 @@ +import Config + +# Add configuration that is only needed when running on the host here. + +config :nerves_runtime, + kv_backend: + {Nerves.Runtime.KVBackend.InMemory, + contents: %{ + # The KV store on Nerves systems is typically read from UBoot-env, but + # this allows us to use a pre-populated InMemory store when running on + # host for development and testing. + # + # https://hexdocs.pm/nerves_runtime/readme.html#using-nerves_runtime-in-tests + # https://hexdocs.pm/nerves_runtime/readme.html#nerves-system-and-firmware-metadata + + "nerves_fw_active" => "a", + "a.nerves_fw_architecture" => "generic", + "a.nerves_fw_description" => "N/A", + "a.nerves_fw_platform" => "host", + "a.nerves_fw_version" => "0.0.0" + }} diff --git a/camera_to_hls_nerves/config/target.exs b/camera_to_hls_nerves/config/target.exs new file mode 100644 index 00000000..0f3b8842 --- /dev/null +++ b/camera_to_hls_nerves/config/target.exs @@ -0,0 +1,120 @@ +import Config + +# Use Ringlogger as the logger backend and remove :console. +# See https://hexdocs.pm/ring_logger/readme.html for more information on +# configuring ring_logger. + +config :logger, backends: [RingLogger] + +# Use shoehorn to start the main application. See the shoehorn +# library documentation for more control in ordering how OTP +# applications are started and handling failures. + +config :shoehorn, init: [:nerves_runtime, :nerves_pack] + +# Erlinit can be configured without a rootfs_overlay. See +# https://github.com/nerves-project/erlinit/ for more information on +# configuring erlinit. + +# Advance the system clock on devices without real-time clocks. +config :nerves, :erlinit, update_clock: true + +# Configure the device for SSH IEx prompt access and firmware updates +# +# * See https://hexdocs.pm/nerves_ssh/readme.html for general SSH configuration +# * See https://hexdocs.pm/ssh_subsystem_fwup/readme.html for firmware updates + +keys = + [ + Path.join([System.user_home!(), ".ssh", "id_rsa.pub"]), + Path.join([System.user_home!(), ".ssh", "id_ecdsa.pub"]), + Path.join([System.user_home!(), ".ssh", "id_ed25519.pub"]) + ] + |> Enum.filter(&File.exists?/1) + +if keys == [], + do: + Mix.raise(""" + No SSH public keys found in ~/.ssh. An ssh authorized key is needed to + log into the Nerves device and update firmware on it using ssh. + See your project's config.exs for this error message. + """) + +config :nerves_ssh, + authorized_keys: Enum.map(keys, &File.read!/1) + +# Configure the network using vintage_net +# +# Update regulatory_domain to your 2-letter country code E.g., "US" +# +# See https://github.com/nerves-networking/vintage_net for more information + +network = %{ + key_mgmt: :wpa_psk, + ssid: + case System.fetch_env("SSID") do + {:ok, ssid} -> ssid + :error -> raise "SSID not provided, set the environment variable SSID" + end, + psk: + case System.fetch_env("PSK") do + {:ok, psk} -> psk + :error -> "" + end +} + +config :vintage_net, + regulatory_domain: "00", + config: [ + {"usb0", %{type: VintageNetDirect}}, + {"eth0", + %{ + type: VintageNetEthernet, + ipv4: %{method: :dhcp} + }}, + {"wlan0", + %{ + type: VintageNetWiFi, + vintage_net_wifi: %{ + networks: [network] + }, + ipv4: %{method: :dhcp} + }} + ] + +config :mdns_lite, + # The `hosts` key specifies what hostnames mdns_lite advertises. `:hostname` + # advertises the device's hostname.local. For the official Nerves systems, this + # is "nerves-<4 digit serial#>.local". The `"nerves"` host causes mdns_lite + # to advertise "nerves.local" for convenience. If more than one Nerves device + # is on the network, it is recommended to delete "nerves" from the list + # because otherwise any of the devices may respond to nerves.local leading to + # unpredictable behavior. + + hosts: [:hostname, "nerves"], + ttl: 120, + + # Advertise the following services over mDNS. + services: [ + %{ + protocol: "ssh", + transport: "tcp", + port: 22 + }, + %{ + protocol: "sftp-ssh", + transport: "tcp", + port: 22 + }, + %{ + protocol: "epmd", + transport: "tcp", + port: 4369 + } + ] + +# Import target specific config. This must remain at the bottom +# of this file so it overrides the configuration defined above. +# Uncomment to use target specific configurations + +# import_config "#{Mix.target()}.exs" diff --git a/camera_to_hls_nerves/lib/nerves_membrane_demo.ex b/camera_to_hls_nerves/lib/nerves_membrane_demo.ex new file mode 100644 index 00000000..9a44d4d4 --- /dev/null +++ b/camera_to_hls_nerves/lib/nerves_membrane_demo.ex @@ -0,0 +1,5 @@ +defmodule CameraToHlsNerves do + @moduledoc """ + Example of streaming live feed from a RaspberryPi camera to a browser with HLS + """ +end diff --git a/camera_to_hls_nerves/lib/nerves_membrane_demo/application.ex b/camera_to_hls_nerves/lib/nerves_membrane_demo/application.ex new file mode 100644 index 00000000..5d4cd5df --- /dev/null +++ b/camera_to_hls_nerves/lib/nerves_membrane_demo/application.ex @@ -0,0 +1,30 @@ +defmodule CameraToHlsNerves.Application do + use Application + + def start(_type, _args) do + + File.rm_rf!("/data/output") + File.mkdir!("/data/output") + File.cd!("/") + + :inets.start() + + httpd_options = [ + bind_address: ~c"0.0.0.0", + port: 8000, + document_root: ~c".", + server_name: ~c"camera_to_hls_nerves", + server_root: ~c"/" + ] + + children = [ + %{ + id: :http_server, + start: {:inets, :start, [:httpd, httpd_options]} + }, + CameraToHlsNerves.Pipeline + ] + + Supervisor.start_link(children, strategy: :one_for_one) + end +end diff --git a/camera_to_hls_nerves/lib/nerves_membrane_demo/pipeline.ex b/camera_to_hls_nerves/lib/nerves_membrane_demo/pipeline.ex new file mode 100644 index 00000000..7c9168dd --- /dev/null +++ b/camera_to_hls_nerves/lib/nerves_membrane_demo/pipeline.ex @@ -0,0 +1,32 @@ +defmodule CameraToHlsNerves.Pipeline do + use Membrane.Pipeline + + def start_link(opts) do + Membrane.Pipeline.start_link(__MODULE__, opts) + end + + @impl true + def handle_init(_ctx, _opts) do + spec = [ + child(:source, %Membrane.Rpicam.Source{framerate: {30, 1}}) + |> child(:parser, %Membrane.H264.Parser{generate_best_effort_timestamps: %{framerate: {30, 1}}}) + |> via_in(:input, + options: [ + encoding: :H264, + track_name: "my_track", + segment_duration: Membrane.Time.seconds(5) + ] + ) + |> child(:hls_sink, %Membrane.HTTPAdaptiveStream.SinkBin{ + manifest_module: Membrane.HTTPAdaptiveStream.HLS, + storage: %Membrane.HTTPAdaptiveStream.Storages.FileStorage{directory: "/data/output"}, + target_window_duration: Membrane.Time.seconds(10) + }) + ] + + # Not waiting causes libcamera-vid to crash + Process.sleep(50) + + {[spec: spec], %{}} + end +end diff --git a/camera_to_hls_nerves/mix.exs b/camera_to_hls_nerves/mix.exs new file mode 100644 index 00000000..badf5e7c --- /dev/null +++ b/camera_to_hls_nerves/mix.exs @@ -0,0 +1,93 @@ +defmodule CameraToHlsNerves.MixProject do + use Mix.Project + + @app :camera_to_hls_nerves + @version "0.1.0" + @all_targets [ + :rpi, + :rpi0, + :rpi2, + :rpi3, + :rpi3a, + :rpi4, + :bbb, + :osd32mp1, + :x86_64, + :grisp2, + :mangopi_mq_pro + ] + + def project do + [ + app: @app, + version: @version, + elixir: "~> 1.11", + archives: [nerves_bootstrap: "~> 1.12"], + start_permanent: Mix.env() == :prod, + deps: deps(), + releases: [{@app, release()}], + preferred_cli_target: [run: :host, test: :host] + ] + end + + # Run "mix help compile.app" to learn about applications. + def application do + [ + mod: {CameraToHlsNerves.Application, []}, + extra_applications: [:logger, :runtime_tools, :inets] + ] + end + + # Run "mix help deps" to learn about dependencies. + defp deps do + [ + # Dependencies for all targets + {:nerves, "~> 1.10", runtime: false}, + {:shoehorn, "~> 0.9.1"}, + {:ring_logger, "~> 0.10.0"}, + {:toolshed, "~> 0.3.0"}, + {:httpoison, "~> 2.0"}, + + {:membrane_rpicam_plugin, path: "~/Membrane/membrane_rpicam_plugin", override: true}, + {:membrane_h264_plugin, "~> 0.9.0"}, + {:membrane_http_adaptive_stream_plugin, "~> 0.18.0"}, + {:membrane_aac_plugin, github: "membraneframework/membrane_aac_plugin", branch: "remove-crc-calculation", override: true}, + + # Allow Nerves.Runtime on host to support development, testing and CI. + # See config/host.exs for usage. + {:nerves_runtime, "~> 0.13.0"}, + + # Dependencies for all targets except :host + {:nerves_pack, "~> 0.7.0", targets: @all_targets}, + + # Dependencies for specific targets + # NOTE: It's generally low risk and recommended to follow minor version + # bumps to Nerves systems. Since these include Linux kernel and Erlang + # version updates, please review their release notes in case + # changes to your application are needed. + {:nerves_system_rpi, "~> 1.24", runtime: false, targets: :rpi}, + {:nerves_system_rpi0, "~> 1.24", runtime: false, targets: :rpi0}, + {:nerves_system_rpi2, "~> 1.24", runtime: false, targets: :rpi2}, + {:nerves_system_rpi3, "~> 1.24", runtime: false, targets: :rpi3}, + {:nerves_system_rpi3a, "~> 1.24", runtime: false, targets: :rpi3a}, + {:nerves_system_rpi4, "~> 1.24", runtime: false, targets: :rpi4}, + {:nerves_system_bbb, "~> 2.19", runtime: false, targets: :bbb}, + {:nerves_system_osd32mp1, "~> 0.15", runtime: false, targets: :osd32mp1}, + {:nerves_system_x86_64, "~> 1.24", runtime: false, targets: :x86_64}, + {:nerves_system_grisp2, "~> 0.8", runtime: false, targets: :grisp2}, + {:nerves_system_mangopi_mq_pro, "~> 0.6", runtime: false, targets: :mangopi_mq_pro} + ] + end + + def release do + [ + overwrite: true, + # Erlang distribution is not started automatically. + # See https://hexdocs.pm/nerves_pack/readme.html#erlang-distribution + cookie: "#{@app}_cookie", + include_erts: &Nerves.Release.erts/0, + steps: [&Nerves.Release.init/1, :assemble], + strip_beams: Mix.env() == :prod or [keep: ["Docs"]] + ] + end +end diff --git a/camera_to_hls_nerves/mix.lock b/camera_to_hls_nerves/mix.lock new file mode 100644 index 00000000..9e03efb1 --- /dev/null +++ b/camera_to_hls_nerves/mix.lock @@ -0,0 +1,89 @@ +%{ + "beam_notify": {:hex, :beam_notify, "1.1.0", "4ce38e27460a3c03b6f77c10c6f31458b035ebb1035cd52d4b3e771311837dba", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "8547a310702bfcea0e401534398617b940808ff6ad10c43dddc85c169de7b9cc"}, + "bimap": {:hex, :bimap, "1.3.0", "3ea4832e58dc83a9b5b407c6731e7bae87458aa618e6d11d8e12114a17afa4b3", [:mix], [], "hexpm", "bf5a2b078528465aa705f405a5c638becd63e41d280ada41e0f77e6d255a10b4"}, + "bunch": {:hex, :bunch, "1.6.0", "4775f8cdf5e801c06beed3913b0bd53fceec9d63380cdcccbda6be125a6cfd54", [:mix], [], "hexpm", "ef4e9abf83f0299d599daed3764d19e8eac5d27a5237e5e4d5e2c129cfeb9a22"}, + "bunch_native": {:hex, :bunch_native, "0.5.0", "8ac1536789a597599c10b652e0b526d8833348c19e4739a0759a2bedfd924e63", [:mix], [{:bundlex, "~> 1.0", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "24190c760e32b23b36edeb2dc4852515c7c5b3b8675b1a864e0715bdd1c8f80d"}, + "castore": {:hex, :castore, "1.0.4", "ff4d0fb2e6411c0479b1d965a814ea6d00e51eb2f58697446e9c41a97d940b28", [:mix], [], "hexpm", "9418c1b8144e11656f0be99943db4caf04612e3eaecefb5dae9a2a87565584f8"}, + "certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"}, + "circular_buffer": {:hex, :circular_buffer, "0.4.1", "477f370fd8cfe1787b0a1bade6208bbd274b34f1610e41f1180ba756a7679839", [:mix], [], "hexpm", "633ef2e059dde0d7b89bbab13b1da9d04c6685e80e68fbdf41282d4fae746b72"}, + "coerce": {:hex, :coerce, "1.0.1", "211c27386315dc2894ac11bc1f413a0e38505d808153367bd5c6e75a4003d096", [:mix], [], "hexpm", "b44a691700f7a1a15b4b7e2ff1fa30bebd669929ac8aa43cffe9e2f8bf051cf1"}, + "elixir_make": {:hex, :elixir_make, "0.7.7", "7128c60c2476019ed978210c245badf08b03dbec4f24d05790ef791da11aa17c", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "5bc19fff950fad52bbe5f211b12db9ec82c6b34a9647da0c2224b8b8464c7e6c"}, + "finch": {:hex, :finch, "0.16.0", "40733f02c89f94a112518071c0a91fe86069560f5dbdb39f9150042f44dcfb1a", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f660174c4d519e5fec629016054d60edd822cdfe2b7270836739ac2f97735ec5"}, + "gen_state_machine": {:hex, :gen_state_machine, "3.0.0", "1e57f86a494e5c6b14137ebef26a7eb342b3b0070c7135f2d6768ed3f6b6cdff", [:mix], [], "hexpm", "0a59652574bebceb7309f6b749d2a41b45fdeda8dbb4da0791e355dd19f0ed15"}, + "hackney": {:hex, :hackney, "1.20.1", "8d97aec62ddddd757d128bfd1df6c5861093419f8f7a4223823537bad5d064e2", [:rebar3], [{:certifi, "~> 2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fe9094e5f1a2a2c0a7d10918fee36bfec0ec2a979994cff8cfe8058cd9af38e3"}, + "hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"}, + "httpoison": {:hex, :httpoison, "2.2.0", "839298929243b872b3f53c3693fa369ac3dbe03102cefd0a126194738bf4bb0e", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a49a9337c2b671464948a00cff6a882d271c1c8e3d25a6ca14d0532cbd23f65a"}, + "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, + "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, + "mdns_lite": {:hex, :mdns_lite, "0.8.8", "e455f4d99dc708a9996ae8559f2893429ef39f0ca7d84ee63ce0e4b2f6a00a3f", [:mix], [{:vintage_net, "~> 0.7", [hex: :vintage_net, repo: "hexpm", optional: true]}], "hexpm", "221badb8e7b2a725ef642dc6121a61d8bfb7bad2a70afcc97bce6c9c7ce3c47c"}, + "membrane_aac_format": {:hex, :membrane_aac_format, "0.8.0", "515631eabd6e584e0e9af2cea80471fee6246484dbbefc4726c1d93ece8e0838", [:mix], [{:bimap, "~> 1.1", [hex: :bimap, repo: "hexpm", optional: false]}], "hexpm", "a30176a94491033ed32be45e51d509fc70a5ee6e751f12fd6c0d60bd637013f6"}, + "membrane_aac_plugin": {:git, "https://github.com/membraneframework/membrane_aac_plugin.git", "7b756b242cba72e568b14d5a5509f16a3b703375", [branch: "remove-crc-calculation"]}, + "membrane_cmaf_format": {:hex, :membrane_cmaf_format, "0.7.0", "573bfff6acf2371c5046b9174569f6316f4205e3d6e13e814bf7e613e5653a54", [:mix], [], "hexpm", "4ac6a24a33f61347a2714c982a5f84aa6207641f4de2ad5afde68a8b800da8de"}, + "membrane_core": {:hex, :membrane_core, "1.0.0", "1b543aefd952283be1f2a215a1db213aa4d91222722ba03cd35280622f1905ee", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.3", [hex: :qex, repo: "hexpm", optional: false]}, {:ratio, "~> 3.0", [hex: :ratio, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "352c90fd0a29942143c4bf7a727cc05c632e323f50a1a4e99321b1e8982f1533"}, + "membrane_file_plugin": {:hex, :membrane_file_plugin, "0.16.0", "7917f6682c22b9bcfc2ca20ed960eee0f7d03ad31fd5f59ed850f1fe3ddd545a", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "b0727998f75a9b4dab8a2baefdfc13c3eac00a04e061ab1b0e61dc5566927acc"}, + "membrane_h264_format": {:hex, :membrane_h264_format, "0.6.1", "44836cd9de0abe989b146df1e114507787efc0cf0da2368f17a10c47b4e0738c", [:mix], [], "hexpm", "4b79be56465a876d2eac2c3af99e115374bbdc03eb1dea4f696ee9a8033cd4b0"}, + "membrane_h264_plugin": {:hex, :membrane_h264_plugin, "0.9.0", "4b76079489451794c27993fbe6108f10a34068d3034985dc73d601e46266ef90", [:mix], [{:bunch, "~> 1.4", [hex: :bunch, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:membrane_h264_format, "~> 0.6.0", [hex: :membrane_h264_format, repo: "hexpm", optional: false]}], "hexpm", "7ecb9fdbe26304a577d9e32895aeee963b0a4bcc01fd77ecd9aebabdafbce58d"}, + "membrane_h265_format": {:hex, :membrane_h265_format, "0.2.0", "1903c072cf7b0980c4d0c117ab61a2cd33e88782b696290de29570a7fab34819", [:mix], [], "hexpm", "6df418bdf242c0d9f7dbf2e5aea4c2d182e34ac9ad5a8b8cef2610c290002e83"}, + "membrane_http_adaptive_stream_plugin": {:hex, :membrane_http_adaptive_stream_plugin, "0.18.0", "c83dd7e921dfd595b10e12d85bde313612ece8ca64d6ff27815156b900592d16", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:membrane_aac_plugin, "~> 0.18.0", [hex: :membrane_aac_plugin, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:membrane_h264_plugin, "~> 0.9.0", [hex: :membrane_h264_plugin, repo: "hexpm", optional: false]}, {:membrane_mp4_plugin, "~> 0.31.0", [hex: :membrane_mp4_plugin, repo: "hexpm", optional: false]}, {:membrane_tee_plugin, "~> 0.12.0", [hex: :membrane_tee_plugin, repo: "hexpm", optional: false]}, {:qex, "~> 0.5", [hex: :qex, repo: "hexpm", optional: false]}], "hexpm", "4e3a1ec9e84892d6f0b115183f4e4f3e202fcefe07aa722f7c2b107cd4403669"}, + "membrane_mp4_format": {:hex, :membrane_mp4_format, "0.8.0", "8c6e7d68829228117d333b4fbb030e7be829aab49dd8cb047fdc664db1812e6a", [:mix], [], "hexpm", "148dea678a1f82ccfd44dbde6f936d2f21255f496cb45a22cc6eec427f025522"}, + "membrane_mp4_plugin": {:hex, :membrane_mp4_plugin, "0.31.0", "1932c86e2f4a24aca1b99ee531a131fd0da1128db8975ba8f8738e3b1bbcfabd", [:mix], [{:bunch, "~> 1.5", [hex: :bunch, repo: "hexpm", optional: false]}, {:membrane_aac_format, "~> 0.8.0", [hex: :membrane_aac_format, repo: "hexpm", optional: false]}, {:membrane_cmaf_format, "~> 0.7.0", [hex: :membrane_cmaf_format, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:membrane_file_plugin, "~> 0.16.0", [hex: :membrane_file_plugin, repo: "hexpm", optional: false]}, {:membrane_h264_format, "~> 0.6.1", [hex: :membrane_h264_format, repo: "hexpm", optional: false]}, {:membrane_h264_plugin, "~> 0.9.0", [hex: :membrane_h264_plugin, repo: "hexpm", optional: false]}, {:membrane_h265_format, "~> 0.2.0", [hex: :membrane_h265_format, repo: "hexpm", optional: false]}, {:membrane_mp4_format, "~> 0.8.0", [hex: :membrane_mp4_format, repo: "hexpm", optional: false]}, {:membrane_opus_format, "~> 0.3.0", [hex: :membrane_opus_format, repo: "hexpm", optional: false]}], "hexpm", "9968e56e02085228974bf6a59c8858f3c0d9800a4e767c1b3b2f2890050c72f4"}, + "membrane_opus_format": {:hex, :membrane_opus_format, "0.3.0", "3804d9916058b7cfa2baa0131a644d8186198d64f52d592ae09e0942513cb4c2", [:mix], [], "hexpm", "8fc89c97be50de23ded15f2050fe603dcce732566fe6fdd15a2de01cb6b81afe"}, + "membrane_tee_plugin": {:hex, :membrane_tee_plugin, "0.12.0", "f94989b4080ef4b7937d74c1a14d3379577c7bd4c6d06e5a2bb41c351ad604d4", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "0d61c9ed5e68e5a75d54200e1c6df5739c0bcb52fee0974183ad72446a179887"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, + "mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"}, + "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, + "mint": {:hex, :mint, "1.5.1", "8db5239e56738552d85af398798c80648db0e90f343c8469f6c6d8898944fb6f", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "4a63e1e76a7c3956abd2c72f370a0d0aecddc3976dea5c27eccbecfa5e7d5b1e"}, + "muontrap": {:hex, :muontrap, "1.3.2", "8942689f0727160d97d61ff25156fb35b7a10e4e925c88378a69a4041cc04257", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "e29715dafdd8184c68516bad103ba1d58c7b3a7e1f5311fbf75c1d617caefa56"}, + "nerves": {:hex, :nerves, "1.10.4", "9c7e1f3e0e2896216c1b623dc05e05ec434d5f3f1d8291d4688b61b1a4f5540d", [:make, :mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "2e9c728f1d95e6ce998a4836d2f96f27777663953339d0f85fb68dc11ab48f1d"}, + "nerves_logging": {:hex, :nerves_logging, "0.2.2", "d0e878ac92e6907757fa9898b661250fa1cf50474763ca59ecfadca1c2235337", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "74c181c6f011ea0c2d52956ad82065a59d7c7b62ddfba5967b010ef125f460a5"}, + "nerves_motd": {:hex, :nerves_motd, "0.1.13", "5ab28a458e8ba8cf7f165573dd413f3ed0f9720dc08eda51c2bcb0d7edffa9ee", [:mix], [{:nerves_runtime, "~> 0.8", [hex: :nerves_runtime, repo: "hexpm", optional: false]}, {:nerves_time, "~> 0.4", [hex: :nerves_time, repo: "hexpm", optional: true]}, {:nerves_time_zones, "~> 0.1", [hex: :nerves_time_zones, repo: "hexpm", optional: true]}], "hexpm", "f3fee43ab52181b0de015eec4a9835b99526170ac83a0f621a155f458e1c9eeb"}, + "nerves_pack": {:hex, :nerves_pack, "0.7.0", "bc93834edbb9321b180dc104440070279eb02159359715f68f770e74ed86a582", [:mix], [{:mdns_lite, "~> 0.8", [hex: :mdns_lite, repo: "hexpm", optional: false]}, {:nerves_motd, "~> 0.1", [hex: :nerves_motd, repo: "hexpm", optional: false]}, {:nerves_runtime, "~> 0.6", [hex: :nerves_runtime, repo: "hexpm", optional: false]}, {:nerves_ssh, "~> 0.3", [hex: :nerves_ssh, repo: "hexpm", optional: false]}, {:nerves_time, "~> 0.3", [hex: :nerves_time, repo: "hexpm", optional: false]}, {:ring_logger, "~> 0.8", [hex: :ring_logger, repo: "hexpm", optional: false]}, {:vintage_net, "~> 0.10", [hex: :vintage_net, repo: "hexpm", optional: false]}, {:vintage_net_direct, "~> 0.10", [hex: :vintage_net_direct, repo: "hexpm", optional: false]}, {:vintage_net_ethernet, "~> 0.10", [hex: :vintage_net_ethernet, repo: "hexpm", optional: false]}, {:vintage_net_wifi, "~> 0.10", [hex: :vintage_net_wifi, repo: "hexpm", optional: false]}], "hexpm", "65a43ea78c10938c87c72d6d42a82c05e831e9a95a0ea26fe8f9d848c009cc57"}, + "nerves_runtime": {:hex, :nerves_runtime, "0.13.6", "aef9cb5e6232605d4e5421b297f41cde0535a53913c21e51c7ebe6c71c1b9cf6", [:mix], [{:nerves_logging, "~> 0.2.0", [hex: :nerves_logging, repo: "hexpm", optional: false]}, {:nerves_uevent, "~> 0.1.0", [hex: :nerves_uevent, repo: "hexpm", optional: false]}, {:uboot_env, "~> 0.3.0 or ~> 1.0", [hex: :uboot_env, repo: "hexpm", optional: false]}], "hexpm", "44b031f46542079d67d3ef0bd7b0c966e580909dd5cc61b7825a76e881e7cd5a"}, + "nerves_ssh": {:hex, :nerves_ssh, "0.4.3", "32540ad52a9781b7b1a1427ea1d282a9129f16b40f0a06de2074019ed455e760", [:mix], [{:nerves_runtime, "~> 0.11", [hex: :nerves_runtime, repo: "hexpm", optional: false]}, {:ssh_subsystem_fwup, "~> 0.5", [hex: :ssh_subsystem_fwup, repo: "hexpm", optional: false]}], "hexpm", "dfd079e4609d1d231dd29a9588534957a24c0baed1f434233dbfc2a679ea14d8"}, + "nerves_system_bbb": {:hex, :nerves_system_bbb, "2.19.1", "433cbd58ba177b03244b720ee71790d0c6d050e0f6b4a7947cc5f663dd9782eb", [:mix], [{:nerves, "~> 1.6.0 or ~> 1.7.15 or ~> 1.8", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.24.1", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_toolchain_armv7_nerves_linux_gnueabihf, "~> 1.8.0", [hex: :nerves_toolchain_armv7_nerves_linux_gnueabihf, repo: "hexpm", optional: false]}], "hexpm", "f0d7d6e1b68e5fcf1b2022e34a67f879e0ce2222db1ed0c2563b80010688b535"}, + "nerves_system_br": {:hex, :nerves_system_br, "1.24.1", "2c9df0bee3bc01a971e1d72a5b137fe9448a74ba1fdd0da02c52e291b468f8a7", [:mix], [], "hexpm", "d13ce0501f4db51869628d138edf5bffbb4fe38f3afa9f9f1e5371f7501535ff"}, + "nerves_system_grisp2": {:hex, :nerves_system_grisp2, "0.8.1", "6804234b44c3b8d7ceec794a1506d6cd707b1c5b62307a1c38f3189f255a7a85", [:mix], [{:nerves, "~> 1.6.0 or ~> 1.7.15 or ~> 1.8", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.24.1", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_toolchain_armv7_nerves_linux_gnueabihf, "~> 1.8.0", [hex: :nerves_toolchain_armv7_nerves_linux_gnueabihf, repo: "hexpm", optional: false]}], "hexpm", "4a34ab31260975ad6deab0309c6a4993776bb8ebe8e5660d2776471be7e50bbe"}, + "nerves_system_mangopi_mq_pro": {:hex, :nerves_system_mangopi_mq_pro, "0.6.1", "9c6db766bdc880d49deaf28d722b5ba3e6dbbfc91bc89703055b85e655d27ced", [:mix], [{:nerves, "~> 1.6.0 or ~> 1.7.15 or ~> 1.8", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.24.1", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_toolchain_riscv64_nerves_linux_gnu, "~> 1.8.0", [hex: :nerves_toolchain_riscv64_nerves_linux_gnu, repo: "hexpm", optional: false]}], "hexpm", "3bc073e0ee35deb3ed71b24289fda23cda46301490ef84fc31d303983ba6fd11"}, + "nerves_system_osd32mp1": {:hex, :nerves_system_osd32mp1, "0.15.1", "f96c68a9c0d15a874d88369ee6dd54575e1ec2cea5e49661eb55198377fec26b", [:mix], [{:nerves, "~> 1.6.0 or ~> 1.7.15 or ~> 1.8", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.24.1", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_toolchain_armv7_nerves_linux_gnueabihf, "~> 1.8.0", [hex: :nerves_toolchain_armv7_nerves_linux_gnueabihf, repo: "hexpm", optional: false]}], "hexpm", "ee825f3773960826f6d9a12316ac909f3ed21da42649d4a5b941623937f23095"}, + "nerves_system_rpi": {:hex, :nerves_system_rpi, "1.24.1", "e6d161edf9a9a7f6fbdd49d4cd16b127e48ee35557335422e8b03d851c920453", [:mix], [{:nerves, "~> 1.6.0 or ~> 1.7.15 or ~> 1.8", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.24.1", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_toolchain_armv6_nerves_linux_gnueabihf, "~> 1.8.0", [hex: :nerves_toolchain_armv6_nerves_linux_gnueabihf, repo: "hexpm", optional: false]}], "hexpm", "9280cec6e399224f96a15c563405f2259215cd37d77c3872a9859ef148c31b8a"}, + "nerves_system_rpi0": {:hex, :nerves_system_rpi0, "1.24.1", "f84d13a4558aaa12af0e19f80ca177e3df86256472e24c1151e4d68b36b3859f", [:mix], [{:nerves, "~> 1.6.0 or ~> 1.7.15 or ~> 1.8", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.24.1", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_toolchain_armv6_nerves_linux_gnueabihf, "~> 1.8.0", [hex: :nerves_toolchain_armv6_nerves_linux_gnueabihf, repo: "hexpm", optional: false]}], "hexpm", "87e5bb5ad5a863b851a0dc89cbd971a3eedaa54eeee201f0bf440a2a5f008031"}, + "nerves_system_rpi2": {:hex, :nerves_system_rpi2, "1.24.1", "45c8647b12084135ec62ac652083ae4b20c870ea3e8f7d74aed039ddfda747dc", [:mix], [{:nerves, "~> 1.5.4 or ~> 1.6.0 or ~> 1.7.15 or ~> 1.8", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.24.1", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_toolchain_armv7_nerves_linux_gnueabihf, "~> 1.8.0", [hex: :nerves_toolchain_armv7_nerves_linux_gnueabihf, repo: "hexpm", optional: false]}], "hexpm", "f319eef5eba8892b52d5df3e3bc3b343eb44460d24b2029bc7f92caa6c9bca81"}, + "nerves_system_rpi3": {:hex, :nerves_system_rpi3, "1.24.1", "7ec035c7ff7c420a34a7e015dc37bbe5461a41b3fef2e2e07916db1aee28515e", [:mix], [{:nerves, "~> 1.5.4 or ~> 1.6.0 or ~> 1.7.15 or ~> 1.8", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.24.1", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_toolchain_armv7_nerves_linux_gnueabihf, "~> 1.8.0", [hex: :nerves_toolchain_armv7_nerves_linux_gnueabihf, repo: "hexpm", optional: false]}], "hexpm", "4a5bccb59d271d58983598d5fcd5b75270a8fc5131cde9adcc9f071e01637e62"}, + "nerves_system_rpi3a": {:hex, :nerves_system_rpi3a, "1.24.1", "868face3ff211fad45ac288b8c51e8b16c5a2b3e6967d9f05bbe98223b75bc5d", [:mix], [{:nerves, "~> 1.5.4 or ~> 1.6.0 or ~> 1.7.15 or ~> 1.8", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.24.1", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_toolchain_armv7_nerves_linux_gnueabihf, "~> 1.8.0", [hex: :nerves_toolchain_armv7_nerves_linux_gnueabihf, repo: "hexpm", optional: false]}], "hexpm", "a359025273ba90ec0896c13ee0ed921f7d5c82132e6944f079ab109e822bfff7"}, + "nerves_system_rpi4": {:hex, :nerves_system_rpi4, "1.24.1", "a6f61fa0a76dd2507266ca2d8b66db16f4c65899bd4f3f59a53f54f74a00dac2", [:mix], [{:nerves, "~> 1.5.4 or ~> 1.6.0 or ~> 1.7.15 or ~> 1.8", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.24.1", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_toolchain_aarch64_nerves_linux_gnu, "~> 1.8.0", [hex: :nerves_toolchain_aarch64_nerves_linux_gnu, repo: "hexpm", optional: false]}], "hexpm", "57fdf3e6551716be2cca2ac05eeef33be9603643e36b799b347a20b43997fcc0"}, + "nerves_system_rpi4_membrane": {:git, "https://github.com/membraneframework-labs/nerves_system_rpi4_membrane.git", "ad33f48648eee38c2c967972006ba8b48f25f461", []}, + "nerves_system_x86_64": {:hex, :nerves_system_x86_64, "1.24.1", "168f9f0182658f3d3912764675d0fa4bf95d254cfb5e011faf42814a887efbca", [:mix], [{:nerves, "~> 1.5.4 or ~> 1.6.0 or ~> 1.7.15 or ~> 1.8", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.24.1", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_toolchain_x86_64_nerves_linux_musl, "~> 1.8.0", [hex: :nerves_toolchain_x86_64_nerves_linux_musl, repo: "hexpm", optional: false]}], "hexpm", "461dce58907a1e0b7c5013d25581b628e1a2ae11056da23005ddf2aee57b685b"}, + "nerves_time": {:hex, :nerves_time, "0.4.6", "f02e5e866149f3884a4b125104a5b677f7e61d271c1f7d87bc989197dc02dae5", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:muontrap, "~> 0.5 or ~> 1.0", [hex: :muontrap, repo: "hexpm", optional: false]}], "hexpm", "1fecb9e9dd098c0e93d35205a79e604831779f2d2313cfe7c31d181678e26ce6"}, + "nerves_toolchain_aarch64_nerves_linux_gnu": {:hex, :nerves_toolchain_aarch64_nerves_linux_gnu, "1.8.0", "40f7fe58737aaa9c6beee0e3599cca2265d1b4e40d7ab2713d7ad872349f21c2", [:mix], [{:nerves, "~> 1.4", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_toolchain_ctng, "~> 1.9.3", [hex: :nerves_toolchain_ctng, repo: "hexpm", optional: false]}], "hexpm", "c06a16b54634bbab7348ee7686e3b02574e0af742144c406b0f196b5b374349c"}, + "nerves_toolchain_armv6_nerves_linux_gnueabihf": {:hex, :nerves_toolchain_armv6_nerves_linux_gnueabihf, "1.8.0", "ac380cc3c20d0fe20256c4366548f5e099813602cc00f3433c3d426d7978f721", [:mix], [{:nerves, "~> 1.0", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_toolchain_ctng, "~> 1.9.3", [hex: :nerves_toolchain_ctng, repo: "hexpm", optional: false]}], "hexpm", "d9d5182ba20fb14463f4d4be578dd04d79616bc2896c09eeb9f26d60990b750d"}, + "nerves_toolchain_armv7_nerves_linux_gnueabihf": {:hex, :nerves_toolchain_armv7_nerves_linux_gnueabihf, "1.8.0", "2286e6272c340c3f49a29632321ad1ff6d8d09ddf130669d42530430bf13b3a7", [:mix], [{:nerves, "~> 1.0", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_toolchain_ctng, "~> 1.9.3", [hex: :nerves_toolchain_ctng, repo: "hexpm", optional: false]}], "hexpm", "099e109947165275d6050f561757827f2d10dd63fa6fd7cbbae5ed57b9f748ee"}, + "nerves_toolchain_ctng": {:hex, :nerves_toolchain_ctng, "1.9.3", "60e87fde05988c4264babc8d68a9221c7b8fe5dc195b7d1526f29b8e626c735c", [:mix], [{:nerves, "~> 1.0", [hex: :nerves, repo: "hexpm", optional: false]}], "hexpm", "2b6edb0687b7f78d3fa49958d759f647e351b23c1f59f637c617a6dc179994ae"}, + "nerves_toolchain_riscv64_nerves_linux_gnu": {:hex, :nerves_toolchain_riscv64_nerves_linux_gnu, "1.8.0", "576b0e7d95a04cb025deff72a7722b9b26d7943af581a1488513e1da12e946b5", [:mix], [{:nerves, "~> 1.4", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_toolchain_ctng, "~> 1.9.3", [hex: :nerves_toolchain_ctng, repo: "hexpm", optional: false]}], "hexpm", "f73ab2d65396907f84c00f47c85d958662f5c31e70c90a52df56eb3b01059ccc"}, + "nerves_toolchain_x86_64_nerves_linux_musl": {:hex, :nerves_toolchain_x86_64_nerves_linux_musl, "1.8.0", "0d766d676436820017ae7f22e9eec35d42071387d1a1d420a8ef513c46e3990a", [:mix], [{:nerves, "~> 1.0", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_toolchain_ctng, "~> 1.9.3", [hex: :nerves_toolchain_ctng, repo: "hexpm", optional: false]}], "hexpm", "8fa0c79f42858e4295f874e207c5be8bfb17a974de2be156fb8d8338e897f92a"}, + "nerves_uevent": {:hex, :nerves_uevent, "0.1.0", "651111a46be9a238560cbf7946989fc500e5f33d7035fd9ea7194d07a281bc19", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:property_table, "~> 0.2.0", [hex: :property_table, repo: "hexpm", optional: false]}], "hexpm", "cb0b1993c3ed3cefadbcdb534e910af0661f95c3445796ce8a7c8be3519a4e5f"}, + "nimble_options": {:hex, :nimble_options, "1.0.2", "92098a74df0072ff37d0c12ace58574d26880e522c22801437151a159392270e", [:mix], [], "hexpm", "fd12a8db2021036ce12a309f26f564ec367373265b53e25403f0ee697380f1b8"}, + "nimble_pool": {:hex, :nimble_pool, "1.0.0", "5eb82705d138f4dd4423f69ceb19ac667b3b492ae570c9f5c900bb3d2f50a847", [:mix], [], "hexpm", "80be3b882d2d351882256087078e1b1952a28bf98d0a287be87e4a24a710b67a"}, + "numbers": {:hex, :numbers, "5.2.4", "f123d5bb7f6acc366f8f445e10a32bd403c8469bdbce8ce049e1f0972b607080", [:mix], [{:coerce, "~> 1.0", [hex: :coerce, repo: "hexpm", optional: false]}, {:decimal, "~> 1.9 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "eeccf5c61d5f4922198395bf87a465b6f980b8b862dd22d28198c5e6fab38582"}, + "one_dhcpd": {:hex, :one_dhcpd, "2.0.2", "49ae0bc4ecc4bf958a2e3eb9c25149dbb37102b77163ed3f9ebadfe49090b44a", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "f95de030d199c834dacacc8420881e21c27cec60371711bdffd2fc183234cbf8"}, + "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"}, + "property_table": {:hex, :property_table, "0.2.4", "c53e3684b6da8cb77ceee89f8c7a980d6c626429a6653473db29c210b9d53103", [:mix], [], "hexpm", "feae0e06fee2740452dd8375eb2c3407ece12317525491345f141dcbe1b9442c"}, + "qex": {:hex, :qex, "0.5.1", "0d82c0f008551d24fffb99d97f8299afcb8ea9cf99582b770bd004ed5af63fd6", [:mix], [], "hexpm", "935a39fdaf2445834b95951456559e9dc2063d0a055742c558a99987b38d6bab"}, + "ratio": {:hex, :ratio, "3.0.2", "60a5976872a4dc3d873ecc57eed1738589e99d1094834b9c935b118231297cfb", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:numbers, "~> 5.2.0", [hex: :numbers, repo: "hexpm", optional: false]}], "hexpm", "3a13ed5a30ad0bfd7e4a86bf86d93d2b5a06f5904417d38d3f3ea6406cdfc7bb"}, + "req": {:hex, :req, "0.4.5", "2071bbedd280f107b9e33e1ddff2beb3991ec1ae06caa2cca2ab756393d8aca5", [: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", "dd23e9c7303ddeb2dee09ff11ad8102cca019e38394456f265fb7b9655c64dd8"}, + "ring_logger": {:hex, :ring_logger, "0.10.5", "3cbf444df171e80da1d7e25ecc226375bdda8f31b7b5892784cc2d26d01e5c66", [:mix], [{:circular_buffer, "~> 0.4.0", [hex: :circular_buffer, repo: "hexpm", optional: false]}], "hexpm", "16ac1fb35eea6e0ebeedde695ed973cf27fe43e76d4877bd593b9f8efc754ffe"}, + "secure_random": {:hex, :secure_random, "0.5.1", "c5532b37c89d175c328f5196a0c2a5680b15ebce3e654da37129a9fe40ebf51b", [:mix], [], "hexpm", "1b9754f15e3940a143baafd19da12293f100044df69ea12db5d72878312ae6ab"}, + "shmex": {:hex, :shmex, "0.5.0", "7dc4fb1a8bd851085a652605d690bdd070628717864b442f53d3447326bcd3e8", [:mix], [{:bunch_native, "~> 0.5.0", [hex: :bunch_native, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.0", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "b67bb1e22734758397c84458dbb746519e28eac210423c267c7248e59fc97bdc"}, + "shoehorn": {:hex, :shoehorn, "0.9.1", "8e12670024c2942e3c2fdd27cd5a034ee0337ee7c25c37b3ebc2ad482de67199", [:mix], [], "hexpm", "fccd040ac22de9b3cc111bbf78a363832c7210010a3fff4a550fbb2f10de0692"}, + "ssh_subsystem_fwup": {:hex, :ssh_subsystem_fwup, "0.6.1", "628f8e3795de5f1d0e7b3b55de4248ab0a77ab4c47e3cd282f1dda89d6354a9f", [:mix], [], "hexpm", "babdae337f2dc011ab5478662b4ec850650d7acfb165662ae47f6f0ce8892499"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, + "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, + "toolshed": {:hex, :toolshed, "0.3.1", "9c7f90c015e8f6034eb43c4f5203ac6226d0db5f1a575ccf69af94b5d77cba64", [:mix], [{:nerves_runtime, "~> 0.8", [hex: :nerves_runtime, repo: "hexpm", optional: true]}], "hexpm", "92fc4a792cd1dbc4fd6963431b5c3511e88454c68e32a30cf17366905b43612e"}, + "uboot_env": {:hex, :uboot_env, "1.0.1", "b0e136cf1a561412ff7db23ed2b6df18d7c7ce2fc59941afd851006788a67f3d", [:mix], [], "hexpm", "b6d4fe7c24123be57ed946c48116d23173e37944bc945b8b76fccc437909c60b"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, + "unifex": {:hex, :unifex, "1.1.0", "26b1bcb6c3b3454e1ea15f85b2e570aaa5b5c609566aa9f5c2e0a8b213379d6b", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.0", [hex: :bundlex, repo: "hexpm", optional: false]}, {:shmex, "~> 0.5.0", [hex: :shmex, repo: "hexpm", optional: false]}], "hexpm", "d8f47e9e3240301f5b20eec5792d1d4341e1a3a268d94f7204703b48da4aaa06"}, + "vintage_net": {:hex, :vintage_net, "0.13.5", "b02cbb44434eba68d8e991e7c9a75d491da73c3073ff4823843e66f451d6f088", [:make, :mix], [{:beam_notify, "~> 0.2.0 or ~> 1.0", [hex: :beam_notify, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:gen_state_machine, "~> 2.0.0 or ~> 2.1.0 or ~> 3.0.0", [hex: :gen_state_machine, repo: "hexpm", optional: false]}, {:muontrap, "~> 0.5.1 or ~> 0.6.0 or ~> 1.0", [hex: :muontrap, repo: "hexpm", optional: false]}, {:property_table, "~> 0.2.0", [hex: :property_table, repo: "hexpm", optional: false]}], "hexpm", "67e04b8eaa40600bbea4902aba363792598b31cf144f6033d93d7662b60519ad"}, + "vintage_net_direct": {:hex, :vintage_net_direct, "0.10.7", "940561c375f04d6734ac78100ae1d8ef790ffd7e966f70efb525230fa1bc5774", [:mix], [{:one_dhcpd, "~> 0.2.3 or ~> 1.0 or ~> 2.0", [hex: :one_dhcpd, repo: "hexpm", optional: false]}, {:vintage_net, "~> 0.9.1 or ~> 0.10.0 or ~> 0.11.0 or ~> 0.12.0 or ~> 0.13.0", [hex: :vintage_net, repo: "hexpm", optional: false]}], "hexpm", "c040e9c33220495c28ba4464c5924da00bd4949627c4cb9c99ba1ed96f7b9429"}, + "vintage_net_ethernet": {:hex, :vintage_net_ethernet, "0.11.2", "ef67db5ace9ad5ca5bf229a507247f9eb45b847dc0ff694a6e8a156ed9c5915d", [:mix], [{:vintage_net, "~> 0.12.0 or ~> 0.13.0", [hex: :vintage_net, repo: "hexpm", optional: false]}], "hexpm", "6915f9e15e1aa15e52d1948f318ce5109181d1ad7aaa50016bad5dd8e22df9ea"}, + "vintage_net_wifi": {:hex, :vintage_net_wifi, "0.11.7", "dbebd230366a62f62bdcf3ca72e9d6e18d31854a94e726a213ed4419b517ab3e", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:vintage_net, "~> 0.12.0 or ~> 0.13.0", [hex: :vintage_net, repo: "hexpm", optional: false]}], "hexpm", "2e3eb5bb6f60bcbfccd3d302ff80ccf52f5dd42abbffae153604e80163fbbc9e"}, + "zarex": {:hex, :zarex, "1.0.3", "a9e9527a1c31df7f39499819bd76ccb15b0b4e479eed5a4a40db9df7ad7db25c", [:mix], [], "hexpm", "4400a7d33bbf222383ce9a3d5ec9411798eb2b12e86c65ad8e6ac08d8116ca8b"}, +} diff --git a/camera_to_hls_nerves/rel/vm.args.eex b/camera_to_hls_nerves/rel/vm.args.eex new file mode 100644 index 00000000..3fb4e40d --- /dev/null +++ b/camera_to_hls_nerves/rel/vm.args.eex @@ -0,0 +1,60 @@ +## Customize flags given to the VM: http://erlang.org/doc/man/erl.html + +## Do not set -name or -sname here. Prefer configuring them at runtime +## Configure -setcookie in the mix.exs release section or at runtime + +## Number of dirty schedulers doing IO work (file, sockets, and others) +##+SDio 5 + +## Increase number of concurrent ports/sockets +##+Q 65536 + +## Tweak GC to run more often +##-env ERL_FULLSWEEP_AFTER 10 + +## Use Ctrl-C to interrupt the current shell rather than invoking the emulator's +## break handler and possibly exiting the VM. ++Bc + +# Allow time warps so that the Erlang system time can more closely match the +# OS system time. ++C multi_time_warp + +## Load code at system startup +## See http://erlang.org/doc/system_principles/system_principles.html#code-loading-strategy +-mode embedded + +# Load code as per the boot script since not using archives +# See https://www.erlang.org/doc/man/init.html#command-line-flags +-code_path_choice strict + +## Disable scheduler busy wait to reduce idle CPU usage and avoid delaying +## other OS processes. See http://erlang.org/doc/man/erl.html#+sbwt ++sbwt none ++sbwtdcpu none ++sbwtdio none + +## Save the shell history between reboots +## See http://erlang.org/doc/man/kernel_app.html for additional options +-kernel shell_history enabled + +## Enable heartbeat monitoring of the Erlang runtime system +-heart -env HEART_BEAT_TIMEOUT 30 + +## Start the Elixir shell + +-noshell +-user elixir +-run elixir start_iex + + +## Enable colors in the shell +-elixir ansi_enabled true + +## Options added after -extra are interpreted as plain arguments and can be +## retrieved using :init.get_plain_arguments(). Options before the "--" are +## interpreted by Elixir and anything afterwards is left around for other IEx +## and user applications. +-extra --no-halt +-- +--dot-iex /etc/iex.exs diff --git a/camera_to_hls_nerves/rootfs_overlay/etc/iex.exs b/camera_to_hls_nerves/rootfs_overlay/etc/iex.exs new file mode 100644 index 00000000..74ee8d61 --- /dev/null +++ b/camera_to_hls_nerves/rootfs_overlay/etc/iex.exs @@ -0,0 +1,4 @@ +NervesMOTD.print() + +# Add Toolshed helpers to the IEx session +use Toolshed diff --git a/camera_to_hls_nerves/rootfs_overlay/stream.html b/camera_to_hls_nerves/rootfs_overlay/stream.html new file mode 100644 index 00000000..6864d784 --- /dev/null +++ b/camera_to_hls_nerves/rootfs_overlay/stream.html @@ -0,0 +1,20 @@ + + + + + +
+ The video should show up below. If it doesn't, make sure that the index.m3u8 file is generated in the /data/output + directory and refresh the page. +
+ + + + + + \ No newline at end of file