Skip to content

Media Synchronization

Describe how media flows between central storage and the tenant edge.

The node agent runs two sync loops:

  • Down (assets): polls GET /api/v1/nodes/media/manifest?since=<version> (304 when unchanged). The manifest lists assets by object_key, local_path, content_sha256 and size_bytes. Each object is fetched through the node-authenticated proxy GET /api/v1/nodes/media/object?key=… (MinIO is never reachable from the edge), streamed to a temp file, verified against its SHA-256, and atomically renamed into place under EDGE_MEDIA_ROOT. Files already matching the hash are skipped; a prune removes local assets no longer in the manifest.
  • Up (recordings): polls GET /api/v1/nodes/recordings/pending and uploads each file as multipart to POST /api/v1/nodes/recordings/<call_id>. See Recordings.
Terminal window
EDGE_MEDIA_ROOT=/var/lib/get2dial/media # playback root; MUST match the control plane
AGENT_MEDIA_SYNC_ENABLED=true
AGENT_MEDIA_SYNC_SECONDS=60
AGENT_MEDIA_SYNC_PRUNE=true # remove assets no longer in the manifest

A new voicemail-drop asset uploaded to the audio library changes the manifest version (its content_sha256 is the change key); on the next poll the node agent pulls just that object to EDGE_MEDIA_ROOT/tenants/<tenant>/…, after which FreeSWITCH can play it locally.

  • EDGE_MEDIA_ROOT must match the control plane’s expectation or the stamped voicemail/asset paths won’t resolve on the edge.
  • Sync is manifest- and hash-driven — assets transfer once and are reused; downloads are atomic so a half-written file is never played.