MobMedia.Engine behaviour (mob_media v0.1.0)

Copy Markdown View Source

What does the decoding behind MobMedia. The callbacks mirror the NIF (:mob_media_nif) one for one, so every engine speaks the same contract.

Shipped engines:

  • MobMedia.Engine.Native — the platform decoders (the default when the NIF is linked into the app).
  • MobMedia.Engine.Fake — no device: decodes WAV files in Elixir and plays back scripted results for any other path. For host tests and agents.
  • MobMedia.Engine.Unavailable — answers {:error, :unavailable} (the default when the NIF isn't linked, e.g. on the host).

Pick one with config :mob_media, engine: Module.

The contract

Each operation is called in a short-lived worker process that MobMedia owns, with a fresh ref. It returns at once: :ok when the work was started, or {:error, reason} when it couldn't be. After :ok the engine sends that process exactly one message, from any process or thread:

{:mob_media, ref, {:ok, {duration_ms, width, height, has_audio, has_video, mime}}}  # info/2
{:mob_media, ref, {:ok, bytes_written}}                                            # audio_pcm/5
{:mob_media, ref, {:ok, {width, height}}}                                          # frame/6
{:mob_media, ref, {:error, reason}}

duration_ms is -1 when unknown, width/height are 0 without video and mime is "" when unknown. audio_pcm/5 writes signed 16-bit little-endian interleaved PCM to out; frame/6 writes a JPEG there. The engine never deletes or renames out: MobMedia owns the files.

path exists (checked before the call). Reasons: :unsupported (not a format the platform can open or decode), :no_audio, :no_video, :decode_failed (the decoder failed part way), :io_error (couldn't write out), :not_found.

Summary

Types

What the engine delivers in {:mob_media, ref, result}.

Callbacks

Decode the first audio track of path to rate Hz, channels-channel s16le PCM written to out.

Whether this engine can do any work here.

Write the video frame of path at at_ms (clamped to the duration) as a JPEG of quality (1..100) to out, scaled down so neither side exceeds max_px (0: full size).

Read the duration, dimensions, tracks and MIME type of path.

A writable directory for the engine's temporary output files.

Types

result()

@type result() ::
  {:ok,
   {integer(), non_neg_integer(), non_neg_integer(), boolean(), boolean(),
    binary()}}
  | {:ok, non_neg_integer()}
  | {:ok, {pos_integer(), pos_integer()}}
  | {:error, term()}

What the engine delivers in {:mob_media, ref, result}.

Callbacks

audio_pcm(ref, path, out, rate, channels)

@callback audio_pcm(
  ref :: reference(),
  path :: binary(),
  out :: binary(),
  rate :: pos_integer(),
  channels :: 1 | 2
) :: :ok | {:error, term()}

Decode the first audio track of path to rate Hz, channels-channel s16le PCM written to out.

available?()

@callback available?() :: boolean()

Whether this engine can do any work here.

frame(ref, path, out, at_ms, max_px, quality)

@callback frame(
  ref :: reference(),
  path :: binary(),
  out :: binary(),
  at_ms :: non_neg_integer(),
  max_px :: non_neg_integer(),
  quality :: 1..100
) :: :ok | {:error, term()}

Write the video frame of path at at_ms (clamped to the duration) as a JPEG of quality (1..100) to out, scaled down so neither side exceeds max_px (0: full size).

info(ref, path)

@callback info(ref :: reference(), path :: binary()) :: :ok | {:error, term()}

Read the duration, dimensions, tracks and MIME type of path.

tmp_dir()

@callback tmp_dir() :: Path.t()

A writable directory for the engine's temporary output files.