MPEG-DASH Streaming with Dash.js handler

Dash.js Version: 4.3.0
Buffer Level:
Reported Bitrate:
Framerate:
Resolution:

MPEG-DASH streaming test with videojs and Nuevo plugin

Nuevodevel.com introduce nuevo-dash plugin, source handler based on dash.js library for supporting MPEG-DASH playback on browsers with support for Media Source Extensions.This is alternative for videojs default HTTP streaming engine. Existing videos-contrib-dash plugin for videojs is outdated, doesn't allow to set dash.js options, doesn't allow to load and manage quality variants.
The plugin by Nuevodevel.com supports the latest Dash.js version: 4.3.
Code snippet
<script src="//domain.com/videojs/video.min.js"></script>
<script src="//domain.com/videojs/plugins/nuevo-dash.js"></script>
<script src="//domain.com/videojs/nuevo.min.js"></script>

<video id="myplayer" class="video-js" width+"640" height="360" controls>
<source src="//path/to/manifest.mpd" type="application/dash+xml" />
</video>

<script>
var player = videojs('myplayer');
player.nuevoPlugin({
logo: "//domain.com/path/to/logo.png",
logourl: "/domain.com"
});
</script>

Passing options to Dash.js

With the release of dash.js structure the various settings in dash.js has changed. See how few options can be passed to dash.js when using videojs with nuevo-dash plugin.
Code snippet
<script>
const dashOptions = {
streaming: {
buffer: {
fastSwitchEnabled: true
}
abr:{
limitBitrateByPortal: true,
initialBitrate: {
audio: -1,
video: 360
}
}
}
}
var player = videojs('myplayer', { html5:{ dash: dashOptions }});
</script>

