elixir-vision / picam

Elixir library used to capture MJPEG video on a Raspberry Pi using the camera module.
Other
122 stars 27 forks source link
camera elixir hacktoberfest mjpeg nerves-project raspberry-pi video

Picam

Hex version

Picam is an Elixir library that provides a simple API for streaming MJPEG video and capturing JPEG stills using the camera module on Raspberry Pi devices running Linux.

Features currently supported by the API:

For specifics on the above features, please consult the Hex docs.

Requirements

Requirement Notes
Host Device Raspberry Pi 1, 2, 3, Zero/W Zero and Zero W require a special ribbon cable
Operating System Linux Works out of the box with Raspbian and Nerves builds
Camera Module V1, V2 Regular, NoIR. Note for V2 module, gpu_mem in /boot/config.txt must be set >= 192
C Libraries Broadcom VideoCore Located in /opt/vc by default. Override with VIDEOCORE_DIR

Installation

The package can be installed by adding picam to your list of dependencies in mix.exs:

def deps do
  [{:picam, "~> 0.4.0"}]
end

Usage

Picam uses a port application named raspijpgs that interfaces with the underlying Multi-Media Abstraction Layer (MMAL) API in VideoCore. The port is started by the Picam.Camera process.

For example, to write a JPEG still using the :sketch image effect to /tmp/frame.jpg:

iex(1)> Picam.Camera.start_link
{:ok, #PID<0.160.0>}

iex(2)> Picam.set_img_effect(:sketch)
:ok

iex(3)> Picam.set_size(640, 0) # 0 automatically calculates height
:ok

iex(4)> File.write!(Path.join(System.tmp_dir!, "frame.jpg"), Picam.next_frame)
:ok

iex(5)> Picam.set_img_effect(:none) # Disable the effect
:ok

If you receive an :unexpected_exit error immediately after starting the Picam.Camera process and you're using a V2 camera module, please check that you've set gpu_mem to a value >= 192 in /boot/config.txt. You can verify this has taken effect in your terminal using vcgencmd get_mem gpu.

More than likely you'll want to put the Picam.Camera process in your supervision tree rather than starting it manually:

# lib/my_app/application.ex

children = [
  worker(Picam.Camera, []),
  # ...
]

Faking the camera for development and testing

In order to facilitate running in dev and test modes on your development host, you can override the real Picam.Camera worker with Picam.FakeCamera by setting the :camera config option:

# config.exs

# ...

import_config "#{Mix.Project.config[:target]}.exs"
# config/host.exs

use Mix.Config
config :picam, camera: Picam.FakeCamera

This will cause Picam to use the FakeCamera back-end instead of the real Camera back-end, which streams a static image of the specified size at approximately the specified fps rate (using a naïve sleep-based delay between frames). In order for this to work, you will need to make sure you are staring the matching worker for your environment:

# lib/my_app/application.ex

camera = Application.get_env(:picam, :camera, Picam.Camera)

children = [
  worker(camera, []),
  # ...
]

When using the FakeCamera, all the normal Picam API commands will be validated but silently ignored, with the following exceptions:

Examples

The examples directory is where you can find other useful demos of Picam in action. More examples will be added over time.

Directory Demo
picam_http Streaming MJPEG video using plug

Limitations

Copyright and License

Copyright (c) 2013-2017, Broadcom Europe Ltd, Silvan Melchior, James Hughes, Frank Hunleth, Jeff Smith

Picam source code is licensed under the BSD 3-Clause License.