Results 1 to 7 of 7

Thread: Best HLS packetizer setting for given bandwidth

  1. #1

    Question Best HLS packetizer setting for given bandwidth

    Hello and good time of day.

    Can you give some tips how to determine the most suitable settings for given channel bandwidth to minimize stalled time?
    We using version 4.0.4

    Thanks in advance.

  2. #2

    Default

    Hello there.

    I am not sure exactly what you are asking here.

    You can use this guide to configure the HLS packetization:
    How to configure Apple HLS packetization (cupertinostreaming)

    To estimate how much memory is used to store the chunks for a single live stream, use the following formula:
    [total-memory-mb] = ([stream-bitrate-kbps]/([1024-kb-per-mb]*[8-bits-per-byte])) * [cupertinoChunkDurationTarget-seconds] * [cupertinoMaxChunkCount]

    For example, a 500 kbps stream consumes the following amount of memory, given the default settings from the guide:

    (500/(1024*8)) * 10 * 10 = 6 MB of memory

    To calculate the number of connections you can support, you can use this formula:

    number of users * stream bitrate + 20% IP overhead = total server bandwidth

    With a 1g nic (20% overhead accounted for) = 800mbs throughput, which is 800 1 mbs streams, or 1600 500kbs streams.

    You will have to test your actual server/network using the load test tool, or monitoring utilization in production. You must be properly tuned. And to achieve maximum levels you may have to tune your server and network in other ways outside Wowza.

    I hope this is helpful.

    Kind regards,

    Salvadore

  3. #3

    Default

    Big thanks, i read this article and it was helpful, but i it not what i asking.

    I should detect what values of cupertinoChunkDurationTarget, cupertinoMaxChunkCount, cupertinoPlaylistChunkCount, cupertinoRepeaterChunkCount are the best for live channel when broadcasting to mobile devices, but have no idea how to check channel health with set of parameters not only by own eyes.

  4. #4

    Default

    HTTP streaming sends chunks to the client. The client needs 3 chunks cached before it starts playing.

    By default Wowza is set to send 3, 10 second chunks (cupertinoPlaylistChunkCount) in each packet sent to the client.

    Chunks must start on a key frame. So it is best to use a key frame interval that is factor of the cupertinoChunkDurationTarget setting.
    Try 2 second key frame frequency and cupertinoChunkDurationTarget "2000" (2 seconds)

    cupertinoMaxChunkCount is the total number of chunks that are maintained. So as the stream moves a bit further off of live, the player will start to request segments from further in the past. Having a larger list of chunks in reserve will insure this does not lead to a missing chunk error.

    Kind regards,

    Salvadore

  5. #5

    Default

    Thanks, it helps keep stream live, but don't helps determine it's quality.

    Ok, i try to search not so strait method, may be javascript script that scan video current time and alert if video stalled for more then 2 seconds.

  6. #6

    Default

    I am sorry, but I am not clear on what you are asking.

    Can you please try to explain it again?

    Thank you.

    Salvadore

  7. #7

    Default

    Hmm, i need a tool to check channel health not only by my own eyes.

    I wrote this javascript, but it register only errors, and if no stalled times, then i don't know how it goes with current settings and what difference between two set of configuration variables.

    <html><head>
    <meta http-equiv="content-type" content="text/html; charset=windows-1251"><style type="text/css">
    video{
        width: 854px;
        height: 480px;
        }
        
    #liniya { 
        float:left; 
        margin-left:15px; 
        text-align:center;
        }
    </style>
    
    </head><body>
    
    
    <div style=" width:100%; height:1px; clear:both;"></div>
    <div id="liniya">
    <video id="video" controls="controls" preload="none"> 
    
      <source src="http://*/test/video/playlist.m3u8" type="video/mp4">
    
    
    <!--<source src="http://mirrorblender.top-ix.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_stereo.ogg?"+Math.random() type=video/ogg />-->
    </video>
    </div> 
    
    <div id="liniya">
    <table>
    <tbody><tr>
    <td><input id="progress" type="text"></td>
    <td><input id="percent" type="text"></td>
    </tr>
    <tr><td colspan="2"><textarea rows="1" cols="60" name="info" id="info">videotime 0: 0.00  videotime 1: 0.00 | 0.00 | 0</textarea></td></tr>
    <tr><td colspan="2"><textarea rows="1" cols="60" name="buffered" id="buffered"></textarea></td></tr>
    <tr><td colspan="2"><textarea rows="1" cols="60" name="played" id="played"></textarea></td></tr>
    <tr><td colspan="2"><textarea rows="25" cols="60" name="text" id="text"></textarea></td></tr>
    <tr><td colspan="2"><textarea rows="25" cols="60" name="data" id="data"></textarea></td></tr>
    </tbody></table>
    </div>
    
    <div style=" width:100%; height:1px; clear:both;"></div>
    
    
    
    <script type="text/javascript">
    var progress_counter = 0;
    var start = new Date();
    var current = new Date();
    var time = 0;
    var videotime_0 = 0;
    var videotime_1 = 0;
    var video_current = 0;
    
    var stalled_guard_lock = false;
    var error_count = 0;
    var last_error_time = new Date();
    var atbe = 0; // average time between errors
    
    var time_update_counter = 0;
    
    
    
    txt = document.getElementById("text");
    video = document.getElementById("video");
    progress = document.getElementById("progress");
    info = document.getElementById("info");
    percent = document.getElementById("percent");
    buffer = document.getElementById("buffered");
    data = document.getElementById("data");
    played = document.getElementById("played");
    
    function timer() { 
    	info.value = "videotime 0: " + videotime_0.toFixed(2) + "  videotime 1: " + videotime_1.toFixed(2) + " | "+Math.abs(videotime_1-videotime_0).toFixed(2) + ' | ' + time_update_counter;
    	buffer.value = "Buffer Start: " + video.buffered.start(0) + " End: " + video.buffered.end(0) + ' | '+ 'ReadyState = '+ video.readyState;
    	played.value = "Played Start: " + video.played.start(0) + " End: " + video.played.end(0).toFixed(2) + ' | '+ 'Paused = '+ video.paused;
    
    }
    
    setInterval(timer, 1000);
    
    
    function video_timer() { 
    	stalled_guard_lock = false;
    	if (video_current == 0){
    		videotime_0 = video.currentTime;
    		//videotime_0 = time_update_counter;
    		video_current = 1;
    		return;
    	}
    	if (video_current == 1){
    		videotime_1 = video.currentTime;
    		//videotime_1 = time_update_counter;
    		video_current = 0;
    		return;
    	}
    
    }
    
    setInterval(video_timer, 1000);
    
    function stalled_guard() { 
    	var now = new Date();
    	if ( Math.abs(videotime_1-videotime_0) > 2) {
    		if (stalled_guard_lock) return;
    		txt.value += "Stalled for "+Math.abs(videotime_1-videotime_0).toFixed(2)+" seconds.\n";
    		error_count += 1;
    		progress.value = "Error count: " + error_count;
    		atbe += (now - last_error_time)/1000;
    		last_error_time = new Date();
    		percent.value = "atbe: " + (atbe/error_count).toFixed(2);
    		stalled_guard_lock = true;	
    	}
    
    }
    
    setInterval(stalled_guard, 100);
    
    
    
    video.addEventListener("progress", function(){
        progress_counter+=1;
        progress.value = 'Progress Events: '+progress_counter;
        var percentLoaded = parseInt(((video.buffered.end(0) / video.duration) * 100));
        document.getElementById("percent").value = 'Loaded: ' + percentLoaded + ' %';
        }, false)
    
    window.addEventListener("load", function(){txt.value = ""}, false)
    
    video.addEventListener("abort", function(){txt.value += "loading of an audio/video is aborted\n"}, false)
    
    video.addEventListener("canplay", function(){txt.value += "can start playing\n"}, false)
    video.addEventListener("durationchange", function(){
    	txt.value += "duration changed\n"
    	/*for (var prop in video.attributes){
    		data.value += prop +' = ' + video.attributes[prop] + '\n';
    	}*/
    
    
    }, false)
    
    video.addEventListener("ended", function(){txt.value += "ended\n"}, false)
    video.addEventListener("error", function(){txt.value += "error occurred during the loading\n"}, false)
    
    video.addEventListener("loadeddata", function(){txt.value += "loaded the current frame\n"}, false)
    video.addEventListener("loadedmetadata", function(){txt.value += "metadata loaded\n"}, false)
    
    video.addEventListener("loadstart", function(){txt.value += "starts looking for the video\n"}, false)
    
    video.addEventListener("pause", function(){txt.value += "video has been paused\n"}, false)
    
    video.addEventListener("play", function(event){
    	txt.value += "video has been started / unpaused\n";
    	info.value = video.currentSrc;
    	//alert(event.target.src);
    	}, false)
    
    video.addEventListener("playing", function(){
    	txt.value += "ready to play\n"
    	start = new Date();
    	}, false)
    
    video.addEventListener("seeking", function(){txt.value += "seeking start\n"}, false)
    video.addEventListener("seeked", function(){txt.value += "seeking end\n"}, false)
    
    video.addEventListener("stalled", function(){txt.value += "trying to get media data, but data is not available\n"}, false)
    
    video.addEventListener("timeupdate", function(){
    	time_update_counter += 1;
    	info.value = "videotime 0: " + videotime_0.toFixed(2) + "  videotime 1: " + videotime_1.toFixed(2) + " | "+Math.abs(videotime_1-videotime_0).toFixed(2) + ' | ' + time_update_counter;
    
    	}, false)
    video.addEventListener("waiting", function(){txt.value += "needs to buffer the next frame\n"}, false)
    
    video.addEventListener("canplaythrough", function(){txt.value += "Can play through video without stopping\n"}, false)
    
    </script>
    
    
    </body></html>

Similar Threads

  1. HLS packetizer responses for invalid streams
    By johnsterling in forum Live Streaming and Encoder Discussion
    Replies: 6
    Last Post: 07-01-2014, 04:01 AM
  2. Cupertino packetizer - on chunk ready?
    By aegeli in forum Wowza Streaming Server Java API
    Replies: 2
    Last Post: 06-12-2014, 10:45 AM
  3. Setting up Wowza for HLS chunking and streaming
    By spence in forum General Forum
    Replies: 5
    Last Post: 10-24-2013, 12:07 PM
  4. Packetizer source.stream: how to disabled?
    By dilonge in forum AddOn: Transcoder
    Replies: 7
    Last Post: 12-18-2012, 10:29 AM
  5. Packetizer events
    By slalompoint in forum Server-side Modules and Code Samples Discussion
    Replies: 4
    Last Post: 01-17-2012, 07:53 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •