Skip to content

Commit

Permalink
Merge pull request #461 from fixedmachine/maxskippedfragments
Browse files Browse the repository at this point in the history
Add maxSkippedFragments setting to define max skipped fragments before throwing an error
  • Loading branch information
mangui committed Dec 17, 2015
2 parents 0ec0667 + 4cbe6e5 commit 21c1a27
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 9 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ The plugin accepts several **optional** configuration options, such as:
- `hls_fragmentloadskipaftermaxretry` (default true): control behaviour in case fragment load still fails after max retry timeout
* true : fragment will be skipped and next one will be loaded.
* false : an I/O Error will be raised.
- `hls_maxskippedfragments` (default 5): Maximum count of skipped fragments in a row before an I/O Error will be raised.
* 0 - no skip (same as fragmentLoadSkipAfterMaxRetry = false).
* -1 - no limit for skipping, skip till the end of the playlist.
- `hls_capleveltostage` (default false) : limit levels usable in auto-quality by the stage dimensions (width and height)
- true : level width and height (defined in m3u8 playlist) will be compared with the player width and height (stage.stageWidth and stage.stageHeight). Max level will be set depending on the `hls_maxlevelcappingmode` option. Note: this setting is ignored in manual mode so all the levels could be selected manually.
- false : levels will not be limited. All available levels could be used in auto-quality mode taking only bandwidth into consideration.
Expand Down
11 changes: 11 additions & 0 deletions src/org/mangui/hls/HLSSettings.as
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,17 @@ package org.mangui.hls {
*/
public static var fragmentLoadSkipAfterMaxRetry : Boolean = true;

/**
* maxSkippedFragments
*
* Maximum count of skipped fragments in a row before an I/O Error will be raised.
* 0 - no skip (same as fragmentLoadSkipAfterMaxRetry = false)
* -1 - no limit for skipping, skip till the end of the playlist
*
* Default is 5.
*/
public static var maxSkippedFragments : int = 5;

/**
* flushLiveURLCache
*
Expand Down
32 changes: 23 additions & 9 deletions src/org/mangui/hls/loader/FragmentLoader.as
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,22 @@ package org.mangui.hls.loader {
import flash.events.*;
import flash.net.*;
import flash.utils.ByteArray;
import flash.utils.getTimer;
import flash.utils.Timer;
import flash.utils.getTimer;

import org.mangui.hls.HLS;
import org.mangui.hls.HLSSettings;
import org.mangui.hls.constant.HLSLoaderTypes;
import org.mangui.hls.constant.HLSTypes;
import org.mangui.hls.controller.AudioTrackController;
import org.mangui.hls.controller.LevelController;
import org.mangui.hls.demux.Demuxer;
import org.mangui.hls.demux.DemuxHelper;
import org.mangui.hls.demux.Demuxer;
import org.mangui.hls.demux.ID3Tag;
import org.mangui.hls.event.HLSError;
import org.mangui.hls.event.HLSEvent;
import org.mangui.hls.event.HLSLoadMetrics;
import org.mangui.hls.flv.FLVTag;
import org.mangui.hls.HLS;
import org.mangui.hls.HLSSettings;
import org.mangui.hls.model.AudioTrack;
import org.mangui.hls.model.Fragment;
import org.mangui.hls.model.FragmentData;
Expand Down Expand Up @@ -81,6 +82,7 @@ package org.mangui.hls.loader {
private var _fragRetryCount : int;
private var _fragLoadStatus : int;
private var _fragSkipping : Boolean;
private var _fragSkipCount : int;
/** reference to previous/current fragment */
private var _fragPrevious : Fragment;
private var _fragCurrent : Fragment;
Expand Down Expand Up @@ -334,6 +336,7 @@ package org.mangui.hls.loader {
_fragmentFirstLoaded = false;
_fragPrevious = null;
_fragSkipping = false;
_fragSkipCount = 0;
_levelNext = -1;
_timer.start();
}
Expand All @@ -348,6 +351,7 @@ package org.mangui.hls.loader {
_loadingState = LOADING_IDLE;
_fragmentFirstLoaded = true;
_fragSkipping = false;
_fragSkipCount = 0;
_levelNext = -1;
_fragPrevious = lastFrag;
_timer.start();
Expand Down Expand Up @@ -447,7 +451,7 @@ package org.mangui.hls.loader {
}
// switch back to IDLE state to request new fragment at lowest level
_loadingState = LOADING_IDLE;
} else if(HLSSettings.fragmentLoadSkipAfterMaxRetry == true) {
} else if(HLSSettings.fragmentLoadSkipAfterMaxRetry == true && _fragSkipCount < HLSSettings.maxSkippedFragments || HLSSettings.maxSkippedFragments < 0) {
CONFIG::LOGGING {
Log.warn("error parsing fragment, skip it and load next one");
}
Expand All @@ -459,6 +463,10 @@ package org.mangui.hls.loader {
_fragRetryTimeout = 1000;
_fragPrevious = _fragCurrent;
_fragSkipping = true;
_fragSkipCount++;
CONFIG::LOGGING {
Log.debug("fragments skipped / max: " + _fragSkipCount + "/" + HLSSettings.maxSkippedFragments );
}
// set fragment first loaded to be true to ensure that we can skip first fragment as well
_fragmentFirstLoaded = true;
_loadingState = LOADING_IDLE;
Expand Down Expand Up @@ -512,7 +520,7 @@ package org.mangui.hls.loader {
}
// switch back to IDLE state to request new fragment at lowest level
_loadingState = LOADING_IDLE;
} else if(HLSSettings.fragmentLoadSkipAfterMaxRetry == true) {
} else if(HLSSettings.fragmentLoadSkipAfterMaxRetry == true && _fragSkipCount < HLSSettings.maxSkippedFragments || HLSSettings.maxSkippedFragments < 0) {
/* check if loaded fragment is not the last one of a live playlist.
if it is the case, don't skip to next, as there is no next fragment :-)
*/
Expand All @@ -527,7 +535,7 @@ package org.mangui.hls.loader {
_fragRetryTimeout = Math.min(HLSSettings.fragmentLoadMaxRetryTimeout, 2 * _fragRetryTimeout);
} else {
CONFIG::LOGGING {
Log.warn("max fragment load retry reached, skip fragment and load next one");
Log.warn("max fragment load retry reached, skip fragment and load next one.");
}
var tags : Vector.<FLVTag> = tags = new Vector.<FLVTag>();
tags.push(_fragCurrent.getSkippedTag());
Expand All @@ -537,6 +545,10 @@ package org.mangui.hls.loader {
_fragRetryTimeout = 1000;
_fragPrevious = _fragCurrent;
_fragSkipping = true;
_fragSkipCount++;
CONFIG::LOGGING {
Log.debug("fragments skipped / max: " + _fragSkipCount + "/" + HLSSettings.maxSkippedFragments );
}
// set fragment first loaded to be true to ensure that we can skip first fragment as well
_fragmentFirstLoaded = true;
_loadingState = LOADING_IDLE;
Expand Down Expand Up @@ -601,6 +613,7 @@ package org.mangui.hls.loader {
Log.debug("loading completed");
}
_fragSkipping = false;
_fragSkipCount = 0;
_metrics.loading_end_time = getTimer();
_metrics.size = fragData.bytesLoaded;

Expand Down Expand Up @@ -978,7 +991,7 @@ package org.mangui.hls.loader {

/* try to do progressive buffering here.
* only do it in case :
* first fragment is already loaded
* first fragment is already loaded
* or if first fragment is not loaded, we can do it if
* startLevel is already defined (startLevel is already set or
* startFromLevel/startFromBitrate not set to -1
Expand Down Expand Up @@ -1062,9 +1075,10 @@ package org.mangui.hls.loader {
_fragHandleParsingError("error parsing fragment, no tag found");
return;
}
// parsing complete, reset retry counter
// parsing complete, reset retry and skip counters
_fragRetryCount = 0;
_fragRetryTimeout = 1000;
_fragSkipCount = 0;
CONFIG::LOGGING {
if (fragData.audio_found) {
Log.debug("m/M audio PTS:" + fragData.pts_min_audio + "/" + fragData.pts_max_audio);
Expand Down

0 comments on commit 21c1a27

Please sign in to comment.