🚀 Basic Conversion
ffmpeg -i "https://example.com/playlist.m3u8" -c copy output.mp4
-c copy
- Meaning: Copy streams without re-encoding
- Effect: Fastest conversion method - simply copies the video and audio streams as-is from the source to the output file
- Usage: When the source format is compatible with the output container
🛠️🎧 -bsf:a aac_adtstoasc
ffmpeg -i input.m3u8 -c copy -bsf:a aac_adtstoasc output.mp4
M3U8 files typically contain TS segments with AAC audio. When you copy these directly to MP4, the AAC audio might not play properly because:
- M3U8/TS files: AAC audio is packaged differently
- MP4 files: Require specific AAC headers that TS files don’t have
The bitstream filter fixes this by restructuring the AAC data to be MP4-compatible.
- Meaning: Bitstream Filter for Audio that converts AAC Data Transport Stream To Audio Specific Config
- Effect: Fixes AAC audio in MP4 container by adding proper header information
- When needed: Required when copying AAC audio from TS (Transport Stream) to MP4 format
Re-encoding With specific video/audio codecs
ffmpeg -i "input.m3u8" -c:v libx264 -c:a aac output.mp4
-c:v libx264: Use the H.264 video codec (via the libx264 encoder).-c:a aac: Use AAC audio codec
Specify quality and preset
ffmpeg -i "input.m3u8" -c:v libx264 -preset medium -crf 23 -c:a aac -b:a 128k output.mp4
-preset medium- Sets the encoding speed vs. compression efficiency trade-off.
- Available presets:
ultrafast,superfast,veryfast,faster,fast,medium,slow,slower,veryslow. - medium is the default and a good balance between speed and quality.
- Constant Rate Factor (
-crf) controls video quality and file size.- Lower CRF = better quality & larger file.
- Higher CRF = lower quality & smaller file.
- Range is 0–51 (where 0 is lossless, 18–28 is common).
- 23 is a reasonable default.
Set output resolution
ffmpeg -i "input.m3u8" -vf "scale=1280:720" -c:a copy output.mp4
-vf "scale=1280:720": Resize video to 720p
With user agent (for protected streams)
ffmpeg -user_agent "Mozilla/5.0" -i "input.m3u8" -c copy output.mp4
With timeout and retry options
ffmpeg -timeout 3000000 -reconnect 1 -i "input.m3u8" -c copy output.mp4
⏳ -timeout 3000000
- Sets the network timeout for reading from the input URL.
- Unit: microseconds (3000000 µs = 3 seconds)
- If no data is received within this time, the connection is considered stalled.
- Useful for unreliable or slow network conditions.
⚠️ Note: -timeout is a protocol-level option and may only work with certain protocols (like http or https), not all input types.
🔁 -reconnect 1
- Tells ffmpeg to reconnect automatically if the connection is dropped.
- Useful when streaming from unstable sources (e.g., live HLS feeds).
⚠️ Like -timeout, this flag only works with certain input protocols (e.g. http, https, tcp). It may not work if not placed before -i, or if the protocol doesn’t support it.
Specify segment duration and format
ffmpeg -i "input.m3u8" -f mp4 -movflags faststart -c copy output.mp4
⚡ -movflags faststart
ffmpeg -i "https://example.com/stream.m3u8" -c copy -movflags faststart -stats output.mp4
- Moves the moov atom (index of the .mp4 file) to the beginning of the file.
- Essential for progressive download / streaming (e.g., HTML5
<video>tags). - Without this, the video won’t start playing until the whole file is downloaded.
Add Headers
There are several ways to add headers to FFmpeg requests. Here are the most common methods:
1. Using -headers Option
ffmpeg -headers "User-Agent: Mozilla/5.0
Referer: https://example.com
Origin: https://example.com
Cookie: session=abc123" -i "input.m3u8" output.mp4
2. Using -user_agent Option (for User-Agent only)
ffmpeg -user_agent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" -i "input.m3u8" output.mp4
3. Multiple Header Options
ffmpeg -user_agent "Mozilla/5.0" -headers "Referer: https://example.com
Authorization: Bearer token123" -i "input.m3u8" output.mp4
4. Common Headers for Different Scenarios
For HLS Streams with Protection:
ffmpeg -headers "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Referer: https://streaming-site.com/
Origin: https://streaming-site.com/
X-Requested-With: XMLHttpRequest" -i "input.m3u8" output.mp4
With Authentication:
ffmpeg -headers "Authorization: Bearer your_token_here
User-Agent: Mozilla/5.0" -i "input.m3u8" output.mp4
With Cookies:
ffmpeg -headers "Cookie: session_id=abc123; user_pref=dark
User-Agent: Mozilla/5.0" -i "input.m3u8" output.mp4
5. Using Header File
Create a headers.txt file:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Referer: https://example.com
Origin: https://example.com
Accept: */*
Accept-Language: en-US,en;q=0.9
Accept-Encoding: gzip, deflate, br
Then use
ffmpeg -headers @headers.txt -i "input.m3u8" output.mp4