Skip to content

Instantly share code, notes, and snippets.

@DevStefIt
Last active July 5, 2025 07:47
Show Gist options
  • Save DevStefIt/cf18fd8ac8627985d42f3d8ffe28720c to your computer and use it in GitHub Desktop.
Save DevStefIt/cf18fd8ac8627985d42f3d8ffe28720c to your computer and use it in GitHub Desktop.
HLS and DASH guide on an Nginx server with RTMP mode enabled, with FFmpeg as support
ffmpeg -re -i INPUT -c:v libx264 -c:a aac -preset slower -f dash ARBITRARY_NAME.mpd
# Remember to redirect all the stream files (the .ts files) in the playlist files (the .m3u8 files) using
ffmpeg -i 'input_file.mkv' \
-filter_complex \
"[0:v]split=3[v1][v2][v3]; \
[v1]copy[v1out]; [v2]scale=w=640:h=360[v2out]; [v3]scale=w=352:h=288[v3out]" \
-map [v1out] -c:v:0 libx264 -b:v:0 5M -maxrate:v:0 5M -minrate:v:0 5M -bufsize:v:0 10M -preset slow \
-map [v2out] -c:v:1 libx264 -b:v:1 3M -maxrate:v:1 3M -minrate:v:1 3M -bufsize:v:1 3M -preset slow \
-map [v3out] -c:v:2 libx264 -b:v:2 1M -maxrate:v:2 1M -minrate:v:2 1M -bufsize:v:2 1M -preset slow \
-map a:0 -c:a:0 aac -b:a:0 96k -ac 2 \
-map a:0 -c:a:1 aac -b:a:1 96k -ac 2 \
-map a:0 -c:a:2 aac -b:a:2 48k -ac 2 \
-f hls \
-hls_time 2 \
-hls_playlist_type vod \
-hls_flags independent_segments \
-hls_segment_type mpegts \
-hls_segment_filename stream_%v/data%02d.ts \
-master_pl_name master.m3u8 \
-var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2" stream_%v.m3u8

First of all, we need to do all the things indicated here: https://gist.github.com/DevStefIt/23b8971db7e3fe084d29f2c915fb7773 We need to modify the Nginx configuration file:

sudo vim /etc/nginx/nginx.conf

Then, have to add the following lines in the existing RTMP configuration (or create a new one if you do not have it)

. . .
rtmp {
        server {
...
                application live {
                        live on;
                        record off;
                        hls on;
                        hls_path /var/www/html/stream/hls;
                        hls_fragment 3;
                        hls_playlist_length 60;
                        hls_cleanup off;

                        dash on;
                        dash_path /var/www/html/stream/dash;
                        dash_cleanup off;
                }
        }
}
...

We need to configure a block in the sites-available folder.

sudo vim /etc/nginx/sites-available/rtmp

And insert the following lines:

...
server {
    listen 8088;

    location / {
        add_header Access-Control-Allow-Origin *;
        root /var/www/html/stream;
    }
}

types {
    application/dash+xml mpd;
}

Port 8088 is chosen because it is different than the other chose ports.

We enable port 8088 in TCP mode on the firewall

sudo ufw allow 8088/tcp

We create the folders of interest

sudo mkdir -p /var/www/html/stream/hls
sudo mkdir -p /var/www/html/stream/dash

We also grant a reasonable access for the current user

sudo chown -R $USER:$USER /var/www/html/stream
sudo chmod -R 775 /var/www/html/stream

We reload Nginx

sudo systemctl reload nginx

If you would like to stream your file via RTMP

ffmpeg -re -i INPUT -c:v libx264 -c:a aac -preset ultrafast -tune zerolatency -f flv rtmp://127.0.0.1/live/ARBITRARY_NAME

To view the content via HLS:

http://server_ip:8088/hls/ARBITRARY_NAME.m3u8

To view the content via DASH:

http://server_ip:8088/dash/ARBITRARY_NAME.mpd

@francisuk1989
Copy link

francisuk1989 commented Mar 4, 2023

If anyone has a Nvidia GPU that compatible with Cuda https://developer.nvidia.com/cuda-downloads you can use the GPU instead of the CPU however i have only done this via linux ubuntu 22.04, I did have to compile ffmpeg but was easy as nvidia listed it step by step https://docs.nvidia.com/video-technologies/video-codec-sdk/ffmpeg-with-nvidia-gpu/index.html#compiling-for-linux

streaming_commands.md
Stream your file via RTMP with you NVIDA GPU and leave the CPU to do only Audio (AAC) what is VERY little CPU used.
ffmpeg -y -vsync 0 -i input -c:v h264_nvenc -c:a aac -tune zerolatency -f flv rtmp://127.0.0.1/live/ARBITRARY_NAME

ffmpeg_dash.sh
ffmpeg -y -vsync 0 -i input -c:v h264_nvenc -c:a aac -tune zerolatency -f dash ARBITRARY_NAME.mpd

@GbitencourtTA
Copy link

Hi I have a question, not sure if you or anyone else encountered a similar issue.

I'm working on a RaspberryPi 4b trying to stream HLS currently of just the video of "Big Buck Bunny.mp4". I followed the tutorial, the files created in the respective locations, and got of the tests to work, all except the last part where I try to view the stream using a variation of "http://server_ip:8088/hls/ARBITRARY_NAME.m3u8". Every time I try to access "http://(my raspberry pi's address):8088/hls/BBB.m3u8" to view it throws this error:

[tcp @ 0x7f70003f20] Connection to tcp://(my raspberry pi's address):8088 failed: Connection refused
http://(my raspberry pi's address):8088/hls/BBB.m3u8: Connection refused

I also tried using the "vlc media player" and it threw the error:

Your input can't be opened:
VLC is unable to open the MRL 'http://(my raspberry pi's address):8088/hls/BBB.m3u8'. Check the log for details.

I have confirmed the file is in the proper location. Any possible thoughts for a fix?

note any mention of (my raspberry pi's address) is to replace my real address, no I did not use that as the address when testing lol

@DevStefIt
Copy link
Author

@GbitencourtTA The first thing that can give you problems might be the firewall rules.
Try to take a look at my video about RTMP, where there is the first server configuration with ufw as firewall https://youtu.be/DBn_dS04kMY

@tkb1902
Copy link

tkb1902 commented Jan 16, 2025

try using this command to start stream but replace file name with yours and also the paths to your hls and dash root@TashingaPc:/mnt/d# ffmpeg -re -i 'Big_Buck_Bunny.mp4' -c:v libx264 -preset slower -tune zerolatency -c:a aac -f flv rtmp://localhost/live/bbb -f hls -hls_time 3 -hls_list_size 20 -hls_segment_filename "/var/www/html/stream/hls/segment_%03d.ts" "/var/www/html/stream/hls/index.m3u8" -f dash -seg_duration 3 -init_seg_name "init.m4s" -media_seg_name "chunk_%03d.m4s" "/var/www/html/stream/dash/manifest.mpd" -loglevel debug

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment