Skip to main content

NGINX

NGINX F4F HDS Module: Adobe HTTP Dynamic Streaming

by ,


We have by far the largest RPM repository with NGINX module packages and VMODs for Varnish. If you want to install NGINX, Varnish, and lots of useful performance/security software with smooth yum upgrades for production use, this is the repository for you.
Active subscription is required.

The NGINX F4F HDS module (ngx_http_f4fhds_module) is an open-source NGINX module that serves Adobe HTTP Dynamic Streaming (HDS) content. It processes requests for F4F video fragments, which was the standard format for Flash-based adaptive bitrate streaming. This module is an open-source alternative to both the commercial NGINX Plus ngx_http_f4f_module and Adobe’s own HTTP Origin Module for Apache.

If you are maintaining a legacy streaming infrastructure that still relies on Adobe HDS, this module allows NGINX to serve F4F fragments efficiently. However, since Adobe officially ended Flash support in December 2020, most organizations should plan a migration to modern streaming protocols like HLS or MPEG-DASH. This article covers both how to use the module and how to transition away from it.

What Is Adobe HTTP Dynamic Streaming?

Adobe HTTP Dynamic Streaming (HDS) was Adobe’s adaptive bitrate streaming protocol, introduced alongside Flash Media Server. It used two key file types:

  • .f4f files — fragmented media containers holding the actual video and audio data
  • .f4x files — index files that map fragment numbers to byte offsets within the .f4f file

A typical HDS request follows the pattern /videoSeg1-Frag1, where Seg1 identifies the segment and Frag1 specifies the fragment number. The server reads the .f4x index to locate the correct byte range in the .f4f file, then returns that fragment to the client.

Adobe’s f4fpackager tool was used to pre-process video files into this format. The packager split videos into segments and fragments, creating the .f4f and .f4x file pairs needed for streaming.

How the Module Works

When a request arrives at a location where f4fhds is enabled, the module performs the following steps:

  1. Parses the request URI — extracts the segment and fragment numbers from the URL pattern (e.g., /videoSeg1-Frag3 yields segment 1, fragment 3)
  2. Reads the index file — memory-maps the corresponding .f4x file and parses the AFRA (Adobe Fragment Random Access) box to locate the fragment’s byte offset
  3. Extracts the fragment — memory-maps the .f4f media file and copies the fragment data (AFRA + ABST + MOOF + MDAT boxes) into the response buffer
  4. Returns the response — sends the fragment back to the client with the appropriate headers

The module uses mmap(2) for file access, which provides efficient memory-mapped I/O. However, this means the media files must reside on a local filesystem — networked filesystems like NFS are not supported.

An X-Inventos-F4FHDS-Version response header is added to every response, which is useful for verifying that the module is active and processing requests.

Installation

RHEL, CentOS, AlmaLinux, Rocky Linux

Install the NGINX F4F HDS module from the GetPageSpeed RPM repository:

sudo dnf install https://extras.getpagespeed.com/release-latest.rpm
sudo dnf install nginx-module-f4fhds

Then load the module by adding the following line at the top of /etc/nginx/nginx.conf:

load_module modules/ngx_http_f4fhds_module.so;

Alternatively, include all installed module configs:

