How to save HLS stream to local disk in source code by ffmpeg?
Categories:
Recording HLS Streams to Local Disk with FFmpeg

Learn how to programmatically capture and save HTTP Live Streaming (HLS) content to your local storage using FFmpeg, a powerful multimedia framework.
HTTP Live Streaming (HLS) is a widely adopted adaptive streaming protocol for delivering video and audio content over the internet. While designed for live playback, there are many scenarios where you might need to save an HLS stream to a local file for offline viewing, archival, or further processing. FFmpeg is an incredibly versatile command-line tool and library that excels at handling various multimedia tasks, including capturing and converting streams. This article will guide you through the process of using FFmpeg within your source code to reliably record HLS streams.
Understanding HLS and FFmpeg's Role
HLS streams consist of a master playlist (typically an .m3u8
file) that points to media playlists, which in turn list short media segments (usually .ts
files). FFmpeg is capable of parsing these playlists, downloading the segments, and concatenating them into a single output file. It handles the complexities of stream detection, segment downloading, and re-muxing into a desired container format like MP4 or MKV.
flowchart TD A[HLS Stream URL (.m3u8)] --> B{FFmpeg Process} B --> C[Parse Master Playlist] C --> D[Identify Media Playlists] D --> E[Download Media Segments (.ts)] E --> F[Concatenate & Re-mux] F --> G[Local Output File (e.g., .mp4)]
FFmpeg HLS Recording Workflow
Basic FFmpeg Command for HLS Recording
The simplest way to record an HLS stream using FFmpeg involves specifying the input HLS URL and the desired output file. FFmpeg will automatically detect the stream type and attempt to save it. For live streams, you might need to specify a duration or rely on the stream ending naturally. For VOD (Video On Demand) HLS, FFmpeg will download all available segments.
ffmpeg -i "http://example.com/live/stream.m3u8" -c copy -bsf:a aac_adtstoasc "output.mp4"
Basic FFmpeg command to record an HLS stream.
-c copy
option tells FFmpeg to copy the audio and video streams directly without re-encoding. This is much faster and preserves original quality. The -bsf:a aac_adtstoasc
bitstream filter is often necessary for AAC audio when re-muxing from TS segments to MP4.Integrating FFmpeg into Source Code
To integrate FFmpeg into your application, you typically execute FFmpeg as a child process. This allows your program to control the recording process, including starting, stopping, and monitoring its progress. Most programming languages provide mechanisms to spawn external processes and capture their output. Below are examples for Python and Node.js, demonstrating how to execute the FFmpeg command.
Python
import subprocess
hls_url = "http://example.com/live/stream.m3u8" output_file = "recorded_stream.mp4"
command = [ "ffmpeg", "-i", hls_url, "-c", "copy", "-bsf:a", "aac_adtstoasc", output_file ]
try: process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate()
if process.returncode == 0:
print(f"HLS stream successfully recorded to {output_file}")
else:
print(f"Error recording HLS stream: {stderr.decode('utf-8')}")
except FileNotFoundError: print("FFmpeg not found. Please ensure it's installed and in your PATH.") except Exception as e: print(f"An error occurred: {e}")
Node.js
const { spawn } = require('child_process');
const hlsUrl = "http://example.com/live/stream.m3u8"; const outputFile = "recorded_stream.mp4";
const commandArgs = [ "-i", hlsUrl, "-c", "copy", "-bsf:a", "aac_adtstoasc", outputFile ];
const ffmpegProcess = spawn('ffmpeg', commandArgs);
ffmpegProcess.stdout.on('data', (data) => {
console.log(stdout: ${data}
);
});
ffmpegProcess.stderr.on('data', (data) => {
// FFmpeg often outputs progress to stderr
console.error(stderr: ${data}
);
});
ffmpegProcess.on('close', (code) => {
if (code === 0) {
console.log(HLS stream successfully recorded to ${outputFile}
);
} else {
console.error(FFmpeg process exited with code ${code}
);
}
});
ffmpegProcess.on('error', (err) => { console.error('Failed to start FFmpeg process:', err); });
Advanced Recording Options
FFmpeg offers many options for more granular control over the recording process. Here are a few common ones:
1. Limiting Recording Duration
Use the -t
option to specify a duration in seconds or HH:MM:SS
format. This is crucial for recording live streams for a fixed period.
2. Overwriting Existing Files
Add -y
to automatically overwrite the output file if it already exists, preventing FFmpeg from prompting for confirmation.
3. Specifying Start Offset
Use -ss
before the input (-i
) to start recording from a specific timestamp within the HLS stream (if supported by the stream).
4. Handling Network Issues
For unstable networks, consider adding -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5
to allow FFmpeg to attempt reconnection if the stream drops.
ffmpeg -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5 -i "http://example.com/live/stream.m3u8" -t 00:01:00 -c copy -bsf:a aac_adtstoasc -y "output_60s.mp4"
FFmpeg command with duration, overwrite, and reconnection options.
By leveraging FFmpeg's robust capabilities and integrating it into your applications, you can effectively capture and manage HLS streams for various purposes. Always refer to the official FFmpeg documentation for the most up-to-date and comprehensive list of options.