Open-source project
mangui/flashls avatar
mangui/flashls

flashls plays HLS in Flash with the quality switching left open

HLS Flash Plugin/Player (Chromeless,OSMF,FlowPlayer,mediaelement.js,video.js,Clappr)

743 stars259 forksActionScriptMPL-2.0

At a glance

What is it?
flashls is an open source ActionScript plugin that plays HLS streams inside a Flash player, with a configurable buffer model, three quality switching modes, an ABR algorithm and AES-128 support. Its audience is the shrinking set of projects that still have to serve a Flash player, and the newest tagged release is from 2017.
Who is it for?
flashls suits a team that still has a Flash playback path to keep alive, such as a long-lived enterprise player or an installed base that cannot be upgraded, and who needs HLS with a real buffer and switching model rather than a naive playlist reader.
Can I use it commercially?
Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 77 days ago.
What is it written in?
Mainly ActionScript, according to GitHub's language statistics.

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

Editorial analysis

A Flash plugin for a protocol that outlived its host

The situation this project addresses is unusual. HLS survived and kept evolving, while the player that many of these streams were built for did not. flashls is an open source HLS Flash plugin that allows you to play HLS streams, written in ActionScript, and it plugs into a set of existing players rather than being a player itself. The compatibility list is specific: Clappr, Flowplayer Flash 3.2.12, Flowplayer 6.x, MediaElement.js with integration since MediaElement.js 2.15.0, OSMF 2.0 based players such as SMP and GrindPlayer, and Video.js 4.6, 4.7 and 4.8. The Video.js support is an adaptation carried out in a separate repository. The intended user is therefore not a developer starting a new player but a developer with an existing Flash player who needs HLS to work inside it.

VoD, live with a sliding window, and three ways to change quality

The feature list starts with the playlist types, covering VoD and live playlists, with sliding window, also known as DVR, support on live playlists. The interesting part is adaptive streaming, which offers manual and automatic quality switching with three distinct modes. Instant switching pauses playback, flushes the whole buffer, fetches fragments matching the new quality level and the current playback position, then resumes. Smooth switching flushes the buffer on the next fragment boundary and fetches fragments for the new level at the next fragment position, which allows a smooth and still fast switch, usually without interrupting playback. Bandwidth conservative switching does not flush the buffer at all, and the next fragment to be buffered simply uses the newly selected level. Which one you want depends on whether a brief stall is acceptable in exchange for an immediate picture change.

The ABR algorithm comes from a named paper, not from guesswork

Automatic switching is driven by an adaptive bitrate algorithm, and the README attributes it to a specific publication, rate adaptation for dynamic adaptive streaming over HTTP in content distribution network, by Chenghao Liu, Imed Bouazizi, Miska M. Hannuksela and Moncef Gabbouj, with the document linked in the docs directory. That attribution matters more than a version number would, because it tells you the switching policy is a published, peer-reviewed rate adaptation scheme rather than a heuristic that happens to work. The feature list also names an emergency quality switch-down to avoid buffering in the case of a sudden bandwidth drop, and notes that the maximum quality level the auto switch algorithm can select can be capped, either to the player dimension or upon frame drop detection. That second cap is the mechanism that stops a fast connection from pulling a 4K rendition into a small player.

Buffer behaviour is configured in seconds, not in fragments

The configuration model is where the engineering is, and it is built around a buffer with several independent thresholds. The README documents the options as optional, with defaults, and the debug switches are the simplest of them:

code
  - `hls_debug` (default false) - Toggle _debug_ traces, outputted on JS console
  - `hls_debug2` (default false) - Toggle _verbose debug_ traces, outputted on JS console
  - `hls_minbufferlength` (default -1) - Minimum buffer length in _seconds_ that needs to be reached before playback can start (after seeking) or restart (in case of empty buffer)

