-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
558 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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] | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" | ||
}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
defmodule CameraToHlsNerves do | ||
@moduledoc """ | ||
Example of streaming live feed from a RaspberryPi camera to a browser with HLS | ||
""" | ||
end |
30 changes: 30 additions & 0 deletions
30
camera_to_hls_nerves/lib/nerves_membrane_demo/application.ex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Oops, something went wrong.