Library / SDK
winshining/nginx-http-flv-module avatar
winshining/nginx-http-flv-module

nginx-http-flv-module: HTTP-FLV and GOP cache on top of nginx-rtmp-module

A media streaming server based on nginx-rtmp-module. In addtion to the features nginx-rtmp-module provides, HTTP-FLV, GOP cache, VHosts (one IP for multi domain names) and JSON style statistics are supported now.

2,933 stars594 forksCBSD-2-Clause

At a glance

What is it?
A C module that folds HTTP-FLV playback, GOP cache, virtual hosts and JSON statistics into the nginx-rtmp stack. It suits operators who already run nginx for RTMP ingest and want browser playback without a separate server.
Who is it for?
Adopt it if you already run nginx-rtmp-module, publish RTMP from FFmpeg or OBS, and want HTTP-FLV playback for flv.js or VLC without adding another process. Do not adopt it if your clients are HLS-only, if you need a prebuilt binary, or if you cannot rebuild NGINX from source.
Can I use it commercially?
Yes. BSD-2-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 42 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The gap nginx-http-flv-module fills for RTMP operators

nginx-rtmp-module gives you RTMP ingest and playback, but no HTTP-FLV output. That matters because Flash is gone: the README points to Adobe's Flash Player end-of-life page and notes that plugins relying on Flash stopped working once browsers removed it. The browser-side replacement is flv.js, which the README says can only run in browsers that support Media Source Extensions. flv.js needs a plain HTTP response carrying an FLV stream, and stock nginx-rtmp-module does not produce one.

This module adds that output path. It is aimed at people who already publish RTMP from FFmpeg or OBS and want the same stream playable over HTTP without standing up a second media server. The feature table in the README lists HTTP-FLV, GOP cache, virtual hosts, audio-only support for RTMP and HTTP-FLV, single-track HLS, reuseport, a timer for the access log, JSON-style statistics and statistics for recordings as additions over nginx-rtmp-module. HTTPS-FLV and chunked responses are called out for the HTTP-FLV row.

It is not a general-purpose streaming framework. It is a module compiled into NGINX, so your deployment story is an NGINX build story.

How the module sits inside NGINX and nginx-rtmp-module

The repository layout makes the architecture visible. The RTMP side is a set of ngx_rtmp_*.c files: core, handshake, AMF, command, live, relay, record, notify, stat, access, limit and others. The HTTP-FLV side is separate: ngx_http_flv_live_module.c and its header, plus ngx_rtmp_flv_live_index_module.c and ngx_rtmp_gop_cache_module.c. So the RTMP protocol handling and the HTTP playback handling are distinct translation units that share state inside the same nginx worker.

A publisher connects over RTMP to an application block. The live module holds the stream, and the GOP cache module keeps the most recent group of pictures so a new HTTP-FLV viewer can start at a keyframe instead of waiting for the next one. The HTTP-FLV module then serves that stream over HTTP/1.x, with HTTPS-FLV and chunked response supported according to the README's feature table.

Statistics come from ngx_rtmp_stat_module.c, which the README describes as JSON style, and the module also reports statistics for recordings. Virtual host support means one IP can serve multiple domain names, which is the practical reason to pick this over the upstream module if you host more than one stream domain on a single address. The README also states the module is independent of endianness, with partial support noted in a big-endian branch.

Building nginx-http-flv-module from source on Unix-like systems

There is no package in the README. The build path it gives is: download NGINX and the module, uncompress both, cd into the NGINX source directory, then configure and make. The module can be compiled in statically or as a dynamic module; the README warns that a dynamic module requires NGINX 1.9.11 or newer, while the general compatibility note says NGINX should be 1.2.6 or greater.

Static build, the simpler option:

bash
./configure --add-module=/path/to/nginx-http-flv-module
make
make install

The configure script picks up the module's config file from the repository root. After make install, the resulting nginx binary contains the RTMP and HTTP-FLV handlers.

Dynamic build, if you want to load the module at runtime:

bash
./configure --add-dynamic-module=/path/to/nginx-http-flv-module
make
make install

The README is explicit that you must not compile this module alongside nginx-rtmp-module, because it already contains all of that module's features. Doing both is a build error waiting to happen.

Prerequisites listed are GNU make, GCC (or MSVC on Windows), GDB for debugging, PCRE if you need regular expressions, OpenSSL for encrypted access and zlib for compression. On Windows the README redirects to NGINX's own Win32 build guide and says to add the --add-module flag during the configure step.

Publishing with FFmpeg and playing the stream over HTTP-FLV

The README's publish example avoids transcoding and uses stream copy. MEDIA_FILE_NAME, the appname and the streamname are placeholders you replace; the default RTMP port is 1935, and the README says a non-default port must be given explicitly with :port.

bash
ffmpeg -re -i MEDIA_FILE_NAME -c copy -f flv rtmp://example.com[:port]/appname/streamname

The appname has to match an application block in the rtmp configuration. The streamname can be anything but cannot be omitted. The README notes that some legacy FFmpeg versions lack -c copy, in which case -vcodec copy -acodec copy is the substitute.

Playback over HTTP-FLV uses this URL shape:

bash
http://example.com[:port]/dir?[port=xxx&]app=appname&stream=streamname

The README warns that if you play this with ffplay on the command line, the URL must be wrapped in quotation marks, because some shells treat the ampersand as a request to run the command in the background and will silently drop the remaining arguments. That is a shell behaviour, not a server one, and it is the kind of detail that costs an afternoon if you skip it.

For browser playback the README names flv.js, which requires Media Source Extensions support. VLC and OBS are listed as supporting both RTMP and HTTP-FLV; JW Player is listed for RTMP only.

Where nginx-http-flv-module is the wrong choice

