Bandwidth detection Make sure you reach your entire audience with good quality

Introduction

The Bandwidth detection plugin monitors the bandwidth that is available to the player. Based on this detection, the plugin selects the stream or file that is best suited to the available bandwidth.

The goal is to offer the best viewing experience possible for an audience with varying Internet connection speeds. People with fast connections are served with HD content; people with slow connections are served with smaller files (i.e. lower bitrate). Playback needs to be uninterrupted while maintaining the best possible video quality.

Video files are encoded with several different bitrates so that good matches are available for the connection speeds that are being targeted.

Features

  • Quality Of Service monitoring and dynamic stream switching.
  • Support for progressive download, pseudostreaming, and RTMP.
  • Manual selection of the bitrate. Users can be offered the option to select their preferred bitrate.
  • HD button feature to toggle between a hd and sd clip.
Quality Of Service monitoring makes sure that playback continues uninterrupted using the best possible quality. The plugin continuously monitors and calculates the following metrics: available maximum bandwidth; number of dropped video frames; the amount of data currently buffered; and the available video screen size. Based on these factors, it determines the optimal bitrate. If needed the stream is dynamically switched during playback (requires Wowza 2 or Adobe FCS). Continuous monitoring and control is required to ensure good results as the available bandwidth fluctuates.

The player dimensions are considered when selecting the appropriate file. The plugin never selects a file that has dimensions larger than the player's screen. Selecting too large a file would waste bandwidth. When going fullscreen, the player switches to a larger file if available bandwidth permits.

Dynamic Stream Switching Example

The player shown below uses dynamic stream switching with Amazon CloudFront. Here is a tutorial about configuring Amazon CloudFront streaming using Flowplayer.

Search engine friendly content

Server Bandwidth Detection Example

Detecting bandwidth on startup via cloudfront.