include /usr/share/nginx/modules/*.conf;

Debian and Ubuntu

First, set up the GetPageSpeed APT repository, then install:

sudo apt-get update
sudo apt-get install nginx-module-f4fhds

The APT module page lists all supported Debian and Ubuntu versions.

On Debian/Ubuntu, the package handles module loading automatically. No load_module directive is needed.

Configuration

The NGINX F4F HDS module provides a single directive.

The f4fhds Directive

Property Value
Syntax f4fhds;
Default
Context location

This directive enables F4F HDS fragment serving within a location block. It takes no arguments or parameters.

Basic Configuration

The simplest configuration serves F4F files from a directory:

server {
    listen 80;
    server_name streaming.example.com;

    location /video/ {
        root /var/www;
        f4fhds;
    }
}

With this configuration, a request to /video/myclipSeg1-Frag1 causes the module to:

  1. Look for /var/www/video/myclip.f4x (the index file)
  2. Parse the index to find fragment 1’s offset
  3. Read /var/www/video/myclip.f4f (the media file)
  4. Return the fragment data

Configuration with Access Control

For production deployments, you should restrict access to your HDS content:

server {
    listen 80;
    server_name streaming.example.com;

    location /video/ {
        root /var/www;
        f4fhds;

        allow 10.0.0.0/8;
        allow 192.168.0.0/16;
        deny all;
    }
}

Serving Multiple Content Libraries

You can serve F4F content from different directories using the alias directive:

server {
    listen 80;
    server_name streaming.example.com;

    location /live/ {
        alias /mnt/storage/live-content/;
        f4fhds;
    }

    location /vod/ {
        alias /mnt/storage/vod-content/;
        f4fhds;
    }
}

Verifying the Module Is Working

After configuring the module, verify it is loaded and responding correctly.

First, test the NGINX configuration syntax:

nginx -t

Then reload NGINX and check for the module’s response header:

sudo systemctl reload nginx
curl -I http://localhost/video/testSeg1-Frag1

Even without actual F4F files present, you should see the module’s signature header in the response:

HTTP/1.1 404 Not Found
Server: nginx/1.28.2
X-Inventos-F4FHDS-Version: 0.4

The X-Inventos-F4FHDS-Version header confirms the module is active and processing HDS requests. The 404 status is expected when no matching .f4x and .f4f files exist at the requested path.

If you send a POST request instead, the module correctly returns 405 Not Allowed, since it only supports GET and HEAD methods:

curl -I -X POST http://localhost/video/testSeg1-Frag1
HTTP/1.1 405 Not Allowed

Comparison with the Commercial NGINX Plus Module

The commercial ngx_http_f4f_module, available only with an NGINX Plus subscription, offers one additional directive:

Feature f4fhds (Open-Source) NGINX Plus f4f
Directive f4fhds; f4f;
Buffer size config Not configurable (uses mmap) f4f_buffer_size (default 512k)
File access method mmap(2) — zero-copy Buffer-based reads
Multi-segment support First segment only (Seg1) Full segment support
License LGPL-2.1 (free) Commercial (NGINX Plus)
Availability GetPageSpeed packages F5/NGINX subscription

The open-source module uses memory-mapped I/O (mmap), which can be more efficient than buffer-based reads for local files. However, it only supports single-segment files (Seg1), which is the common case for most HDS deployments.

Limitations

Before deploying this module, consider these important limitations:

  • Single segment only — the module assumes all files contain segment 1 (Seg1). Multi-segment HDS content is not supported.
  • Local filesystems only — because the module uses mmap(2), the .f4f and .f4x files must reside on a local, non-networked filesystem. NFS, CIFS, and other network filesystems will not work reliably.
  • No manifest generation — the module serves fragments only. You must generate F4F manifest files (.f4m) separately using Adobe’s f4fpackager or equivalent tools.
  • Legacy protocol — Adobe HDS depends on Flash Player, which reached end-of-life in December 2020. No modern browser supports Flash natively.

Why You Should Migrate Away from Adobe HDS

Adobe HDS was designed for Flash Player, which Adobe officially discontinued on December 31, 2020. All major browsers have removed Flash support entirely. Therefore, while the f4fhds module remains useful for maintaining existing infrastructure during a transition period, it is not suitable for new streaming deployments.

The modern alternatives to Adobe HDS are:

HLS (HTTP Live Streaming)

Apple’s HLS has become the de facto standard for adaptive bitrate streaming. It uses .m3u8 playlist files and .ts (MPEG-TS) or .mp4 (fMP4) segments. HLS is supported natively by all modern browsers, iOS, Android, and smart TVs.

NGINX can serve HLS content using the VOD module, which performs on-the-fly transmuxing of MP4 files to HLS format without pre-packaging.

MPEG-DASH

MPEG-DASH is an international standard (ISO/IEC 23009-1) for adaptive streaming. It uses .mpd manifest files and supports both MPEG-TS and fMP4 segments. DASH is supported by most browsers through JavaScript players like dash.js.

The NGINX MPEG-TS module can accept live MPEG-TS streams and serve them as both HLS and DASH simultaneously.

Live Streaming with RTMP

For live streaming workflows that previously used Flash-based RTMP ingest with HDS output, you can use the NGINX HTTP-FLV module, which accepts RTMP streams and delivers them over HTTP-FLV or converts them to HLS.

Migration Path: From HDS to HLS/DASH

If you currently use this module and need to migrate, follow these steps:

Step 1: Audit Your Current HDS Content

Identify all F4F content on your servers:

find /var/www/video -name "*.f4f" -o -name "*.f4x" -o -name "*.f4m" | wc -l

Step 2: Convert F4F Files to MP4

Use FFmpeg to convert your F4F content to standard MP4 format:

ffmpeg -i input.f4v -c copy output.mp4

For fragmented F4F files, you may need to reassemble them first. If you have the original source files, use those instead.

Step 3: Set Up the VOD Module for On-the-Fly HLS

Install the NGINX VOD module to serve your MP4 files as HLS streams without pre-packaging:

sudo dnf install nginx-module-vod

Then configure NGINX to serve HLS from your converted MP4 files. The VOD module handles all the segmentation and manifest generation automatically.

Step 4: Run Both Protocols in Parallel

During the transition, serve both HDS and HLS/DASH from the same server:

server {
    listen 80;
    server_name streaming.example.com;

    # Legacy HDS endpoint (remove after migration)
    location /hds/ {
        alias /var/www/video/f4f/;
        f4fhds;
    }

    # Modern HLS endpoint
    location /hls/ {
        alias /var/www/video/mp4/;
        # VOD module configuration here
    }
}

Step 5: Update Client Applications

Update your video players to use HLS or DASH URLs instead of HDS. Popular players like Video.js, hls.js, and Shaka Player all support HLS and DASH natively without any plugin.

Step 6: Decommission HDS

Once all clients have migrated, remove the F4F HDS configuration and delete the legacy F4F files:

# Remove the HDS location block
# location /hds/ { ... }

Troubleshooting

“unknown directive f4fhds”

The module is not loaded. Ensure you have the load_module directive at the top of nginx.conf:

load_module modules/ngx_http_f4fhds_module.so;

On RHEL-based systems, you can also include all module configs:

include /usr/share/nginx/modules/*.conf;

404 Not Found with X-Inventos-F4FHDS-Version Header

The module is loaded and processing requests, but cannot find the .f4x index file. Verify:

  • The file path is correct (check root or alias directive)
  • The .f4x file exists alongside the .f4f file
  • The file name matches the request URL (e.g., /video/clipSeg1-Frag1 requires clip.f4x and clip.f4f)

500 Internal Server Error

Check the NGINX error log for details:

tail -f /var/log/nginx/error.log

Common causes include:

  • Corrupted F4X file — the AFRA box structure is invalid or the file is truncated
  • Permission denied — NGINX worker process cannot read the F4F/F4X files. Ensure the nginx user has read permissions.
  • Network filesystem — the files are on an NFS or CIFS mount. Move them to a local filesystem.

405 Not Allowed

The module only supports GET and HEAD HTTP methods. If your client sends POST or other methods, you will receive a 405 response. This is correct behavior — HDS clients should only use GET requests.

Performance Considerations

The f4fhds module uses mmap(2) for file I/O, which provides several performance benefits:

  • Zero-copy reads — the kernel maps file data directly into the process address space without extra copy operations
  • Kernel page cache — frequently accessed fragments benefit from the operating system’s page cache
  • Low memory overhead — mapped pages are shared between processes and can be evicted under memory pressure

For best performance, ensure that:

  • F4F files are stored on fast local storage (SSD preferred)
  • The system has enough RAM to cache frequently accessed fragments
  • The worker_processes directive is set appropriately for your CPU count

Conclusion

The NGINX F4F HDS module provides a free, open-source way to serve Adobe HTTP Dynamic Streaming content from NGINX. It is a drop-in alternative to the commercial NGINX Plus F4F module for single-segment HDS deployments.

However, Adobe HDS is a legacy protocol tied to the now-discontinued Flash Player. If you are still serving HDS content, you should plan a migration to HLS or MPEG-DASH. The NGINX VOD module and MPEG-TS module provide modern alternatives that work with all current browsers and devices.

The module source code is available on GitHub.

D

Danila Vershinin

Founder & Lead Engineer

NGINX configuration and optimizationLinux system administrationWeb performance engineering

10+ years NGINX experience • Maintainer of GetPageSpeed RPM repository • Contributor to open-source NGINX modules

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

This site uses Akismet to reduce spam. Learn how your comment data is processed.