The compatibility statement is the first constraint: NGINX should be 1.2.6 or greater, and the README says compatibility with other versions is unknown. If you are pinned to a distribution-packaged NGINX and cannot rebuild it, this module is not for you, because the README offers no prebuilt artifact and no package name.

Codec support is the second. The topics list aac, h264 and flvjs, and the publish example uses stream copy. If your source is HEVC or another codec outside that set, the README gives no indication that it will work, and the module does not transcode. You would need FFmpeg to transcode before publishing, which changes the resource profile of the ingest host.

Platform is the third. Linux is recommended; FreeBSD and MacOS are listed; Windows is listed as limited. If Windows is your production target, the README sends you to NGINX's own Win32 build documentation, and the module's own guidance there concerns compiler behaviour on older Visual Studio versions rather than a supported deployment recipe.

Finally, if your clients are HLS-only, this module's HTTP-FLV output does not help them. The README lists single-track HLS support as an addition, so HLS is present, but the feature table's framing makes clear that HTTP-FLV is the headline capability, not HLS.

How it differs from nginx-rtmp-module and from an HLS-first setup

The obvious alternative is nginx-rtmp-module itself. The difference is not subtle: nginx-http-flv-module is described as based on it and containing all of its features, then adding HTTP-FLV, GOP cache, virtual hosts, reuseport, JSON statistics and recording statistics. Choosing upstream means giving up HTTP playback entirely, since the table marks HTTP-FLV as absent there. If all your viewers are RTMP clients, upstream is the smaller dependency and you avoid a fork's maintenance surface.

An HLS-first setup is the other direction. HLS segments media into files and serves them over ordinary HTTP, which works with native browser video elements and needs no Media Source Extensions. The trade-off is latency: segmenting introduces delay that a continuous FLV stream over HTTP does not have. The README's own note about Flash's end of life and its recommendation of flv.js point at the browser-playback problem, and HTTP-FLV answers it with a persistent connection rather than a playlist. If sub-second latency is not a requirement, HLS is the lower-risk path because it does not require a custom NGINX build.

GOP cache is the detail that separates a usable HTTP-FLV endpoint from a frustrating one. Without it, a viewer joining mid-GOP waits for the next keyframe. The README lists GOP cache as an addition over nginx-rtmp-module, which is the concrete reason to prefer this module if you serve viewers who join streams at arbitrary times.

Maintenance, licensing and the upgrade path

The repository is not archived. The last push was on 2026-08-19, and releases are tagged: v1.2.14 on 2026-07-04, v1.2.13 on 2026-02-23 and v1.2.12 on 2024-12-31. The gap between v1.2.12 and v1.2.13 is roughly fourteen months, so release cadence has not been even, though the two most recent tags are about four months apart. The README carries a GitHub Actions workflow badge for the master branch, which indicates CI is configured, but the README does not describe what the workflow runs.

Upgrade cost is tied to NGINX, not to the module alone. Because the module compiles into NGINX, every NGINX upgrade means rebuilding the module against the new source tree. A dynamic module decouples that slightly, at the cost of the 1.9.11 minimum and the need to load it explicitly. Either way, you are maintaining a build pipeline, not just a config file.

The licence is BSD-2-Clause, stated in the repository and present as a LICENSE file at the top level. That is a permissive licence, which generally means you can redistribute and modify with the copyright notice retained, but the LICENSE file does not spell out the obligations and this is not legal advice. If you ship a product containing this module, have counsel read the LICENSE file rather than relying on the licence name.

Editorial conclusion

Adopt it if you already run nginx-rtmp-module, publish RTMP from FFmpeg or OBS, and want HTTP-FLV playback for flv.js or VLC without adding another process. Do not adopt it if your clients are HLS-only, if you need a prebuilt binary, or if you cannot rebuild NGINX from source. Before rollout, verify your NGINX version against the documented 1.2.6 minimum (1.9.11 for a dynamic module), confirm your source is H.264/AAC, and check that your build does not also link nginx-rtmp-module, since the two must not be compiled together.

Frequently asked questions

What is nginx-http-flv-module and what does it add to nginx-rtmp-module?

It is a media streaming server based on nginx-rtmp-module that keeps all of that module's features and adds HTTP-FLV, GOP cache, virtual hosts, reuseport support, a timer for the access log, JSON style statistics and statistics for recordings. HTTPS-FLV and chunked response are supported for the HTTP-FLV path.

Which NGINX version does nginx-http-flv-module require?

The README says the NGINX version should be equal to or greater than 1.2.6, and that compatibility with other versions is unknown. If you compile the module as a dynamic module, the README states the NGINX version must be 1.9.11 or newer.

Can I compile nginx-http-flv-module together with nginx-rtmp-module?

No. The README states that nginx-http-flv-module has all the features nginx-rtmp-module provides, so the two must not be compiled together.

How do I publish a stream to nginx-http-flv-module?

The README's example uses FFmpeg with stream copy to an RTMP URL of the form rtmp://example.com[:port]/appname/streamname, where appname must match an application block and streamname cannot be omitted. The default RTMP port is 1935, and any other port must be specified explicitly.

How is an HTTP-FLV stream played from nginx-http-flv-module?

The README gives the URL shape http://example.com[:port]/dir?[port=xxx&]app=appname&stream=streamname, and notes that when using ffplay the URL must be enclosed in quotation marks so the shell does not discard arguments after the ampersand. VLC and OBS are listed as supporting both RTMP and HTTP-FLV, while flv.js is listed for HTTP-FLV in browsers with Media Source Extensions.

Official sources

  1. Issues
  2. License: BSD-2-Clause
  3. README
  4. Releases
  5. winshining/nginx-http-flv-module on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/winshining-nginx-http-flv-module.svg)](https://hysenlabs.com/projects/winshining-nginx-http-flv-module)