Search engine friendly content
Choose Video Bitrate:
flowplayer("detectionplayer", "/swf/flowplayer.swf", {
        clip: {

            urlResolvers: 'bwcheck',
            provider: 'rtmp',
            autoPlay: false,
            scaling: 'fit',

            // available bitrates and the corresponding files. We specify also the video width
            // here, so that the player does not use a too large file. It switches to a
            // file/stream with larger dimensions when going fullscreen if the available bandwidth permits.
            bitrates: [
                {
                url: "mp4:bbb-400", width: 320, height: 180, bitrate: 400,
                // this is the default bitrate, the playback kicks off with this and after that
                // Quality Of Service monitoring adjusts to the most appropriate bitrate
                isDefault: true
                },
                { url: "mp4:bbb-800", width: 480, bitrate: 800 },
                { url: "mp4:bbb-1200", width: 720, bitrate: 1200 },
                { url: "mp4:bbb-1600", width: 1080, bitrate: 1600 }
            ]
        },
        plugins: {

            // bandwidth check plugin
            bwcheck: {
                url: '/swf/flowplayer.bwcheck-3.2.7.swf',
                // we use dynamic switching, the appropriate bitrate is switched on the fly.
                dynamic: true,

                //cloudfront uses fms 3.5
                serverType: 'fms',

                netConnectionUrl: 'rtmp://s3b78u0kbtx79q.cloudfront.net/cfx/st',

                //detect bandwidth on startup
                checkOnStart: true,

                //remember the bitrate so detection happens only once
                rememberBitrate: true,

                // show the selected file in the content box. This is not used in real installations.
                onStreamSwitchBegin: function (newItem, currentItem) {
                    $f().getPlugin('content').setHtml("Will switch to: " + newItem.streamName + " from " + currentItem.streamName);
                },
                onStreamSwitch: function (newItem) {
                $f().getPlugin('content').setHtml("Switched to: " + newItem.streamName);
                },

                onBwDone: function(mappedBitrate, detectedBitrate) {
                    var content = $f().getPlugin('content');
                    var info = "Your speed is: " + detectedBitrate + "
Your chosen bitrate: " + mappedBitrate.bitrate + "
Video file served: " + mappedBitrate.url; content.setHtml(info); } }, // RTMP streaming plugin rtmp: { url: '/swf/flowplayer.rtmp.swf', netConnectionUrl: 'rtmp://s3b78u0kbtx79q.cloudfront.net/cfx/st' }, // a content box so that we can see the selected video dimensions. This is not used in real // installations. content: { url: '/swf/flowplayer.content.swf', bottom: 30, left: 0, width: 250, height: 150, backgroundColor: 'transparent', backgroundGradient: 'none', border: 0, textDecoration: 'outline', style: { body: { fontSize: 14, fontFamily: 'Arial', textAlign: 'center', color: '#ffffff' } } } }, log: { level: 'debug', filter: 'org.flowplayer.rtmp.*, org.flowplayer.bwcheck.*,org.flowplayer.controller.*' } });

Server Bandwidth Detection with HD Button Example

Detecting bandwidth on startup via cloudfront, with HD button feature, and increasing max width to allow for HD clip to be selected.

Search engine friendly content
flowplayer("detectionhdplayer", "/swf/flowplayer.swf", {
        clip: {

            urlResolvers: 'bwcheck',
            provider: 'rtmp',
            autoPlay: false,
            scaling: 'fit',

            bitrates: [
                    {
                        url: "mp4:bbb-400", width: 320, height: 180, bitrate: 400
                    },
                    { url: "mp4:bbb-1200", width: 720, bitrate: 1200 }
            ]
        },
        plugins: {

            // bandwidth check plugin
            bwcheck: {
                url: '/swf/flowplayer.bwcheck-3.2.7.swf',


                //cloudfront uses fms 3.5
                serverType: 'fms',

                netConnectionUrl: 'rtmp://s3b78u0kbtx79q.cloudfront.net/cfx/st',

                //detect bandwidth on startup
                checkOnStart: true,

                hdButton: { place: "both" },

                maxWidth: 720,

                //remember the bitrate so detection happens only once
                rememberBitrate: false,

                // show the selected file in the content box. This is not used in real installations.
                onStreamSwitchBegin: function (newItem, currentItem) {
                    $f().getPlugin('content').setHtml("Will switch to: " + newItem.streamName + " from " + currentItem.streamName);
                },
                onStreamSwitch: function (newItem) {
                $f().getPlugin('content').setHtml("Switched to: " + newItem.streamName);
                },

                onBwDone: function(mappedBitrate, detectedBitrate) {
                    var content = $f().getPlugin('content');
                    var info = "Your speed is: " + detectedBitrate + "
Your chosen bitrate: " + mappedBitrate.bitrate + "
Video file served: " + mappedBitrate.url; content.setHtml(info); } }, // RTMP streaming plugin rtmp: { url: '/swf/flowplayer.rtmp.swf', netConnectionUrl: 'rtmp://s3b78u0kbtx79q.cloudfront.net/cfx/st' }, // a content box so that we can see the selected video dimensions. This is not used in real // installations. content: { url: '/swf/flowplayer.content.swf', bottom: 30, left: 0, width: 250, height: 150, backgroundColor: 'transparent', backgroundGradient: 'none', border: 0, textDecoration: 'outline', style: { body: { fontSize: 14, fontFamily: 'Arial', textAlign: 'center', color: '#ffffff' } } } }, log: { level: 'debug', filter: 'org.flowplayer.rtmp.*, org.flowplayer.bwcheck.*,org.flowplayer.controller.*' } });

Http Streaming with HD Button Example

Http streaming with HD button feature example.

Search engine friendly content
flowplayer("httpplayer", "/swf/flowplayer.swf", {
        clip: {

            urlResolvers: 'bwcheck',
            autoPlay: false,
            scaling: 'fit',
            baseUrl: 'http://vod01.netdna.com/vod/demo.flowplayer/pseudo/',

            bitrates: [
                {url: "bbb_480x270.flv", width: 480, height: 270, bitrate: 270, label: "270k"},
                {url: "bbb_640x360.flv", width: 640, height: 360, bitrate: 360, label: "360k"}
            ]
        },
        plugins: {

            // bandwidth check plugin
            bwcheck: {
                url: '/swf/flowplayer.bwcheck-3.2.7.swf',

                serverType: 'http',

                //using http detection set the url to a file minimum of 100kb to download
                netConnectionUrl: 'http://flowplayer.electroteque.org/swf/flowplayer-bwcheck.swf',
                bitrateProfileName: 'HTTPBitrateProfile',

                hdButton: { place: "both" },

                //detect bandwidth on startup
                checkOnStart: true,

                //remember the bitrate so detection happens only once
                rememberBitrate: true,

                // show the selected file in the content box. This is not used in real installations.
                onStreamSwitchBegin: function (newItem, currentItem) {
                    $f().getPlugin('content').setHtml("Will switch to: " + newItem.streamName +
                    " from " + currentItem.streamName);
                },
                onStreamSwitch: function (newItem) {
                    $f().getPlugin('content').setHtml("Switched to: " + newItem.streamName);
                },

                onBwDone: function(mappedBitrate, detectedBitrate) {
                    var content = $f().getPlugin('content');
                    var info = "Your speed is: " + detectedBitrate + "
Your chosen bitrate: " + mappedBitrate.bitrate + "
Video file served: " + mappedBitrate.url; content.setHtml(info); } }, // a content box so that we can see the selected video dimensions. This is not used in real // installations. content: { url: '/swf/flowplayer.content.swf', bottom: 30, left: 0, width: 250, height: 150, backgroundColor: 'transparent', backgroundGradient: 'none', border: 0, textDecoration: 'outline', style: { body: { fontSize: 14, fontFamily: 'Arial', textAlign: 'center', color: '#ffffff' } } } }, log: { level: 'debug', filter: 'org.flowplayer.rtmp.*, org.flowplayer.bwcheck.*,org.flowplayer.controller.*' } });

Pseudo Streaming with HD Button Example

Pseudo streaming with HD button feature example.

Search engine friendly content
flowplayer("pseudoplayer", "/swf/flowplayer.swf", {
        clip: {

            urlResolvers: 'bwcheck',
            provider: 'pseudo',
            autoPlay: false,
            scaling: 'fit',
            baseUrl: 'http://vod01.netdna.com/vod/demo.flowplayer/pseudo/',

            bitrates: [
                {url: "bbb_480x270.flv", width: 480, height: 270, bitrate: 270, label: "270k"},
                {url: "bbb_640x360.flv", width: 640, height: 360, bitrate: 360, label: "360k"}
            ]
        },
        plugins: {
            pseudo: {
                url: '/swf/flowplayer.pseudostreaming.swf'
            },
            // bandwidth check plugin
            bwcheck: {
                url: '/swf/flowplayer.bwcheck-3.2.7.swf',

                serverType: 'http',

                //using http detection set the url to a file minimum of 100kb to download
                netConnectionUrl: 'http://flowplayer.electroteque.org/swf/flowplayer-bwcheck.swf',
                bitrateProfileName: 'HTTPBitrateProfile',

                hdButton: { place: "both" },

                //detect bandwidth on startup
                checkOnStart: true,

                //remember the bitrate so detection happens only once
                rememberBitrate: true,

                // show the selected file in the content box. This is not used in real installations.
                onStreamSwitchBegin: function (newItem, currentItem) {
                    $f().getPlugin('content').setHtml("Will switch to: " + newItem.streamName +
                    " from " + currentItem.streamName);
                },
                onStreamSwitch: function (newItem) {
                    $f().getPlugin('content').setHtml("Switched to: " + newItem.streamName);
                },

                onBwDone: function(mappedBitrate, detectedBitrate) {
                    var content = $f().getPlugin('content');
                    var info = "Your speed is: " + detectedBitrate + "
Your chosen bitrate: " + mappedBitrate.bitrate + "
Video file served: " + mappedBitrate.url; content.setHtml(info); } }, // a content box so that we can see the selected video dimensions. This is not used in real // installations. content: { url: '/swf/flowplayer.content.swf', bottom: 30, left: 0, width: 250, height: 150, backgroundColor: 'transparent', backgroundGradient: 'none', border: 0, textDecoration: 'outline', style: { body: { fontSize: 14, fontFamily: 'Arial', textAlign: 'center', color: '#ffffff' } } } }, log: { level: 'debug', filter: 'org.flowplayer.rtmp.*, org.flowplayer.bwcheck.*,org.flowplayer.controller.*' } });

Javascript Plugin Example

Using the bwcheck javascript plugin to provide a bitrates menu.

Search engine friendly content
Choose Video Bitrate:
flowplayer("javascriptplayer", "/swf/flowplayer.swf", {
        clip: {

            urlResolvers: 'bwcheck',
            provider: 'rtmp',
            autoPlay: false,
            scaling: 'fit',

            // available bitrates and the corresponding files. We specify also the video width
            // here, so that the player does not use a too large file. It switches to a
            // file/stream with larger dimensions when going fullscreen if the available bandwidth permits.
            bitrates: [
                {
                url: "mp4:bbb-400", width: 320, height: 180, bitrate: 400,
                // this is the default bitrate, the playback kicks off with this and after that
                // Quality Of Service monitoring adjusts to the most appropriate bitrate
                isDefault: true
                },
                { url: "mp4:bbb-800", width: 480, bitrate: 800 },
                { url: "mp4:bbb-1200", width: 720, bitrate: 1200 },
                { url: "mp4:bbb-1600", width: 1080, bitrate: 1600 }
            ]
        },
        plugins: {

            // bandwidth check plugin
            bwcheck: {
                url: '/swf/flowplayer.bwcheck-3.2.7.swf',
                // we use dynamic switching, the appropriate bitrate is switched on the fly.
                dynamic: true,

                //cloudfront uses fms 3.5
                serverType: 'fms',

                netConnectionUrl: 'rtmp://s3b78u0kbtx79q.cloudfront.net/cfx/st',

                //detect bandwidth on startup
                checkOnStart: true,

                //remember the bitrate so detection happens only once
                rememberBitrate: true,

                // show the selected file in the content box. This is not used in real installations.
                onStreamSwitchBegin: function (newItem, currentItem) {
                    $f().getPlugin('content').setHtml("Will switch to: " + newItem.streamName +
                    " from " + currentItem.streamName);
                },
                onStreamSwitch: function (newItem) {
                    $f().getPlugin('content').setHtml("Switched to: " + newItem.streamName);
                },

                onBwDone: function(mappedBitrate, detectedBitrate) {
                    var content = $f().getPlugin('content');
                    var info = "Your speed is: " + detectedBitrate + "
Your chosen bitrate: " + mappedBitrate.bitrate + "
Video file served: " + mappedBitrate.url; content.setHtml(info); } }, // RTMP streaming plugin rtmp: { url: '/swf/flowplayer.rtmp.swf', netConnectionUrl: 'rtmp://s3b78u0kbtx79q.cloudfront.net/cfx/st' }, // a content box so that we can see the selected video dimensions. This is not used in real // installations. content: { url: '/swf/flowplayer.content.swf', bottom: 30, left: 0, width: 250, height: 150, backgroundColor: 'transparent', backgroundGradient: 'none', border: 0, textDecoration: 'outline', style: { body: { fontSize: 14, fontFamily: 'Arial', textAlign: 'center', color: '#ffffff' } } } }, log: { level: 'debug', filter: 'org.flowplayer.rtmp.*, org.flowplayer.bwcheck.*,org.flowplayer.controller.*' } }).bwcheck('#bitrateMenu',{seperator: " | "});


Configuration:
property / datatype default description
checkOnStart
boolean
true If true (the default) the plugin checks the bandwidth for every clip once their playback starts even when the clips don't specify this plugin as their urlResolver. Specify false here if you have clips in the playlist for which the bandwidth should not be checked.
selectedBitrateClass
string
bitrate-selected The selected bitrate link class.
activeClass
string
bitrate-active The active bitrate link class.
disabledClass
string
bitrate-disabled The disabled bitrate link class.
bwCheckPlugin
string
bwcheck The name of the bandwidth check plugin in the player configuration.
template
string
{bitrate} k The template config to be used for generating the links. The fields of the bitrates clip config are used as the template variables ie {bitrate}. If the wrapper has the template set, it will be used instead of the template config.
disabledText
string
(not valid with this player size ) The text to display if the item is disabled due to size constraints and the selection strategy.
fadeTime
int
100 The interval time for fading the wrapper in and out. Useful for hiding the wrapper if a template is set in it.
seperator
string
A seperator character to use for seperating the links ie
or | .

JavaScript API

Methods

method returns description
getBitrate() int Gets the current bitrate. The returned value is the bitrate in use after the latest bitrate transition has been completed. If a bitrate switch is in progress the value reflects the bitrate right now being used, not the one we are switching to.
setBitrate(bitrate) Changes the stream to the specified bitrate. The specified value should be one of the values contained in the bitrates array. If the player is currently playing a clip, the stream corresponding to the specified bitrate is started. If dynamic stream switching is enabled, the stream switches dynamically while playing; otherwise, the stream plays from the start of the clip. Note: QoS monitoring and dynamic stream switching is disabled when this method is called so that the dynamic switching does not override the bitrate specified using this method. You can enable dynamic switching again using the enableDynamic() method (see below).
enableDynamic(enabled) Enables or disables dynamic stream switching. The specified enabled value is a Boolean specifying the enabled state.
checkBandwidth() Initiates a new bandwidth check. The detected bandwidth is stored in the client browser if the config option rememberBitrate is set to true. If the player is currently playing a clip, a new stream based on the detected bandwidth is selected and started. If dynamic stream switching is enabled, the stream switches dynamically while playing; otherwise, the stream plays from the start of the clip. When the bandwidth check is successfully called, the onBwDone event is called allowing you to get the results.

Events

Event When does it fire?
onBwDone() Fires when the bandwidth has been detected. The callback is fed with the following arguments:
  • url the complete URL that was resolved for playback
  • mappedBitrate the bitrate selected from the bitrates array
  • detectedBitrate the detected bitrate used to resolve the mappedBitrate
onStreamSwitchBegin(newItem, currentItem) Fires when a bitrate switch is initiated. A second event is fired when the switch is completed, see below. This event is called only when the dynamic configuration property is enabled. The callback is fed with two bitrateItem objects that describe the new bitrate we are switching to and the current one. These objects have following properties:
  • streamName - the name of the stream
  • bitrate
  • width
onStreamSwitch(newItem) Fires when the bitrate switch has been completed. Once fired the new stream starts playing and is shown in the player. This event is called only when the dynamic configuration property is enabled. The callback is fed with an object argument that has following properties:
  • streamName - the name of the stream
  • bitrate
  • width

Here are the events related to establishing a connection and clustering. Note that if you are not clustering the hosts used for bandwidth checking, the host index will always have a value of zero.

Event When does it fire?
onConnect() Fires when the plugin starts a new connection attempt. The callback is fed with two arguments:
  • host the URL from the hosts list where the connection is attempted from
  • hostIndex the index of the host in the hosts list
onConnectFailed() Fires when a connection attempt has failed. The callback is fed with two arguments:
  • host the URL from the hosts list where the failure happened
  • hostIndex the index of the host in the hosts list
onFailed() Fires when all hosts in the cluster have failed. See also the connectCount option, that specifies how many times the hosts are evaluated before failing.

Advanced features

Clustering of bandwidth checks

You can configure an array of hosts to be used for the bandwidth check. The plugin chooses a live host from this array until it finds one that does not fail. This provides a way to add failover. Note that this is not designed to be used with dynamic stream switching as the hosts in the cluster are used only in the initial RTMP bandwidth check call. Here is an example of how to configure clustering for the bandwidth check:

bwcheck: {
    url: 'flowplayer.rtmp-3.1.3.swf',
    serverType: 'red5',

    // the actual streaming happens from this host. In reality you would
    // probably configure a cluster of hosts here too.
    netConnectionUrl: 'rtmp://electroteque.org/bwcheck',

    // the hosts used for the initial bandwidth check
    hosts: [
    {host:'rtmp://electroteque1.org/bwcheck'},
    {host:'rtmp://electroteque2.org/bwcheck'},
    {host:'rtmp://electroteque.org/bwcheck'}
    ]
    }

The configuration above is for clustering the bandwidth checking connections only. If you want to cluster your streaming connections, then you need to use our clustering plugin.

The clustering configuration for bandwidth checking and for the actual streaming are separate. This is because in many cases the RMTP applications used for bandwidth checking are different from the applications that are used for streaming, and therefore their host URLs are also different.