How to reduce the latency of CMAF?

451 Views Asked by At

I implemented CMAF through a self-built nginx server with ffmpeg, but I encountered some technical bottlenecks. My latency always remains at 3 seconds and cannot be further reduced. Additionally, I'm unable to successfully implement chunked transfer.

Briefly describe my environment, I use OBS to push the live stream to the server, then transcode it on the server, and finally push the content to users through CDN.

Here is some of my code

ffmpeg:

sudo ffmpeg -i rtmp://127.0.0.1:1935/live/stream -loglevel 40 -c copy -sc_threshold 0 -g 60 -bf 0 -map 0 -f dash -strict experimental -use_timeline 1 -use_template 1 -seg_duration 1 -window_size 5 -adaptation_sets "id=0,streams=v id=1,streams=a" -streaming 1 -dash_segment_type mp4 -utc_timing_url "http://time.akamai.com/?iso" -movflags frag_keyframe+empty_moov+default_base_moof -ldash 1 -hls_playlist 1 -master_m3u8_publish_rate 1 -remove_at_exit 1 /var/www/html/live/manifest.mpd

nignx config:

server_name myserver.com;
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
    add_header Access-Control-Expose-Headers 'Content-Length,Content-Range';
    root /var/www/html;
    index index.html index.nginx-debian.html;
        location / {
            chunked_transfer_encoding on;
        }

html player

<!DOCTYPE html>
<html lang="zh-tw">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>streaming test</title>
    <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
    <script src="https://cdn.dashjs.org/latest/dash.all.min.js"></script>
    <style>
        body {
            margin: 0;
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            background-color: #000;
        }

        #video {
            max-width: 100%;
            max-height: 100vh;
        }
    </style>
</head>
<body>
    <video id="video" controls></video>

    <script>
        const video = document.getElementById('video');
        const hlsSrc = '/live/master.m3u8'; // Replace with your HLS stream URL
        const dashSrc = '/live/stream.mpd'; // Replace with your DASH stream URL

        function isHlsSupported() {
            return Hls.isSupported() || video.canPlayType('application/vnd.apple.mpegurl');
        }

        function isDashSupported() {
            return !!window.MediaSource && !!MediaSource.isTypeSupported('video/mp4; codecs="avc1.4d401e,mp4a.40.2"');
        }

        if (isHlsSupported()) {
            // Use HLS for playback
            const hls = new Hls({
                lowLatencyMode: true,// Enable low-latency mode
                liveSyncDurationCount: 1, // Number of segments used to sync live stream
                liveMaxLatencyDurationCount: 2,// Number of segments used to calculate the latency
                maxBufferLength: 2,// Max buffer length in seconds
                maxBufferSize: 1000 * 1000 * 100,// Max buffer size in bytes
                liveBackBufferLength: 0// Max back buffer length in seconds (0 means back buffer disabled)
            });
            hls.loadSource(hlsSrc);
            hls.attachMedia(video);
            hls.on(Hls.Events.MANIFEST_PARSED, () => {
                video.play();
            });
        } else if (isDashSupported()) {
            // Use DASH for playback
            const player = dashjs.MediaPlayer().create();
            player.initialize(video, dashSrc, true);
            player.updateSettings({
                streaming: {
                    lowLatencyEnabled: true, // Enable low-latency mode
                    liveDelay: 1, // Set live delay in seconds, equal to 3 times the segment duration
                    liveCatchUpPlaybackRate: 1.2, // Playback rate for catching up when behind the live edge
                    liveCatchUpMinDrift: 0.5, // Minimum drift from live edge before initiating catch-up (in seconds)
                    bufferTimeAtTopQuality: 3, // Maximum buffer length in seconds
                    bufferToKeep: 0, // Duration of the back buffer in seconds (disable back buffer)
                }
            });
        } else {
            console.error('Neither HLS nor DASH playback is supported in this browser.');
        }
    </script>
</body>
</html>

I hope to reduce the latency to 1 second.

0

There are 0 best solutions below