The hls_minbufferlength option, default minus one, is the minimum buffer length in seconds that needs to be reached before playback can start after seeking, or restart in case of an empty buffer, and when set to minus one some heuristics based on past metrics are used to define an accurate value that should prevent the buffer from stalling. The hls_lowbufferlength option, default 3, is the low buffer threshold in seconds, and crossing down that threshold puts HLS into a buffering state while playback continues. hls_maxbufferlength, default 300, caps the maximum buffer length in seconds where zero means infinite buffering, and hls_maxbackbufferlength, default 30, caps the back buffer, which is seekable without redownloading segments. The minBufferLengthCapping option, also default minus one, provides the maximum value used when minBufferLength is minus one.

Start level and seek level are separate decisions with numeric conventions

Two options control which rendition the player begins on, and both use a numeric convention where minus one, minus two and a fraction between 0 and 1 all mean different things. hls_startfrombitrate, default minus one, specifies a preferred bitrate to start with when greater than zero, and when it is minus one and hls_startfromlevel is not specified, automatic start level selection is used, and this parameter takes priority over hls_startfromlevel when set. hls_startfromlevel, default minus one, is a normalized preferred bitrate, where 0 selects the lowest non-audio bitrate, 1 the highest, and 0.5 the closest to the middle bitrate. Minus one means automatic start level selection, with playback starting from the level matching the download bandwidth determined from the download of the first segment, and minus two means playback starts from the first level appearing in the manifest regardless of its bitrate. The hls_autoStartMaxDuration option, default minus one, caps the max fragment loading duration, the bandwidth test plus fragment loading, in automatic start level selection mode.

Seeking has a mode, and the live cache can be flushed

The hls_seekmode option makes the seeking behaviour explicit, with two documented values:

code
  - `hls_seekmode`
    - "ACCURATE" - Seek to exact position
    - "KEYFRAME" - Seek to last keyframe before request

ACCURATE seeks to the exact requested position, and KEYFRAME seeks to the last key frame before the request. The feature list adds that seeking can be done in the buffer and in the back buffer without redownloading segments, which is what makes the back buffer length option worth tuning. The hls_seekfromlevel option, default minus one, decides what happens after a seek: set to true, playback starts from the lowest non-audio level after any seek operation, set to false, it starts from the level used before seeking, and the same normalized 0 to 1 convention applies, with minus one meaning automatic seek level selection keeping the level before the seek. Separately, hls_flushliveurlcache, default false, flushes the live playlist from the URL cache before reloading, which the README describes as a workaround for cache issues with some combination of Flash Player and IE version.

The supported M3U8 tag list is the real compatibility boundary

The plugin's coverage of the playlist format is enumerated, and reading the list tells you what streams it will accept. The supported tag list is:

code
  - `#EXTM3U`
  - `#EXTINF`
  - `#EXT-X-STREAM-INF` (Multiple bitrate)
  - `#EXT-X-ENDLIST` (VoD / Live playlist)
  - `#EXT-X-MEDIA-SEQUENCE`
  - `#EXT-X-TARGETDURATION`
  - `#EXT-X-DISCONTINUITY`
  - `#EXT-X-DISCONTINUITY-SEQUENCE`
  - `#EXT-X-PROGRAM-DATE-TIME` (optional, used to synchronize time-stamps and sequence number when switching from one level to another)
  - `#EXT-X-KEY` (AES-128 method supported only)
  - `#EXT-X-BYTERANGE`

and that is the whole set. Supported tags are #EXTM3U, #EXTINF, #EXT-X-STREAM-INF for multiple bitrate, #EXT-X-ENDLIST for VoD and live playlists, #EXT-X-MEDIA-SEQUENCE, #EXT-X-TARGETDURATION, #EXT-X-DISCONTINUITY, #EXT-X-DISCONTINUITY-SEQUENCE, and #EXT-X-PROGRAM-DATE-TIME, which is described as optional and used to synchronize time stamps and sequence number when switching from one level to another. #EXT-X-KEY is supported with the AES-128 method only, and #EXT-X-BYTERANGE is also in the list. The absence of other tags is the boundary: a stream relying on something outside this set, such as the more recent variable substitution forms, is outside what this plugin documents.

Where the plugin lives and how it reaches a player