Dash.js setting options are described here. Click button below to see an array of all default Dash.js options.
DASH.JS OPTIONS
const defaultSettings = {
        debug: {
            logLevel: Debug.LOG_LEVEL_WARNING,
            dispatchEvent: false
        },
        streaming: {
            abandonLoadTimeout: 10000,
            wallclockTimeUpdateInterval: 100,
            lowLatencyEnabled: false,
            manifestUpdateRetryInterval: 100,
            cacheInitSegments: false,
            eventControllerRefreshDelay: 150,
            capabilities: {
                filterUnsupportedEssentialProperties: true,
                useMediaCapabilitiesApi: false
            },
            timeShiftBuffer: {
                calcFromSegmentTimeline: false,
                fallbackToSegmentTimeline: true
            },
            metrics: {
                maxListDepth: 100
            },
            delay: {
                liveDelayFragmentCount: NaN,
                liveDelay: NaN,
                useSuggestedPresentationDelay: true,
                applyServiceDescription: true
            },
            protection: {
                keepProtectionMediaKeys: false
            },
            buffer: {
                fastSwitchEnabled: true,
                flushBufferAtTrackSwitch: false,
                reuseExistingSourceBuffers: true,
                bufferPruningInterval: 10,
                bufferToKeep: 20,
                bufferTimeAtTopQuality: 30,
                bufferTimeAtTopQualityLongForm: 60,
                initialBufferLevel: NaN,
                stableBufferTime: 12,
                longFormContentDurationThreshold: 600,
                stallThreshold: 0.3,
                useAppendWindow: true,
                setStallState: true
            },
            gaps: {
                jumpGaps: true,
                jumpLargeGaps: true,
                smallGapLimit: 1.5,
                threshold: 0.3
            },
            utcSynchronization: {
                useManifestDateHeaderTimeSource: true,
                backgroundAttempts: 2,
                timeBetweenSyncAttempts: 30,
                maximumTimeBetweenSyncAttempts: 600,
                minimumTimeBetweenSyncAttempts: 2,
                timeBetweenSyncAttemptsAdjustmentFactor: 2,
                maximumAllowedDrift: 100,
                enableBackgroundSyncAfterSegmentDownloadError: true,
                defaultTimingSource: {
                    scheme: 'urn:mpeg:dash:utc:http-xsdate:2014',
                    value: 'https://time.akamai.com/?iso&ms'
                }
            },
            scheduling: {
                defaultTimeout: 500,
                lowLatencyTimeout: 0,
                scheduleWhilePaused: true
            },
            text: {
                defaultEnabled: true
            },
            liveCatchup: {
                minDrift: 0.02,
                maxDrift: 0,
                playbackRate: 0.5,
                latencyThreshold: 60,
                playbackBufferMin: 0.5,
                enabled: false,
                mode: Constants.LIVE_CATCHUP_MODE_DEFAULT
            },
            lastBitrateCachingInfo: {
                enabled: true,
                ttl: 360000
            },
            lastMediaSettingsCachingInfo: {
                enabled: true,
                ttl: 360000
            },
            cacheLoadThresholds: {
                video: 50,
                audio: 5
            },
            trackSwitchMode: {
                audio: Constants.TRACK_SWITCH_MODE_ALWAYS_REPLACE,
                video: Constants.TRACK_SWITCH_MODE_NEVER_REPLACE
            },
            selectionModeForInitialTrack: Constants.TRACK_SELECTION_MODE_HIGHEST_BITRATE,
            fragmentRequestTimeout: 0,
            retryIntervals: {
                [HTTPRequest.MPD_TYPE]: 500,
                [HTTPRequest.XLINK_EXPANSION_TYPE]: 500,
                [HTTPRequest.MEDIA_SEGMENT_TYPE]: 1000,
                [HTTPRequest.INIT_SEGMENT_TYPE]: 1000,
                [HTTPRequest.BITSTREAM_SWITCHING_SEGMENT_TYPE]: 1000,
                [HTTPRequest.INDEX_SEGMENT_TYPE]: 1000,
                [HTTPRequest.MSS_FRAGMENT_INFO_SEGMENT_TYPE]: 1000,
                [HTTPRequest.LICENSE]: 1000,
                [HTTPRequest.OTHER_TYPE]: 1000,
                lowLatencyReductionFactor: 10
            },
            retryAttempts: {
                [HTTPRequest.MPD_TYPE]: 3,
                [HTTPRequest.XLINK_EXPANSION_TYPE]: 1,
                [HTTPRequest.MEDIA_SEGMENT_TYPE]: 3,
                [HTTPRequest.INIT_SEGMENT_TYPE]: 3,
                [HTTPRequest.BITSTREAM_SWITCHING_SEGMENT_TYPE]: 3,
                [HTTPRequest.INDEX_SEGMENT_TYPE]: 3,
                [HTTPRequest.MSS_FRAGMENT_INFO_SEGMENT_TYPE]: 3,
                [HTTPRequest.LICENSE]: 3,
                [HTTPRequest.OTHER_TYPE]: 3,
                lowLatencyMultiplyFactor: 5
            },
            abr: {
                movingAverageMethod: Constants.MOVING_AVERAGE_SLIDING_WINDOW,
                ABRStrategy: Constants.ABR_STRATEGY_DYNAMIC,
                additionalAbrRules: {
                    insufficientBufferRule: true,
                    switchHistoryRule: true,
                    droppedFramesRule: true,
                    abandonRequestsRule: false
                },
                bandwidthSafetyFactor: 0.9,
                useDefaultABRRules: true,
                useDeadTimeLatency: true,
                limitBitrateByPortal: false,
                usePixelRatioInLimitBitrateByPortal: false,
                maxBitrate: {
                    audio: -1,
                    video: -1
                },
                minBitrate: {
                    audio: -1,
                    video: -1
                },
                maxRepresentationRatio: {
                    audio: 1,
                    video: 1
                },
                initialBitrate: {
                    audio: -1,
                    video: -1
                },
                initialRepresentationRatio: {
                    audio: -1,
                    video: -1
                },
                autoSwitchBitrate: {
                    audio: true,
                    video: true
                },
                fetchThroughputCalculationMode: Constants.ABR_FETCH_THROUGHPUT_CALCULATION_MOOF_PARSING
            },
            cmcd: {
                enabled: false,
                sid: null,
                cid: null,
                rtp: null,
                rtpSafetyFactor: 5,
                mode: Constants.CMCD_MODE_QUERY
            }
        }
HIDE

Protected Content

For most protection schemes, the license server information (URL & init data) is included inside the manifest. The notable exception to this is Widevine-Modular (WV). To playback WV content, you must provide the URL to a Widevine license server proxy through "keySystem" array when using the player.src() function. Detailed information about using DRM through Dash.js you can find here.
Code snippet
<script>
var protectionData = {
"com.widevine.alpha": { "serverURL": "http://m.widevine.com/proxy" }
};
player.src({
src: 'http://example.com/my/manifest.mpd',
type: 'application/dash+xml',
keySystemOptions: protectionData
});
</script>

DRM specific headers

Code snippet
<script>
var protectionData = {
"com.widevine.alpha": {
"serverURL": "http://m.widevine.com/proxy",
"httpRequestHeaders": {
"X-AxDRM-Message": "key"
},
priority: 0
}
};
player.src({
src: 'http://example.com/my/manifest.mpd',
type: 'application/dash+xml',
keySystemOptions: protectionData
});
You can access dash player instance as player.dash.mediaPlayer. This way you can track dash events, use dasp player methods, etc.
Code snippet
<script>
var dashVersion = player.dash.mediaPlayer.getVersion();
var metrics = player.dash.mediaPlayer.getDashMetrics();
</script>