nginx-vod-module icon indicating copy to clipboard operation
nginx-vod-module copied to clipboard

How to configure adaptive bitrate for VOD application.

Open Nabute opened this issue 2 years ago • 10 comments

I have an application that's used for event video streaming and I was wondering if there is a way to correctly configure the adaptive bitrate feature of this module. It turns out that I couldn't find enough resources to implement it by myself.

Here is my current configuration, it streams a video from the media folder but it's not in an adaptive way.

http {
    include       mime.types;
    default_type  application/octet-stream;
    client_max_body_size 500M;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    sendfile        off;
    tcp_nopush      on;
    tcp_nodelay     on;

    aio on;
    directio 512;


    keepalive_timeout  65;

    vod_mode                           local;
    vod_metadata_cache                 metadata_cache 16m;
    vod_response_cache                 response_cache 512m;
    vod_last_modified_types            *;
    vod_segment_duration               9000;
    vod_align_segments_to_key_frames   on;
    vod_dash_fragment_file_name_prefix "segment";
    vod_hls_segment_file_name_prefix   "segment";
    

    vod_manifest_segment_durations_mode accurate;

    open_file_cache          max=1000 inactive=5m;
    open_file_cache_valid    2m;
    open_file_cache_min_uses 1;
    open_file_cache_errors   on;

    upstream my_app {
        server backend:8000;
    }

    server {
        listen 80;
        server_name example .com;

        location /.well-known/acme-challenge/ {
            root /var/www/certbot;
        } 
        
        location / {
            return 301 https://$host$request_uri;
        }

    }

    server {
        listen       443 ssl;
        server_name  example.com;

        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; 

        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

        location / {
            proxy_pass http://my_app;
            proxy_set_header X-Forwarded-Proto https;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_set_header Authorization $http_authorization;
            proxy_pass_header Authorization;
            proxy_redirect off;
            
            proxy_read_timeout 1200;
        }

        location /staticfiles/ {
            alias /home/backend/staticfiles/;
            add_header Access-Control-Allow-Headers '*';
            add_header Access-Control-Allow-Origin '*';
            add_header Access-Control-Allow-Methods 'GET, HEAD, OPTIONS';
        }

        location /mediafiles {
            alias /home/backend/mediafiles/;

            location /mediafiles/hls/ {
                vod hls;
                vod_multi_uri_suffix .urlset;
                alias /home/backend/mediafiles/hls/;
                add_header Access-Control-Allow-Headers '*';
                add_header Access-Control-Allow-Origin '*';
                add_header Access-Control-Allow-Methods 'GET, HEAD, OPTIONS';
            }
        }

        
       error_page   500 502 503 504  /50x.html;
        
        location = /50x.html {
            root   html;
        }

    }
    
    
}

Nabute avatar Nov 22 '21 05:11 Nabute

https://github.com/kaltura/nginx-vod-module/issues/1320#issuecomment-976875720

erankor avatar Nov 23 '21 17:11 erankor

@erankor Thank you for your comment and I saw the content but it's not clear on how I can implement that. It would be great if you can provide an example of how I can implement your comment in #1320.

Nabute avatar Nov 24 '21 12:11 Nabute

For example, you are serving files from /home/backend/mediafiles/hls/, if you create multiple renditions there with the names - sample_400k.mp4, sample_900k.mp4, sample_1500k.mp4, then you can call -http://yourserver/mediafiles/hls/sample_,4,9,15,00k.mp4.urlset/master.m3u8 and get an hls stream with all 3 renditions.

erankor avatar Nov 25 '21 08:11 erankor

Well, I tried to go with the multiple rendition process and I was able to generate the multiple files as shown in the image below using this blog.

image

Which is a bit different than your suggestion. that is sample_,4,9,15,00k.mp4.urlset but I replaced it with the directory name for the list of rendition values including the playlist.m3u8 file and the video streaming link become http://server/mediafiles/hls/e6f71feb_1f66_41e2_8a91_b2c3f002ce0c/playlist.m3u8 but still it's not working for me. What is your suggestion?

Nabute avatar Nov 25 '21 17:11 Nabute

From the screenshot, it seems you didn't just transcode to multiple renditions, you also packaged it in HLS. In general, you can either prepackage the content to HLS, or use this module to do it on-the-fly. If you prepackage, you don't need this module, you just need a location with a simple nginx root/alias directive to serve the files. If you want to perform the packaging on-the-fly (which has several benefits, e.g. supporting both HLS&DASH without paying x2 storage), you need to provide this module with multiple MP4s, not m3u8...

erankor avatar Nov 27 '21 13:11 erankor

I got you. The first one is totally understandable and will keep it in mind in case the second one won't work for me. But I want to understand more about the second option that you mentioned since I have limited storage. So how can I provide the multiple MP4s to the module? Is it using ffmpeg or another feature under this module?

Nabute avatar Nov 27 '21 14:11 Nabute

I have the same problem...and i was trying to do the on-the-fly method using this module, @erankor i found similar issue that you answered before https://github.com/kaltura/nginx-vod-module/issues/284#issuecomment-209297592 it look like you are preparing the videos advance...it's conflict with the second option ...that you just suggested .

Mohamed-Kaizen avatar Nov 28 '21 05:11 Mohamed-Kaizen

@Nabute, you need to first make sure you have multiple MP4s for each video with different qualities, you can use ffmpeg for this (as you already did) but use MP4 for the output format instead of HLS. Once you have multiple MP4s, you can provide them to the module using the multiurl syntax - https://github.com/kaltura/nginx-vod-module/#multi-url-structure.

@Mohamed-Kaizen, there is no conflict, transcoding is a very intensive task, I don't think it makes sense to retranscode the video every time it is evicted from CDN cache. Packaging, on the other hand, can be implemented efficiently. So, yes, you have an MP4 on the storage per quality, but you don't have it multiplied by the number of delivery protocols. For example, you may want HLS + DASH + MP4 (for download), if you don't use this module, you will use x3 storage.

erankor avatar Nov 28 '21 09:11 erankor

@erankor Thank you so much. It's working well now!

Nabute avatar Nov 28 '21 20:11 Nabute

@erankor Thank you so much.

Mohamed-Kaizen avatar Dec 07 '21 15:12 Mohamed-Kaizen