The resilience features are the ones that matter in production playback. The README lists a retry mechanism on I/O errors, a recovery mechanism on badly segmented TS streams, and failover on alternate redundant streams, with a link to Apple's guidance on redundant streams. There is also frame drop detection, which triggers an event if the device is not powerful enough to decode the content, and that event is what feeds the cap on the maximum quality level. Timed metadata for HTTP Live Streaming is supported in ID3 format carried in MPEG2-TS, and alternate audio track rendition is handled through a master playlist with alternative audio. The feature list also records buffer progress reporting and configurable seeking method on both VoD and live. The repository root shows the shape of the project, with a src/ directory, a lib/ directory, a build/ directory, a bin/ directory, an API.md, a docs/ directory and examples for chromeless, flowplayer, osmf and libs setups. The README does not give a package manager install or a build command for the plugin, so there is nothing to type before you can use it. The plugin is compiled from the ActionScript sources and dropped into the host player, and the repository carries the example projects that show the wiring: an examples/chromeless directory for using the plugin without a player chrome, an examples/flowplayer directory for the Flowplayer host, an examples/osmf directory for the OSMF path, and an examples/libs directory for the shared libraries those examples need. The API.md file at the root is the reference for the methods the plugin exposes, the src/ directory holds the plugin sources, lib/ holds the supporting code, and build/ and bin/ hold the build output and the compiled artefact. The three example directories are the closest thing the repository has to a getting started guide, since a new integration is realistically a case of taking one of them and adjusting the configuration.

Editorial conclusion

flashls suits a team that still has a Flash playback path to keep alive, such as a long-lived enterprise player or an installed base that cannot be upgraded, and who needs HLS with a real buffer and switching model rather than a naive playlist reader. It does not suit a new browser product, since Flash is gone from every current browser, and it does not suit a team that needs vendor support or a maintained release line, because the newest tagged release is v0.4.4.24 from 2017-03-02. Before adopting, check the Flash Player version in your target environment against the player compatibility list, and note that the last push to the repository was on 2026-08-07 on the dev branch.

Frequently asked questions

Which players is the flashls HLS plugin compatible with?

The README lists Clappr, Flowplayer Flash 3.2.12, Flowplayer 6.x, MediaElement.js with integration since version 2.15.0, OSMF 2.0 based players such as SMP and GrindPlayer, and Video.js 4.6, 4.7 and 4.8. The Video.js support was done as an adaptation in a separate repository.

What are the three quality switching modes in flashls?

Instant switching pauses playback and flushes the whole buffer before fetching fragments for the new level. Smooth switching flushes the buffer on the next fragment boundary for a fast switch that usually does not interrupt playback. Bandwidth conservative switching does not flush the buffer at all and only applies the new level to the next fragment to be buffered.

How do I configure the buffer behaviour of flashls?

The options are all optional and work in seconds. hls_minbufferlength sets the minimum buffer before playback starts, hls_lowbufferlength defaults to 3 and triggers the buffering state, hls_maxbufferlength defaults to 300 with zero meaning infinite buffering, and hls_maxbackbufferlength defaults to 30 for the part that is seekable without redownloading segments.

Which M3U8 tags does flashls support?

The README lists #EXTM3U, #EXTINF, #EXT-X-STREAM-INF, #EXT-X-ENDLIST, #EXT-X-MEDIA-SEQUENCE, #EXT-X-TARGETDURATION, #EXT-X-DISCONTINUITY, #EXT-X-DISCONTINUITY-SEQUENCE, #EXT-X-PROGRAM-DATE-TIME, #EXT-X-KEY with the AES-128 method only, and #EXT-X-BYTERANGE.

How do I choose which quality level flashls starts on?

hls_startfrombitrate takes priority when it is greater than zero. hls_startfromlevel uses a normalized value where 0 is the lowest non-audio bitrate, 1 the highest, 0.5 the middle one, minus one means automatic selection from the measured download bandwidth, and minus two means the first level in the manifest regardless of bitrate.

Official sources

  1. License: MPL-2.0
  2. mangui/flashls on GitHub
  3. Project website
  4. README
  5. Releases
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/mangui-flashls.svg)](https://hysenlabs.com/projects/mangui-flashls)

Was this useful?