A Cloud-Native Pattern for Ingesting and Relaying Live Aerial Footage on Azure
Single-publisher RTMP ingest, multi-subscriber HTTPS delivery, device-independent playback, and cost-conscious Azure deployment
Executive Summary
The requirement is to make a live aerial feed from a drone first-person-view (FPV) controller available to many authorized subscribers on different devices over HTTPS. The recommended pattern separates the workload into four concerns: RTMP ingest, stream packaging, durable origin storage, and global HTTPS distribution.
A lightweight open-source media server—preferably SRS (Simple Realtime Server), with NGINX-RTMP retained as a fallback—runs in Azure Container Apps. It receives one RTMP publisher feed and converts it into HTTP Live Streaming (HLS): a frequently changing .m3u8 playlist and immutable .ts video segments. A storage sidecar uses a system-assigned managed identity and Azure role-based access control (RBAC) to move those artifacts from replica-local scratch storage to Azure Blob Storage. Azure Front Door then serves the HLS content over HTTPS and uses file-type-specific caching so subscriber scale is handled at the edge rather than by the ingest container.
This pattern is applicable beyond aerial footage. It addresses the common one-to-many live-video scenario in which a single publisher sends RTMP while web, mobile, and desktop subscribers consume HLS over HTTPS. It avoids dependence on the retired Azure Media Services product, minimizes always-on compute and commercial license costs, and preserves a path to commercial or ultra-low-latency servers if future requirements justify them.
Recommendation: validate an SRS-based dual-container Azure Container Apps deployment first; use Azure Blob Storage as the HLS origin and Azure Front Door as the distribution layer. Retain NGINX-RTMP as the implementation fallback and evaluate Ant Media or Wowza only if sub-second WebRTC, broadcast-grade transcoding, vendor support, or other advanced media capabilities become mandatory.
1. Problem and Design Objectives
Problem statement
Aerial footage from a drone FPV source must be ingested through Azure and relayed to multiple subscribers on different device types through secure HTTPS sessions. The publisher may be operating over variable cellular or Wi-Fi connectivity, while subscribers may include incident commanders, production teams, engineers, or public audiences using browsers and native applications.
Why the transport must change
RTMP—Real-Time Messaging Protocol—is a reliable, low-latency protocol commonly used to move live audio and video from an encoder to a media server. In the drone workflow, the aircraft sends video to the pilot’s controller or mobile device over a vendor radio or Wi-Fi link; the flight application encodes the feed, typically as H.264 video with AAC audio; and the application pushes the stream to an RTMP URL using a stream key. RTMP is suitable for contribution ingest, but normal browsers do not directly consume live RTMP. The ingest tier must therefore repackage or transcode the feed into an HTTP-deliverable format such as HLS or MPEG-DASH before a CDN can distribute it.
Primary objectives
• Accept a single RTMP publisher feed from a drone, controller, or equivalent live encoder.
• Deliver the live feed to many concurrent subscribers over HTTPS on iOS, Android, macOS, Windows, browsers, and application media players.
• Keep ingest compute small and independent from subscriber scale.
• Use Azure-native infrastructure services for hosting, identity, storage, and edge delivery without assuming a native replacement for Azure Media Services.
• Avoid storage account keys by using managed identity and Azure RBAC wherever the platform permits.
• Prevent stale playlists, playback loops, and unnecessary origin bandwidth through correct cache behavior.
• Support testability, operability, and an evolution path to higher resilience, adaptive bitrate, or ultra-low latency.
Representative use cases
• Emergency and public safety: provide a live aerial view to an operations center or incident commander.
• Broadcast and media: relay aerial video to production systems, OBS Studio, or public distribution platforms.
• Industrial inspection: let remote engineers monitor infrastructure, field assets, or construction progress.
2. Recommended Azure Architecture
End-to-end flow
1. Publisher: the drone application or controller pushes an H.264/AAC feed over RTMP through cellular or Wi-Fi.
2. Ingest and packaging: an Azure Container App runs SRS and accepts the RTMP stream on port 1935. SRS segments the feed into four-second HLS video files and maintains a rolling playlist.
3. Replica-local handoff: the media container writes the generated .ts segments and .m3u8 playlist to a shared, replica-scoped EmptyDir volume.
4. RBAC-based synchronization: a sidecar container monitors the shared directory and writes the HLS artifacts to Azure Blob Storage using the Container App’s managed identity and the Storage Blob Data Contributor role.
5. Origin: Azure Blob Storage provides durable HTTPS access to the HLS artifacts and decouples distribution from the lifecycle and capacity of the ingest replica.
6. Edge distribution: Azure Front Door uses Blob Storage as its origin, bypasses or nearly bypasses caching for the changing playlist, and aggressively caches immutable video segments.
7. Subscribers: browsers and applications request the HLS playlist through the Front Door HTTPS endpoint and retrieve video segments from the closest available edge cache.
Logical path: Drone application/controller → RTMP over cellular or Wi-Fi → SRS in Azure Container Apps → HLS playlist and segments → shared EmptyDir → identity-based sidecar synchronization → Azure Blob Storage origin → Azure Front Door edge cache → HTTPS HLS players on subscriber devices.
Why this separation matters
The ingest container processes the publisher stream once. Subscriber fan-out is performed by Azure Front Door, so adding viewers does not directly increase the media server’s outbound load. Blob Storage separates the origin from the transient container instance, and the sidecar separates media processing from cloud-storage authentication. This keeps the solution modular for development, test, operations, and future replacement of the media engine.
Azure product position
Azure Media Services has been retired, and there is no direct Azure-native replacement for its traditional RTMP ingest, packaging, and broadcast functions. Azure Communication Services targets real-time communications scenarios and is not a direct substitute for one-to-many RTMP-to-HLS broadcasting. The recommended design therefore combines Azure infrastructure services with an open-source or commercial media server. Relevant Microsoft guidance and migration information include Azure Media Services replacement guidance and Azure Container Apps storage mounts.
3. Component Design
3.1 Ingest and packager: Azure Container Apps with SRS
SRS is the preferred first implementation because it is lightweight, supports modern streaming workflows, and can run with a small resource allocation. The container’s scope is intentionally narrow: receive the RTMP publisher feed, create HLS artifacts, expose a health/test HTTP endpoint, and write into the shared directory. A baseline allocation discussed in the source design is 0.25 vCPU and 0.5 GiB for SRS; production sizing must be established by load and endurance testing.
The design uses four-second HLS fragments and a 20-second playlist window, retaining approximately five recent segments. Cleanup is enabled so obsolete segments do not accumulate in local storage. This produces practical low-buffer HLS delivery, though it is not equivalent to sub-second WebRTC.
3.2 Shared scratch space: EmptyDir
The two containers in one Container App replica share a replica-scoped EmptyDir volume. The media server writes HLS artifacts to this local scratch space, and the storage sidecar reads from the same location. This avoids holding an extended live stream in process memory, offers fast local writes, and makes the handoff explicit. EmptyDir is ephemeral: restart, rescheduling, or replica loss removes local files, so the design depends on rapid sidecar synchronization and the rolling nature of live HLS.
3.3 Storage synchronization and zero-trust access
Azure Container Apps file-share mounts traditionally require storage credentials at the infrastructure layer. To preserve a keyless application pattern, the design keeps the shared path local and delegates storage access to a sidecar such as rclone or Blobfuse2. The Container App receives a system-assigned managed identity, and that identity is assigned the Storage Blob Data Contributor role on the target storage scope. The sidecar obtains short-lived Azure credentials at runtime and writes the playlist and segments to Blob Storage without embedding a storage account key or connection string.
The sidecar must preserve the ordering and freshness requirements of live HLS: new segments should become readable before the playlist references them, playlist updates should be rapid, retries must tolerate transient storage failures, and cleanup behavior must not remove content still referenced by an active playlist or cached client.
3.4 Origin: Azure Blob Storage
Blob Storage is the HTTPS origin for HLS outputs. It removes subscriber traffic from the Container App and provides a durable, scalable source for Front Door. Origin paths should be partitioned by stream identity to prevent collisions and to support multiple future publishers. Access should be constrained so subscribers reach content through the approved Front Door path rather than bypassing distribution controls.
3.5 Distribution: Azure Front Door
Azure Front Door is the multi-subscriber delivery tier. It terminates HTTPS, routes requests to the Blob Storage origin, and caches immutable segments at edge locations. The manifest and segment cache policies must differ: the playlist changes every few seconds, while a segment is immutable after creation.
Artifact Front Door behavior TTL Reason
.m3u8 playlist Bypass caching, or use an ultra-short override 0–2 seconds The index changes with each segment. A stale copy can cause stalls or replay loops.
.ts segment Cache aggressively 30 days or the permitted maximum Each segment is immutable after generation, so edge caching removes most repeated origin reads.
4. Baseline Implementation
4.1 SRS configuration
Create srs.conf with the following baseline. It keeps the server in the foreground for container execution, enables HTTP access for test and health scenarios, accepts RTMP on port 1935, and writes a rolling HLS output.
listen 1935;
max_connections 1000;
daemon off;
http_server {
enabled on;
listen 8080;
dir ./objs/nginx/html;
}
vhost __defaultVhost__ {
rtmp_to_hls {
enabled on;
hls_path ./objs/nginx/html;
hls_fragment 4;
hls_window 20;
hls_cleanup on;
}
}
4.2 SRS container image
Package the configuration in a small image derived from SRS 6:
FROM ossrs/srs:6
COPY srs.conf /usr/local/srs/conf/srs.conf
EXPOSE 1935
EXPOSE 8080
CMD ["./objs/srs", "-c", "./conf/srs.conf"]
Mount the shared EmptyDir at the SRS HLS output path so artifacts are written to replica-local disk and made visible to the storage sidecar.
4.3 ACA dual-container template shape
Declare a shared replica-scoped volume:
"volumes": [
{
"name": "shared-stream-volume",
"storageType": "EmptyDir"
}
]
The media-container definition maps that volume into its HLS output location:
{
"name": "srs-server",
"image": "your-registry.azurecr.io/srs:latest",
"volumeMounts": [{
"volumeName": "shared-stream-volume",
"mountPath": "/usr/local/srs/objs/nginx/html"
}],
"resources": { "cpu": "0.25", "memory": "0.5Gi" }
}
The storage sidecar mounts the same volume and authenticates through the managed identity. The source design used an rclone-style command conceptually equivalent to:
rclone sync /data :azureblob,env_auth=true:<blob-container>/stream --verbose
The final implementation must use a supported change-detection or polling loop appropriate for the selected tool; it must not assume an unverified command-line option. It must also upload a segment before publishing the manifest update that references that segment.
4.4 Endpoints
• Publisher RTMP URL: rtmp://<container-domain-or-approved-ingress>:1935/live/
• Stream key: aerial-feed
• Subscriber HTTPS URL: https://<front-door-domain>/live/aerial-feed.m3u8
Clients use a standard HLS player such as Safari’s native playback or an HLS-capable web or application player. If NGINX-RTMP is selected instead, the output route in the source design is /stream/aerial-feed.m3u8.
5. NGINX-RTMP Fallback
If SRS is removed, NGINX with the RTMP module can preserve the same Azure architecture: RTMP ingest in Container Apps, HLS artifacts on the shared volume, identity-based synchronization to Blob Storage, and Front Door distribution. The path changes from the SRS output convention to /stream.
5.1 nginx.conf
worker_processes auto;
rtmp_auto_push on;
events { worker_connections 1024; }
rtmp {
server {
listen 1935;
chunk_size 4000;
application live {
live on;
record off;
hls on;
hls_path /var/www/html/stream;
hls_fragment 4s;
hls_playlist_length 20s;
hls_cleanup on;
}
}
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 8080;
location /stream {
add_header Cache-Control no-cache;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length';
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /var/www/html;
}
}
}
For browser-based use, define the required CORS behavior for the approved subscriber origins. The permissive wildcard shown above is suitable only as a starting point for controlled testing; production should restrict origins according to the product’s authorization model.
5.2 Multi-stage container build
The source design compiles NGINX 1.25.4 with nginx-rtmp-module 1.2.2 in an Alpine 3.19 builder stage, then copies the binary and configuration into a smaller Alpine runtime image. The build installs build-base, PCRE, OpenSSL, zlib, and Git dependencies; configures NGINX with the RTMP module, HTTP SSL support, and threads; creates /var/www/html/stream and log directories; redirects access and error logs to stdout and stderr; exposes ports 1935 and 8080; and starts NGINX in the foreground. Version pins and image provenance should be reviewed and updated through the normal dependency-management process before production deployment.
5.3 NGINX resource and volume mapping
The original deployment shape assigns the NGINX container 0.5 vCPU and 1.0 GiB of memory and mounts shared-stream-volume at /var/www/html/stream. The sidecar maps the same volume at /data and was sized at 0.25 vCPU and 0.5 GiB. These are baseline values, not production guarantees.
6. Media Server Alternatives and Decision Framework
Option Best fit Azure deployment Trade-off
SRS Recommended lightweight RTMP ingest and HLS packaging baseline Azure Container Apps or a Linux host Open-source and efficient; requires product-owned engineering, testing, and support
NGINX-RTMP Developer-controlled, cost-conscious fallback Azure Container Apps, Azure Container Instances, or a Linux VM Simple and lightweight; more manual build, security, and operational ownership
Wowza Streaming Engine Enterprise broadcasting, adaptive bitrate, and vendor-backed media workflows Azure Marketplace VM or clustered deployment Strong transcoding and operational tooling, but higher license and always-on compute cost
Ant Media Server Incident command or other cases requiring ultra-low-latency WebRTC alongside HLS Azure Marketplace and AKS-based clustering Supports sub-second interactive viewing; enterprise features and scale may carry added cost and complexity
Nimble Streamer High-throughput RTMP or SRT contribution, especially over lossy networks Lightweight Azure Linux VM deployment Broad protocol support and efficient transmuxing; introduces another vendor platform
Selection guidance
• Choose SRS for the initial engineering proof of concept and the default cost-conscious architecture.
• Choose NGINX-RTMP when the team has existing NGINX operational expertise or needs the simpler fallback.
• Choose Ant Media when sub-second WebRTC is a verified requirement rather than a preference.
• Choose Wowza when broadcast-grade transcoding, broad vendor support, and reduced custom engineering justify commercial licensing and larger compute.
• Evaluate Nimble Streamer when SRT contribution over unreliable networks becomes important.
Cost model
Dimension Commercial VM model Container-and-edge pattern
Compute Always-on VM capacity sized to avoid ingest and transcoding lag Small container allocation; scale and minimum replicas determined by availability requirements
Licensing Commercial license or per-core charges may apply Open-source media engine, with engineering and support costs owned by the product team
Subscriber scale Limited by origin bandwidth unless clustered and paired with a CDN Front Door serves cached segments; origin demand is largely independent of viewer count
7. Security, Reliability, and Engineering Requirements
Identity and secrets
• Enable a system-assigned managed identity on the Container App.
• Grant only the required Blob data-plane role at the narrowest practical scope. The baseline role is Storage Blob Data Contributor.
• Do not embed storage account keys or connection strings in images, source control, or environment variables.
• Protect the RTMP publisher endpoint with an approved stream-key or token scheme, network restrictions, and rotation procedures.
• Restrict Blob origin access and subscriber authorization according to the product’s audience model; the architecture does not by itself define entitlement or digital-rights management.
Availability and scaling
Azure Container Apps can reduce idle cost, but live ingest is stateful for the lifetime of a publisher session. Scaling to zero during an active or expected stream is inappropriate. A production policy should define minimum replicas, restart behavior, health probes, deployment-drain behavior, and what happens when a publisher reconnects. Horizontal scaling also requires stream-to-replica affinity so one publisher does not move between ingest replicas mid-session.
Network and protocol resilience
RTMP offers low-latency contribution and broad encoder support, but drone connectivity may fluctuate. Test reconnect behavior, packet loss, bitrate changes, and cellular handoffs. If field reliability is insufficient, evaluate SRT-capable contribution or bonded-network encoders. HLS segment duration, playlist window, and player retry policy jointly determine glass-to-glass latency and resilience.
Observability
• Capture publisher connection, disconnect, codec, bitrate, dropped-frame, and segment-generation metrics.
• Measure sidecar upload delay, failed operations, queue depth, local disk usage, and playlist-to-segment ordering.
• Monitor Blob origin errors, Front Door cache-hit ratio, edge latency, 4xx/5xx rates, and geographic distribution.
• Correlate a stream identifier across ingest, storage object paths, Front Door access logs, and client telemetry.
• Alert before local EmptyDir exhaustion and on playlist age exceeding the expected update interval.
Retention and lifecycle
The live HLS window is short, but edge TTL and Blob lifecycle rules must be coordinated. If segments are retained for replay or evidence workflows, define retention, legal, privacy, and cost requirements separately. If the stream is ephemeral, apply lifecycle deletion after the approved interval and ensure cached content cannot outlive policy.
8. Validation and Delivery Plan
Product management
• Confirm target audiences, authorization model, expected concurrent viewers, geographic reach, acceptable latency, recording requirements, and cost envelope.
• Decide whether the product requires standard HLS latency or sub-second WebRTC.
• Define service-level objectives for stream start, continuity, recovery, and availability.
Development management
• Approve ownership boundaries for the media image, sidecar, infrastructure as code, player integration, security updates, and on-call support.
• Plan dependency scanning and patching for SRS or NGINX, the base image, rclone or Blobfuse2, and client libraries.
• Decide whether commercial support is needed before moving from proof of concept to production.
Test engineering
• Validate publish, reconnect, and long-duration endurance behavior under representative 4G/5G and Wi-Fi impairment.
• Verify playback on Safari, iOS, Android, macOS, Windows, and supported web players.
• Load-test subscriber concurrency through Front Door and verify that origin and ingest load remain bounded.
• Confirm manifest freshness, segment ordering, cache rules, CORS, content types, and behavior during sidecar or storage faults.
• Exercise replica restart, deployment rollout, managed-identity token renewal, Blob throttling, Front Door origin failover, and storage cleanup.
• Measure end-to-end latency, startup time, rebuffering, frame loss, cache-hit ratio, origin egress, and cost per stream-hour and viewer-hour.
Azure cloud solution architecture
• Review Container Apps ingress support for the required RTMP TCP endpoint and select the appropriate environment/network configuration.
• Define private networking, DNS, certificates, origin protection, WAF policy, logging, regional strategy, and disaster recovery.
• Implement infrastructure as code for managed identity, RBAC, Container Apps, registry, storage, Front Door routes, rules, diagnostics, budgets, and alerts.
• Validate quotas, data-residency constraints, bandwidth economics, and whether Premium Blob is required after measurement.
Recommended phased decision
1. Proof of concept: one publisher, SRS, one Container App replica, EmptyDir sidecar synchronization, Blob origin, Front Door, and representative device playback.
2. Engineering validation: network impairment, endurance, cache correctness, failure recovery, security review, and cost measurement.
3. Production hardening: authenticated publishing and viewing, origin protection, observability, controlled upgrades, capacity policy, and regional resilience.
4. Re-evaluation gate: move to Ant Media, Wowza, Nimble, or another managed partner only if measured requirements exceed the open-source pattern’s capabilities or support model.
9. Front Door Rules and Acceptance Criteria
Rule 1: live playlist freshness
• Name: LivePlaylistNoCache.
• Condition: URL file extension equals m3u8, case-insensitive.
• Action: disable caching. If a cache is required, override the TTL to no more than two seconds.
• Query strings: ignore query strings unless the authorization design requires them to affect cache identity.
Rule 2: immutable segment caching
• Name: LiveSegmentsAggressiveCache.
• Condition: URL file extension equals ts, case-insensitive.
• Action: enable caching, override the cache duration to 30 days, and use a versioned or unique segment naming scheme.
• Compression: do not depend on compressing already compressed MPEG transport-stream payloads for material savings; validate whether compression is useful for manifests or other text assets.
Acceptance criteria
• A publisher can connect to the approved RTMP endpoint and begin producing HLS output with the configured stream key.
• The playlist becomes available through the Front Door HTTPS domain and advances at the configured cadence.
• Every playlist-referenced segment is available before or when the playlist update reaches subscribers.
• Multiple supported devices can play concurrently without direct access to the ingest container or material per-viewer load growth at the origin.
• Manifest responses are never stale beyond the approved threshold, and immutable segments achieve the expected cache-hit ratio.
• No storage account key is present in the application configuration, image, deployment manifest, or logs.
• Restart, reconnect, and transient storage failure tests complete within the agreed recovery objective without unbounded local disk growth.
10. Recommendation
Proceed with a measured proof of concept using SRS in Azure Container Apps, a managed-identity storage sidecar, Azure Blob Storage, and Azure Front Door. This is the recommended pattern because it isolates the stateful publisher connection from subscriber fan-out, uses open-source packaging to avoid a commercial-media-server commitment, and places scalable HTTPS delivery on Azure’s storage and edge services.
The proof of concept should not be treated as production-ready until it validates the assumptions that materially affect architecture: supported RTMP ingress in the selected Container Apps networking model, sustained media-server sizing, sidecar synchronization semantics, playlist/segment ordering, origin protection, device compatibility, achievable latency, failure recovery, and total cost. NGINX-RTMP remains the direct technical fallback; commercial platforms remain escalation options where measured latency, transcoding, operational support, or protocol requirements demand them.
No comments:
Post a Comment