CGJU
CGJU
May 28, 2026 · 6 min read

FLV.js Introduction

FLV.js is a pure JavaScript FLV player open-sourced by Bilibili (B-site), capable of playing FLV video streams in modern browsers that support MSE (Media Source Extensions) without using Flash plugins. Its emergence solved the challenge of web-based FLV live streaming playback after the deprecation of Flash.

In the Flash era, RTMP/FLV was the mainstream solution for live streaming. But as Flash was phased out by major browsers, web-based live streaming faced a transition. FLV.js allowed HTTP-FLV-based live streaming solutions to continue, and when combined with CDN HTTP distribution, can deliver low-latency, high-concurrency live streaming experiences.

Core Features of FLV.js

  • Pure JavaScript implementation: No plugins required, runs purely in the browser
  • Low latency: HTTP-FLV solution can achieve latency as low as 1-3 seconds
  • High performance: Uses Web Worker for data parsing, does not block the main thread
  • Good compatibility: Supports all modern browsers with MSE support
  • Rich functionality: Supports live streaming, video on demand, live recording, real-time stream switching, and more
  • Open source and free: Open-sourced under the MIT license, free to use

Bilibili Open Source Background

The FLV.js project was born out of Bilibili's frontend team, initially created to solve the player problem for Bilibili's live streaming business. In 2016, with the decline of Flash, Bilibili needed a pure web-based live streaming playback solution, so the project was initiated.

FLV.js was officially open-sourced in 2016 and quickly became a benchmark project in the frontend live streaming field, adopted by numerous live streaming platforms and video websites. Its success promoted the popularization of HTTP-FLV live streaming solutions and spawned more MSE-based player projects.

Working Principles

The core working principle of FLV.js is: fetch FLV stream data via HTTP requests, parse the FLV container format with JavaScript on the browser side, then feed the audio and video data through the MSE API to the browser's native video tag for decoding and playback.

Overall Architecture

  1. IO Layer: Responsible for data transmission, supporting Fetch API, XHR, WebSocket, and other methods
  2. Parsing Layer: Parses FLV data in Web Worker, extracting audio and video frames
  3. Buffer Layer: Manages video buffer to ensure smooth playback
  4. Control Layer: Handles playback, pause, seek, and other control logic
  5. MSE Layer: Feeds parsed data to Media Source Extensions

FLV Parsing Process

FLV.js parses FLV files as follows:

  • Read FLV Header, confirm file type and whether it contains audio and video
  • Parse Script Tag, get video metadata (resolution, bitrate, etc.)
  • Parse Video Tag, extract H.264 video data
  • Parse Audio Tag, extract AAC/MP3 audio data
  • Package audio and video data into FMP4 format for playback via MSE

Difference Between flv.js and mpegts.js

Many people confuse flv.js and mpegts.js, but they are actually two different projects developed by the same author:

Feature flv.js mpegts.js
Developer Bilibili Original flv.js author (individual)
Supported Formats FLV FLV, MPEG-TS
Update Status Slow Active
Features Basic functionality More new features
Recommended Scenarios Only need FLV playback Need more formats and features

Basic Usage Code Examples

Below is a complete example demonstrating how to use FLV.js to play FLV video streams in a web page.

Importing FLV.js

The simplest way is to import via CDN:

<script src="https://cdn.jsdelivr.net/npm/flv.js@latest/dist/flv.min.js"></script>

You can also install via npm:

npm install flv.js --save

HTML Structure

Add a video element to the page:

<video id="videoElement" controls autoplay muted playsinline></video>

JavaScript Initialization

Use FLV.js to create a player instance and load the video stream:

if (flvjs.isSupported()) {
    const videoElement = document.getElementById('videoElement');
    const flvPlayer = flvjs.createPlayer({
        type: 'flv',
        url: 'https://example.com/live/stream.flv',
        isLive: true
    });
    flvPlayer.attachMediaElement(videoElement);
    flvPlayer.load();
    flvPlayer.play();
}

Configuration Parameters Description

  • type: Media type, 'flv' or 'mp4'
  • url: Video stream address
  • isLive: Whether it's a live stream
  • cors: Whether to enable CORS cross-origin
  • withCredentials: Whether to carry cookies
  • hasAudio: Whether it contains audio
  • hasVideo: Whether it contains video

Low Latency Optimization

In live streaming scenarios, latency is a very important metric. FLV.js provides various configuration options to optimize latency.

Key Configuration Items

const flvPlayer = flvjs.createPlayer({
    type: 'flv',
    url: 'https://example.com/live/stream.flv',
    isLive: true
}, {
    enableWorker: true,
    enableStashBuffer: false,
    stashInitialSize: 128,
    liveBufferLatencyChasing: true,
    liveBufferLatencyMaxLatency: 1.5,
    liveBufferLatencyMinRemain: 0.5,
    autoCleanupSourceBuffer: true
});

Low Latency Configuration Description

  • enableWorker: true: Enable Web Worker to avoid parsing blocking the main thread
  • enableStashBuffer: false: Disable stash buffer to reduce latency
  • stashInitialSize: 128: Initial stash size (KB), set a smaller value
  • liveBufferLatencyChasing: true: Enable live stream latency chasing
  • liveBufferLatencyMaxLatency: 1.5: Maximum latency 1.5 seconds, speed up if exceeded
  • liveBufferLatencyMinRemain: 0.5: Minimum buffer 0.5 seconds
  • autoCleanupSourceBuffer: true: Automatically clean up buffer to avoid memory growth

