Search documentation of mob

# Mob.Audio (mob v0.6.18)

Copy Markdown View Source

Microphone recording and audio playback.

Recording requires `:microphone` permission (`Mob.Permissions.request/2`). iOS additionally needs `NSMicrophoneUsageDescription` in `Info.plist`; Android needs `RECORD_AUDIO` in `AndroidManifest.xml`. The default `mix mob.new` templates ship both. See the permissions guide for the cross-platform table.

Playback requires no permission.

## Recording

    Mob.Audio.start_recording(socket, format: :aac, quality: :medium)
    Mob.Audio.stop_recording(socket)
    # → handle_info({:audio, :recorded, %{path: path, duration: seconds}}, socket)
    # → handle_info({:audio, :error,    reason},                            socket)

## Playback

    Mob.Audio.play(socket, "/path/to/file.m4a")
    Mob.Audio.play(socket, "/path/to/file.m4a", loop: true, volume: 0.8)
    Mob.Audio.stop_playback(socket)
    Mob.Audio.set_volume(socket, 0.5)
    # → handle_info({:audio, :playback_finished, %{path: path}}, socket)
    # → handle_info({:audio, :playback_error,    %{reason: reason}}, socket)

iOS: `AVAudioPlayer` / `AVPlayer`. Android: `MediaPlayer`.

## Summary

### Types

format()
quality()

### Functions

play(socket, path, opts \\ [])

Play an audio file. Stops any currently playing audio first.

play_at(socket, path, at_wall_ms, opts \\ [])

Schedule `path` to begin playing at absolute local wall-clock time `at_wall_ms` (in `System.system_time(:millisecond)` terms — caller is responsible for translating from a server-supplied target time via their own clock-sync component).

set_volume(socket, volume)

Adjust playback volume (0.0–1.0) without stopping playback.

start_recording(socket, opts \\ [])

Start recording audio from the microphone.

stop_playback(socket)

Stop the currently playing audio.

stop_recording(socket)

Stop the in-progress recording and save it to a temp file. Result arrives as `{:audio, :recorded, %{path: ..., duration: ...}}`.

## Types

# format()

    @type format() :: :aac | :wav

# quality()

    @type quality() :: :low | :medium | :high

## Functions

# play(socket, path, opts \\ [])

    @spec play(Mob.Socket.t(), String.t(), keyword()) :: Mob.Socket.t()

Play an audio file. Stops any currently playing audio first.

Options:

- `loop: boolean` (default `false`)
- `volume: float 0.0–1.0` (default `1.0`)

Result arrives as:

- `{:audio, :playback_finished, %{path: path}}`
- `{:audio, :playback_error, %{reason: reason}}`

# play_at(socket, path, at_wall_ms, opts \\ [])

    @spec play_at(Mob.Socket.t(), String.t(), integer(), keyword()) :: Mob.Socket.t()

Schedule `path` to begin playing at absolute local wall-clock time `at_wall_ms` (in `System.system_time(:millisecond)` terms — caller is responsible for translating from a server-supplied target time via their own clock-sync component).

The audio hardware clock — not BEAM's timer wheel — fires playback at the requested instant. Multiple `play_at/3` calls accumulate on the player's timeline (call `stop_playback/1` to flush). If `at_wall_ms` is already in the past, the buffer plays as soon as the audio engine can.

Options:

- `volume: float 0.0–1.0` (default `1.0`)

Result arrives as `{:audio, :playback_finished, %{path: path}}` when the scheduled buffer drains, or `{:audio, :playback_error, %{reason: reason}}` if the file fails to open.

iOS: `AVAudioEngine` + `AVAudioPlayerNode.scheduleBuffer(_:at:options:)`, with the `at:` `AVAudioTime` constructed from `mach_absolute_time` so the buffer starts at the requested host time.

Android: TODO — falls back to immediate playback on Android until the AAudio port lands.

# set_volume(socket, volume)

    @spec set_volume(Mob.Socket.t(), float()) :: Mob.Socket.t()

Adjust playback volume (0.0–1.0) without stopping playback.

# start_recording(socket, opts \\ [])

    @spec start_recording(
      Mob.Socket.t(),
      keyword()
    ) :: Mob.Socket.t()

Start recording audio from the microphone.

Options:

- `format: :aac | :wav` (default `:aac`)

- `quality: :low | :medium | :high` (default `:medium`)

# stop_playback(socket)

    @spec stop_playback(Mob.Socket.t()) :: Mob.Socket.t()

Stop the currently playing audio.

# stop_recording(socket)

    @spec stop_recording(Mob.Socket.t()) :: Mob.Socket.t()

Stop the in-progress recording and save it to a temp file. Result arrives as `{:audio, :recorded, %{path: ..., duration: ...}}`.