Other Optimization Recommendations

  • Use HTTP/1.1 persistent connections: Reduce handshake overhead
  • Set GOP length appropriately: Set GOP length to 1-2 seconds on the streaming end
  • Use MPEG-TS over WebSocket: WebSocket has lower latency
  • CDN optimization: Choose a CDN that supports low-latency live streaming
  • Encoding parameter optimization: Use baseline profile to reduce encoding latency

Event Listening

FLV.js provides a rich event system that can listen to various state changes.

Common Events

flvPlayer.on(flvjs.Events.ERROR, function(errorType, errorDetail, errorInfo) {
    console.log('Error:', errorType, errorDetail, errorInfo);
});

flvPlayer.on(flvjs.Events.LOADING_COMPLETE, function() {
    console.log('Loading complete');
});

flvPlayer.on(flvjs.Events.RECOVERED_EARLY_EOF, function() {
    console.log('Recovered from unexpected end');
});

flvPlayer.on(flvjs.Events.MEDIA_INFO, function(mediaInfo) {
    console.log('Media info:', mediaInfo);
});

flvPlayer.on(flvjs.Events.STATISTICS_INFO, function(statInfo) {
    console.log('Statistics info:', statInfo);
});

Event Type Description

  • ERROR: Triggered when an error occurs
  • LOADING_COMPLETE: Triggered when data loading is complete (VOD)
  • RECOVERED_EARLY_EOF: Reconnected after live stream unexpected disconnection
  • MEDIA_INFO: Obtained media metadata information
  • STATISTICS_INFO: Playback statistics (updated every second)
  • BUFFER_EMPTY: Buffer is empty, may stutter
  • BUFFER_FULL: Buffer is full

Error Handling

Comprehensive error handling is essential for production environments. FLV.js errors are divided into different types that require targeted handling.

Error Types

  • NETWORK_ERROR: Network errors, such as connection failure, timeout, etc.
  • MEDIA_ERROR: Media errors, such as decoding failure, unsupported format, etc.
  • OTHER_ERROR: Other errors

Complete Error Handling Example

flvPlayer.on(flvjs.Events.ERROR, function(errorType, errorDetail, errorInfo) {
    console.error('Player error:', errorType, errorDetail);

    if (errorType === flvjs.ErrorTypes.NETWORK_ERROR) {
        if (errorDetail === flvjs.ErrorDetails.NETWORK_STATUS_CODE_INVALID) {
            console.log('HTTP status code error, link may be invalid');
        } else if (errorDetail === flvjs.ErrorDetails.NETWORK_TIMEOUT) {
            console.log('Network timeout, attempting to reconnect...');
            retryPlay();
        }
    } else if (errorType === flvjs.ErrorTypes.MEDIA_ERROR) {
        console.log('Media error, attempting to recover...');
        flvPlayer.recoverMediaError();
    }
});

function retryPlay() {
    flvPlayer.unload();
    flvPlayer.load();
    flvPlayer.play();
}

Auto-Reconnection Mechanism

For live streaming scenarios, stream interruption due to network fluctuations is a common issue. It is recommended to implement an auto-reconnection mechanism:

let retryCount = 0;
const maxRetry = 5;

flvPlayer.on(flvjs.Events.ERROR, function(errorType) {
    if (errorType === flvjs.ErrorTypes.NETWORK_ERROR && retryCount < maxRetry) {
        retryCount++;
        setTimeout(function() {
            flvPlayer.unload();
            flvPlayer.load();
            flvPlayer.play();
        }, 2000 * retryCount);
    }
});

flvPlayer.on(flvjs.Events.RECOVERED_EARLY_EOF, function() {
    retryCount = 0;
});

Best Practices

1. Browser Compatibility Detection

Before initialization, check if the browser is supported, and provide a friendly prompt if not:

if (flvjs.isSupported()) {
    initPlayer();
} else {
    alert('Your browser does not support FLV playback. Please use Chrome, Firefox, or Edge browser');
}

2. Proper Destruction Timing

When the page unloads or switches videos, be sure to destroy the player to release resources:

window.addEventListener('beforeunload', function() {
    if (flvPlayer) {
        flvPlayer.pause();
        flvPlayer.unload();
        flvPlayer.detachMediaElement();
        flvPlayer.destroy();
        flvPlayer = null;
    }
});

3. Handling CORS Cross-Origin

Ensure the video server is configured with the correct CORS headers, otherwise FLV.js cannot load. Required response headers include:

  • Access-Control-Allow-Origin: * (or specified domain)
  • Access-Control-Allow-Methods: GET, POST, OPTIONS
  • Access-Control-Expose-Headers: Content-Length

4. Handling After Live Stream Pause

After pausing a live stream and resuming playback, it will continue from the paused position, leading to accumulated latency. It is recommended to seek to the latest position when resuming after pause:

videoElement.addEventListener('play', function() {
    if (flvPlayer && flvPlayer.config.isLive) {
        const livePosition = videoElement.buffered.end(0) - 1;
        if (videoElement.currentTime < livePosition - 3) {
            videoElement.currentTime = livePosition;
        }
    }
});

Summary

FLV.js is an excellent open-source FLV player that provides a high-performance, low-latency solution for web-based live streaming. Its pure JavaScript implementation requires no plugins, and when combined with the HTTP-FLV protocol, can achieve a low-latency experience close to the Flash era.

For users who want to quickly experience FLV playback, you can directly use our FLV/RTMP Online Player, just paste the live stream address to watch in your browser, no code required.

Related Recommendations

More great articles and useful tools

Want to Play FLV Live Streams?

Use our free FLV online player, just paste the address to play, supports screenshots, recording, and low latency mode

Try It Now ➡